背景
こちらの記事で、Tensorflowのニューラルネットワークを用いた分類予測のプログラムを紹介いたしました。
今回は同じようにtensorflowのニューラルネットワークを用いて、回帰予測(数値予測)を行うプログラムを紹介します。
とりあえず、実装することを目的とするため、細かな解説は割愛します。
データ準備・前処理
今回もkaggleコンペの一つである「House Prize」を使って回帰予測を行っていきます。
今回のデータは、予測に用いることができる項目が79項目もあり、
titanicの生存予測の時よりも、変数が多く、データ前処理も時間がかかったのですが、
本記事ではプログラムの紹介を中心に行いたいため、割愛します。
(下記記事にて、同データセットを例にデータ前処理の方法を紹介しております。)
CSVデータ読み込み
ここは、分類問題のときと同じですが再掲しておきます。
numpyの".loadtext"を使って、訓練データCSVを読み込みします。
import numpy as np
# 訓練データのpathを指定
path="C:\\Users\\●●●\\・・・前処理後訓練データ.csv"
#numpyを使ってCSV読込
# delimiter=ファイルの区切り文字
# skiprows=先頭の何行を無視するか(項目名は読み込まない)
TRAIN_ALLdata = np.loadtxt(path,delimiter=",",skiprows=1)
データの分割
次に、読み込んだデータを目的変数と説明変数に分割します。
(ここも分類問題と同じです。)
#目的変数(out_data)と説明変数(in_data)に分割、
# [x]はx番目で分割
# axis=1は列方向で分割(=0の場合は行方向で分割)
out_data , in_data = np.split(TRAIN_ALLdata,[1],axis=1)
モデルの定義
ここからモデルの定義になりますが、下記ポイントが分類問題の時から変更するポイントです。
- 出力層の活性関数(activation)を"linear"にする
- 評価関数を"MeanSquaredError"(平均二乗誤差)にする
(これ以外もありますが、平均二乗誤差がよく用いられます) - 出力層のノード数を「1」に変更する
import tensorflow as tf
from tensorflow import keras
from keras import layers
#モデルの条件(変数で指定したほうが、後のパラメータ調整が簡単になります。)
h_cnl=20 #ニューロン数(中間層ノード数)
layers_N=3 #中間層数
#モデルの準備(空の箱を準備)
model = keras.Sequential()
#入力層を定義(input_shapeは説明変数の数)
model.add(layers.Dense(h_cnl, activation='relu',name='input', input_shape=(in_data.shape[1],)))
#中間層を定義
# (単純に"model.add"を複数記載してもよいのですが、後のパラメータ調整がしやすいようにfor文記載)
for i in range(layers_N):
model.add(layers.Dense(h_cnl,activation='relu'))
#出力層を定義 activation='linear'に注意
model.add(layers.Dense(1,activation='linear',name='output'))
#モデルの評価関数(loss)、最適化手法(optimizer)を指定
#loss='MeanSquaredError'(平均二乗誤差)にする
model.compile(loss='MeanSquaredError', optimizer="adam")
#モデルの概要を表示(なくてもOK)
model.summary()
モデルの学習実行
モデルの学習を実行してきます。ここも特に分類問題の解きと変わりません。
epoch_num= 200 #学習数
batch_num= 32 #バッチサイズ
# modelの学習開始
# verbose:学習ログの表示(1=ON,0=OFF)
# validation_split:訓練データを分割して検証に用います
history=model.fit(in_data, out_data,
epochs=epoch_num,
batch_size=batch_num,
verbose=1,validation_split=0.2)
結果の表示
続いて、学習の結果を表示させます
ここでは、"matplotlib"を使用します。
横軸「学習回数」縦軸「損失」として、グラフ描画し、学習が進むにつれて損失(loss)が減少していく様子を確認します。
import matplotlib.pyplot as plt
#学習結果表示
plt.plot(history.history['loss'],label='loss')
plt.plot(history.history['val_loss'],label='val_loss')
plt.legend(frameon=False)
plt.xlabel('epochs')
plt.ylabel('loss')
plt.show()
こちらを実行すると、下図のようなグラフが表示されると思います。
ニューラルネットワークは学習の過程で乱数を使用するため、毎回結果は異なります。
(seed値の固定をすれば毎回一緒にすることもできます。)
なので、細かい値は異なると思いますが、おおまかな形(最初大きく減少して、徐々に緩やかになっていく形)が一緒でいればOKです。
テストデータの予測
モデル学習が完了したら、次はテストデータ(未知データ)を予測させます。
#テストデータの読み込み(上記のCSVファイル読込と同じ)
path="C:\\Users\\●●●\\・・・前処理後テストデータ.csv"
TEST_data = np.loadtxt("前処理後テストデータ.csv",delimiter=",",skiprows=1)
#予測の実行
y_predict = model.predict(TEST_data)
#予測結果をCSVファイルで書き出し
np.savetxt("予測結果.csv", y_predict, delimiter=",")
上記実行すると、"予測結果.CSV"が生成されます。
中を除いてみると、下図のようになっていると思います。
回帰予測の場合、予測された数値がそのまま出力されます。
結果の評価
それでは予測結果をKaggleで提出して、正解率を教えてもらいます。
予測結果は指定されたフォーマット(zipファイル内の"sample_submission.csv")で提出しましょう。
上記のプログラムで予測したスコアは0.23391のだったようです。
コンペの概要を読むと、
このコンペはRMSE(MSEの平方根)に従って評価されるようです。
このスコアは低い方が良い結果です。
この後、学習条件の調整等で0.159ぐらいまではスコアを改善できましたが、
これ以上はデータの前処理等から見直す必要がありそうです。
AIとかデータサイエンスというと、スマートな印象ですが、実際はトライ&エラーの繰り返しで非常に泥臭い作業が多いです。
特に、予測精度を上げていく作業は膨大な時間がかかります。なので、どのレベルまで予測精度が必要なのかしっかり決めてから作業に取り掛かることをオススメします。
ある程度取り組んで、目標に到達しなければ潔くあきらめた方がよい場合もあります。
まとめ
いかがだったでしょうか
この記事のプログラムをコピペすれば、ひとまずニューラルネットワークを使った回帰予測ができると思います。
ぜひご活用ください。