buto > /dev/null

だいたい急に挑戦してゴールにたどり着かずに飽きる日々です

Python ニューラルネットワークで学習

Kerasを使ってニューラルネットワークを体験してみた

これまではscikit-learnで相関分析、回帰分析をして学習・予測していました より機械学習っぽいこと(パラメータを調整して予測精度を上げる)をしてみたいので ニューラルネットワークが簡単に使える(らしい)Kerasを使ってみました!

ピンク色のRGB値と好きを学習

相関分析した記事:Python 好きなピンクを相関分析してみる

「ピンク色のRGB値」と「好きかどうか」の関係を学習して予測してみます!!

import pandas as pd
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.utils import np_utils
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

csv_data = pd.read_csv('keras_pink.csv')
data = pd.DataFrame(csv_data)
pd.DataFrame(csv_data)

「LIKE」は好きなピンクは1、そうでなければ0です

f:id:butorisa:20201020141404p:plain

# 説明変数    
x = data[['R', 'G', 'B']]
# 目的変数    
y = data['LIKE']

#学習データとテストデータに分割する    
#test_sizeがテストデータの割合  
X_train, X_test, Y_train, Y_test = train_test_split(x,     
                                                    y,     
                                                    test_size=0.2,     
                                                    random_state=0)

# LIKEの値をone-hotエンコーディング(ベクトルに変換)
Y_train = np_utils.to_categorical(Y_train)
Y_test = np_utils.to_categorical(Y_test)

# ニューラルネットワークモデルの作成
model = Sequential()

# 入力は3個、ノードは5個
model.add(Dense(activation='relu', units=5, input_dim=3))

# 出力は2個(ベクトル[1.0]か[0.1])、シグモイド関数を利用
model.add(Dense(activation='sigmoid', units=2))

作成したニューラルネットワークモデルはこんな感じのはず…!(Nはノードです)

f:id:butorisa:20201020141422j:plain

# モデルのコンパイル
model.compile(loss='mean_absolute_error', # 損失関数:絶対誤差
              optimizer='rmsprop', # 最適化手法:RMSprop
              metrics=['accuracy'])

# 学習を実行
history = model.fit(X_train, Y_train,
            batch_size=2, # データを2個ずつに分けて学習
            epochs=12, # 学習を12回繰り返す
            verbose=1) # プログレスを出力

ここらへんの損失関数、最適化手法は全然分かっていません。。。 epochsを上げると予測精度に変化がでると思っている

Epoch 1/12 19/19 [==============================] - 0s 20ms/step - loss: 0.5021 - accuracy: 0.4737 Epoch 2/12 19/19 [==============================] - 0s 2ms/step - loss: 0.4741 - accuracy: 0.5263 Epoch 3/12 19/19 [==============================] - 0s 2ms/step - loss: 0.4735 - accuracy: 0.4737 Epoch 4/12 19/19 [==============================] - 0s 2ms/step - loss: 0.4729 - accuracy: 0.4737 Epoch 5/12 19/19 [==============================] - 0s 1ms/step - loss: 0.4683 - accuracy: 0.4211 Epoch 6/12 19/19 [==============================] - 0s 2ms/step - loss: 0.4510 - accuracy: 0.5263 Epoch 7/12 19/19 [==============================] - 0s 1ms/step - loss: 0.4479 - accuracy: 0.5263 Epoch 8/12 19/19 [==============================] - 0s 2ms/step - loss: 0.4476 - accuracy: 0.5789 Epoch 9/12 19/19 [==============================] - 0s 2ms/step - loss: 0.4475 - accuracy: 0.5263 Epoch 10/12 19/19 [==============================] - 0s 2ms/step - loss: 0.4475 - accuracy: 0.4737 Epoch 11/12 19/19 [==============================] - 0s 2ms/step - loss: 0.4474 - accuracy: 0.5263 Epoch 12/12 19/19 [==============================] - 0s 1ms/step - loss: 0.4474 - accuracy: 0.5263

# 学習の結果
loss = pd.Series(history.history['loss'])
acc = pd.Series(history.history['accuracy'])
result = pd.concat([loss, acc], axis=1)
result.columns = ['損失関数', '予測精度']
result

欠損値は低いほど予測精度が高いと言えます 損失関数が低くても予測精度が高いとは言い切れない(過学習の場合がある) ↓欠損値ではなく損失関数です

f:id:butorisa:20201020141442p:plain

# 予測精度の履歴をプロット
plt.plot(acc, "o-", label="accuracy")
plt.title('model accuracy')
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.legend(loc="lower right")
plt.show()

x軸:学習回数(エポック数) y軸:model.fitの戻り値(学習時の)予測精度

f:id:butorisa:20201020141500p:plain

# モデルの評価
score = model.evaluate(X_test, Y_test, verbose=0)
print('損失関数:{}'.format(score[0]))
print('予測精度:{}'.format(score[1]))

損失関数:0.20000247657299042 予測精度:0.800000011920929

学習をしたモデルにテストデータを投入して予測精度をテスト! 予測精度:80%は良いほうなのでしょうか??

ニューラルネットワークできたのかな?

それっぽい予測精度は出ているけれど、「ピンク色のRGB値」と「好きかどうか」の関係を学習できているのかはいまいち分かっていない… 回帰分析から難易度が急に上がった感じがすごい

アドバイスをもらえた!

会社の人に見てもらい、アドバイスをもらえました - 色がピンク色だけなのでRGBよりHSV(色相・彩度・明度)の方がデータとして良さそう - データの前処理(正規化など)をした方が良い - 学習時の予測精度が50%程度で学習ができていなさそう - データが少ない、相関が低い - モデルの損失関数を二値交差エントロピーにする - lossは欠損値ではなく、損失関数と言った方が正しい - 「欠損関数が低いほど予測精度が高い」とは言えない