TensorFlowでアヤメ分類

f:id:hanamichi_sukusuku:20210204164029p:plain

実行結果

f:id:hanamichi_sukusuku:20210204164330p:plain

 

このプログラムではTensorFlowを用いてアヤメのデータを学習させて、その結果を出力するもの。

 

アヤメデータの読み込み

iris_data = pd.read_csv("iris.csv", encoding="utf-8")

pandasモジュールはデータ処理の利用するライブラリーで、ここではcsvファイルを読み込むために使用。

pd.read_csv()でcsvファイルを指定し、エンコードの仕方を指定して出力。

 

アヤメデータをラベルと入力データに分離する

y_labels = iris_data.loc[:,"Name"]
x_data = iris_data.loc[:,["SepalLength","SepalWidth","PetalLength","PetalWidth"]]

locを指定することでpd.read_csv()で取得したデータから任意の位置の要素を取得できる。

y_lanelsのiris_data.loc[:, "Name"]では全ての行から"Name"の列の要素を全て取得している。:で全ての行、"Name"でその列の要素を指定。

x_data =iris_data.loc.....では全ての行からそれぞれ指定した列の要素を取得している。

f:id:hanamichi_sukusuku:20210204174222p:plain

csvファイルの中身はこんな感じ。

 

ラベルデータをone-hotベクトルに直す

labels = {
'Iris-setosa': [1, 0, 0],
'Iris-versicolor': [0, 1, 0],
'Iris-virginica': [0, 0, 1]
}
y_nums = np.array(list(map(lambda v : labels[v] , y_labels)))
x_data = np.array(x_data)

one-hotベクトルというのは、一つだけHigh(1)、他はLow(0)の状態で表現することである。TensorFlowではラベルデータをこのone-hotベクトルという形式で表す必要がある。

 

上記のコードではIris-setosaを[1, 0, 0]、Iris-versicolorを[0, 1, 0]、Iris-virginicaを[0, 0, 1]という形に変換している。

mapメソッドを使用して第一引数に関数(どんな処理をするか)、第二引数に処理したいデータを指定する。今回ではラムダを使用して引数で受け取った要素(Iris-setosaまたはris-versicolorまたはIris-virginica)をlabelsのキーに指定して、それに対応する値を返し新しいリストを作成している。

 

学習用とテスト用に分割する

x_train, x_test, y_train, y_test = train_test_split(
x_data, y_nums, train_size=0.8)

 

モデルの定義

Dense = keras.layers.Dense
model = keras.models.Sequential()
model.add(Dense(10, activation='relu', input_shape=(4,)))
model.add(Dense(3, activation='softmax'))

modelにSequentialを定義。

モデルの中にネットワーク(レイヤー)を追加していく。

model.add(Dense(10, activation='relu', input_shape=(4,)))ではユニット数が10、activationは活性化関数としてreluを指定、入力層としてDenseを使用する場合はinput_shapeで入力のパラメーターの数を指定する、今回はSepalLength,SepalWidth,PetalLength,PetalWidthの四次元なので(4,)を指定。

次のDenseでは出力値がIris-setosa、ris-versicolor、Iris-virginicaなので出力用としてユニット数3、activation='softmax'では出力した値の合計が1になるように出力されるように指定している。

 

モデルの構築

model.compile(
   loss='categorical_crossentropy',
   optimizer='adam',
   metrics=['accuracy'])

 

損失関数のlossにはcategorical_crossentropyを指定しており、クラス分類でよく使われる誤差関数の一つ。最適化の手法にはadamを指定しており、これは確率的勾配降下法の一つのアダム法を使って最適化を行うようにしている。metricsではモデルをどのように評価するのかを指定しており、今回は正解率を知りたいのでaccuracyを指定。

 

学習を実行

model.fit(x_train, y_train,
  batch_size=20,
  epochs=300)

baych_sizeは一回に計算するデータの数のことで今回は20に設定。ただ、これを小さくすると使用するメモリー量が少なくなるが、小さくしすぎるとうまく動かなくなるので注意。

epochsは何回学習を繰り返すかの指定。

 

モデルを評価

score = model.evaluate(x_test, y_test, verbose=1)
print('正解率=', score[1], 'loss=', score[0])

model.evaluate()でモデル評価。

score[1]には正解率、scrore[0]には間違い度を表している。