【ディープラーニング】kerasで多クラス分類 〜irisデータセットを用いて〜

前回はKerasを使って2値分類をしました。

【超入門、ニューラルネットワーク】Kerasで2値分類 〜超簡単な例〜

今回はirisデータをセットを使って、多クラス分類をしてみました。
本記事では、pythonの基本操作はできることを想定しています。

IT・Web・ゲーム業界のエンジニア転職なら【Tech Stars Agent】

Kerasとは

Kerasは、ニューラルネットワークを非常にシンプルに構築できるライブラリです。

https://keras.io/ja/

TensorFlow等で書くとかなり長くなってしまうコードがKerasを使うことでシンプルなコードとなります。

ちなみにKerasは下でTensorFlow等が動いています。

多クラス分類とは

多クラス分類とは、データの性質によって複数の対象(クラス)に分類することいいます。

例えば、ある果物が与えられたらその果物をりんご、バナナ、みかん等に分類することです。

問題設定

今回はiris(あやめ)の分類問題を扱います。
ここでは、あやめのデータを取得し、そのデータをモデル(ニューラルネットワーク)に学習させます。
そして、入力情報からどのあやめかを出力させます。

irisデータセット

irisデータセットとは、
あやめの花に関するデータセットになります。
3種類のあやめのデータがそれぞれ50個づつ格納されています。

あやめの情報として、

  • がく片の長さ(sepal length)
  • がく片の幅(sepal width)
  • 花びらの長さ(patal length)
  • 花びらの幅(petal width)

が保存されています。

データセットを見てみましょう。

# データの取得
iris = datasets.load_iris()

x = iris.data   # 説明変数
y = iris.target # 目的変数

print(x[0]) # => array([ 5.1,  3.5,  1.4,  0.2]) 0番目の花の情報
print(y[0]) # => 0 # 0番目の花は0クラス


実装

では、実装していきます。

まず必要なモジュールをimportします。

import numpy as np
from sklearn import datasets
from keras.models import Sequential
from keras.layers import Dense,  Activation
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras.utils import np_utils

irisデータセットの読み込みやデータの加工などを行います。

iris = datasets.load_iris() # データを取得
x = iris.data   # 花の特徴量、長さなど
y = iris.target # 0, 1, 2のラベル
x = preprocessing.scale(x)  # 標準化

ラベルデータをone-hotエンコードをします。

y = np_utils.to_categorical(y)  # one-hotエンコード.例) 1 => [0, 1, 0]

学習用データとテスト用データに分けます。

x_train, x_test, y_train, y_test= train_test_split(x, y, train_size=0.8)    # 教師データとテストデータに分割

モデルを生成します。
今回は非常にシンプルなモデルを用います。

model = Sequential()
model.add(Dense(10, input_dim=4))    # 入力層4ノード, 隠れ層に10ノード, 全結合
model.add(Activation("sigmoid"))    # 活性化関数はsigmoid
model.add(Dense(3)) # 出力層3ノード,全結合
model.add(Activation("sigmoid"))

モデルをコンパイルします。
ここで、誤差関数や最適化手法を設定します。

model.compile(loss="categorical_crossentropy",   # 誤差関数
              optimizer="adam",     # 最適化手法
              metrics=['accuracy'])

モデルに学習させていきます

history = model.fit(x_train, y_train, nb_epoch=500, batch_size=32) # 学習

学習過程のプロットしてみます。

# 学習過程のプロット
plt.plot(history.epoch, history.history["acc"], label="acc")
plt.plot(history.epoch, history.history["loss"], label="loss")
plt.xlabel("epoch")
plt.legend()

accが正答率、lossが誤差(binary_crossentropy)を表しています。
epoch(学習回数)が進むに連れて、正答率が向上して、誤差が小さくなっていることがわかります。
うまく学習が進んでいるようです。

モデルをテストデータで評価してみます。

Test score 0.18996156752109528
Test accuracy 0.9333333373069763

Test scoreが誤差、Test accuracyは正答率を表しています。
正答率が93.3%ですのでけっこう良くできていることがわかります。

いくつかデータを予測してみます。

# 学習できているか見てみる
print("====================================")
print("-----------correct answer-----------")
print(y_test[0])
print(y_test[10])
print("-----------predict answer-----------")
print(np.round(model.predict(x_test)[0]))
print(np.round(model.predict(x_test)[10]))

以下が出力になります。

-----------correct answer-----------
[1. 0. 0.]
[1. 0. 0.]
-----------predict answer-----------
[1. 0. 0.]
[1. 0. 0.]

correct answerが正解データ、predict answerがモデルからの予想値になります。
正しく予想できていることがわかります。

ソースコードの全体像

最後にソースコードの全体像を以下に示します。

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
from keras.models import Sequential
from keras.layers import Dense,  Activation
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras.utils import np_utils

iris = datasets.load_iris() # データを取得
x = iris.data   # 花の特徴量、長さなど
y = iris.target # 0, 1, 2のラベル
x = preprocessing.scale(x)  # 標準化

y = np_utils.to_categorical(y)  # one-hotエンコード.例) 1 => [0, 1, 0]
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8)    # 教師データとテストデータに分割

# モデルの生成
model = Sequential()
model.add(Dense(10, input_dim=4))    # 入力層4ノード, 隠れ層に10ノード, 全結合
model.add(Activation("sigmoid"))    # 活性化関数はsigmoid
model.add(Dense(3)) # 出力層3ノード,全結合
model.add(Activation("sigmoid"))

model.compile(loss="categorical_crossentropy",   # 誤差関数
              optimizer="adam",     # 最適化手法
              metrics=['accuracy'])

history = model.fit(x_train, y_train, nb_epoch=500, batch_size=32) # 学習
# 学習過程のプロット
plt.plot(history.epoch, history.history["acc"], label="acc")
plt.plot(history.epoch, history.history["loss"], label="loss")
plt.xlabel("epoch")
plt.legend()

# 評価
score = model.evaluate(x_test, y_test, verbose=1)
print("Test score", score[0])
print("Test accuracy", score[1])

# 個々のデータを入力して学習できているか見てみる
print("====================================")
print("-----------correct answer-----------")
print(y_test[0])
print(y_test[10])
print("-----------predict answer-----------")
print(np.round(model.predict(x_test)[0]))
print(np.round(model.predict(x_test)[10]))

参考文献


コメント

タイトルとURLをコピーしました