Kerasで回帰ニューラルネットワークを実装してみた【Sequentialモデル】

こんにちは、ゆうじ(@yuji_sgs_prog)です。

機械学習のアウトプットでまとめた内容についての解説記事です。

上記の記事で全てをまとめると大変なので、今回個別の記事でまとめていきます。

Kerasを活用して、ニューラルネットワークによる回帰分析を行いたい方は参考になると思うので、ぜひご覧ください〜

なお、今回のコードを実装するにあたって、「自前CSVデータからKerasでニューラルネットワークを実装」という記事を参考にさせていただきました。めちゃ参考になったので、大変感謝です。(もっとこういった記事が増えるといいですね)

目次

Kerasで回帰ニューラルネットワークを実装する前に

まずは、いきなりモデルの解説に入るのではなく、事前準備や環境について紹介していきます。

Kerasで回帰ニューラルネットワークを実装する前の準備・環境
  • Google Colaboratoryにて実行
  • データセットは3列×10,000行のcsvデータ(自前csvファイルはこちら。※クリックするとダウンロードします | 僕の研究内容と直接関わっています)
  • 一番単純かつシンプルなSequentialモデルを構築

実行環境についてはJupyter Notebookなどでも良いですが、Google Colabratoryなら無料でGPUが使えるので、適当に使ってます。

また、データセットについて、1,2列目をインプットに、3列目をアウトプットとしてニューラルネットワークを構築します。

Kerasで構築したニューラルネットワークのモデル図
今回構築したニューラルネットワークのモデル図

Kerasで回帰ニューラルネットワークを実装したコードを解説

実装したコードの全体像をまず紹介します。

# 使用するライブラリをインポート
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import io
from google.colab import files

from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam
from keras.layers.core import Dropout
from keras.callbacks import EarlyStopping, LearningRateScheduler

from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from math import sqrt
from sklearn.metrics import r2_score


# Google Colaboratoryでファイルをアップロード
uploaded = files.upload()


# データフレームとして、変数dfに3列×10000行のデータを格納
df = pd.read_csv(io.BytesIO(uploaded['data10000.csv']))


# データの分割
(train, test) = train_test_split(df, test_size=0.2, shuffle=True)

# x_train, x_testではcsvファイルの1列目から2列目を,y_train, y_testでは3列目のデータを活用
x_train = train.iloc[:, [0, 1]]
y_train = train.iloc[:, [2]]

x_test = test.iloc[:, [0, 1]]
y_test = test.iloc[:, [2]]


# データの正規化
x_train = (x_train - x_train.min()) / (x_train.max() - x_train.min())
x_test = (x_test - x_test.min()) / (x_test.max() - x_test.min())


# モデルの構築
# inputの数
n_in = 2

# ノードの数
n_hidden = 16

# outputの数
n_out = 1

# 学習回数
epochs = 50
batch_size = 64

model = Sequential()
model.add(Dense(n_hidden, activation= 'relu', input_dim=n_in))
model.add(Dense(n_hidden, activation= 'relu', input_dim=n_in))
model.add(Dense(n_hidden, activation= 'relu', input_dim=n_in))
model.add(Dense(units=n_out))
model.summary()

optimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999)
model.compile(loss='mean_squared_error', optimizer=optimizer)


# 学習オプション
history = model.fit(x_train, y_train, epochs=epochs, batch_size=batch_size, validation_data=(x_test, y_test))


# 構築したモデルで予測
test_predict = model.predict(x_test)


#精度評価指標
# MAE
test_MAE = mean_absolute_error(y_test, test_predict)
print('MAE:', test_MAE)

# MSE
test_MSE = mean_squared_error(y_test, test_predict)
print('MSE:', test_MSE)

# RMSE
test_RMSE = sqrt(mean_squared_error(y_test, test_predict))
print('RMSE:', test_RMSE)

# 決定係数
R2 = r2_score(y_test, test_predict)
print('R2:', R2)

# MAEに対するRMSEの比
print('RMSE/MAE:', test_RMSE / test_MAE)


# 損失関数
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = len(loss)
plt.plot(range(epochs), loss, marker='.', label='loss')
plt.plot(range(epochs), val_loss, marker='.', label='val_loss')
plt.legend(loc='best')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()


# Observed-Predicted Plot
plt.figure()
plt.scatter(y_test, test_predict, c='blue', alpha=0.8)
plt.ylim(plt.ylim())
plt.grid()
plt.xlabel('observed_data')
plt.ylabel('predict_data')
plt.show()

ちょい長めですが、順番に解説していきます。

ライブラリのインポート

# 使用するライブラリをインポート
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

import io
from google.colab import files

from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense, Activation
from keras.optimizers import Adam
from keras.layers.core import Dropout
from keras.callbacks import EarlyStopping, LearningRateScheduler

from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error
from math import sqrt
from sklearn.metrics import r2_score

まず、使用するライブラリをインポートしています。

あまり深く考える部分でもないので、適当にインポートしています。

データセットの読み込み

# Google Colaboratoryでファイルをアップロード
uploaded = files.upload()


# データフレームとして、変数dfに3列×10000行のデータを格納
df = pd.read_csv(io.BytesIO(uploaded['data10000.csv']))

ここでは、ローカルにあるcsvファイルをGoogle Colaboratoryにアップロードして、変数”df”にデータを格納しています。

ちなみに、ここの操作は以下の記事を参考にしました。

データの分割

# データの分割
(train, test) = train_test_split(df, test_size=0.2, shuffle=True)

# x_train, x_testではcsvファイルの1列目から2列目を,y_train, y_testでは3列目のデータを活用
x_train = train.iloc[:, [0, 1]]
y_train = train.iloc[:, [2]]

x_test = test.iloc[:, [0, 1]]
y_test = test.iloc[:, [2]]

ここで、訓練データとテストデータに分けていきます。

上記のプログラムでは、訓練データ:テストデータ=80:20という形で分けていますが、「test_size=○○」の部分を変更すると比率は変わってきます。

また、1,2列目をインプットに、3列目をアウトプットとして、データを分割しています。

訓練データの正規化

# データの正規化
x_train = (x_train - x_train.min()) / (x_train.max() - x_train.min())
x_test = (x_test - x_test.min()) / (x_test.max() - x_test.min())

データの正規化とは、データの最小値を0、最大値を1に変換する操作を指します。

訓練データを見ると、1列目の範囲は0〜10で、2列目の範囲は0〜1と、少し差があります。そのため、いい具合に調整するための操作です。

モデルの構築

# モデルの構築
# inputの数
n_in = 2

# ノードの数
n_hidden = 16

# outputの数
n_out = 1

# 学習回数
epochs = 50
batch_size = 64

model = Sequential()
model.add(Dense(n_hidden, activation= 'relu', input_dim=n_in))
model.add(Dense(n_hidden, activation= 'relu', input_dim=n_in))
model.add(Dense(n_hidden, activation= 'relu', input_dim=n_in))
model.add(Dense(units=n_out))
model.summary()

optimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999)
model.compile(loss='mean_squared_error', optimizer=optimizer)

いよいよ、モデルの構築を行なっていきます。

上記のプログラムでは、中間層が3層で、各層のノード数は16としてニューラルネットワークを構築しています。

活性化関数はReLUを、最適化アルゴリズムはAdamを採用しています。

なお、ここの部分はKerasの公式が参考になります。

学習 → 予測

# 学習オプション
history = model.fit(x_train, y_train, epochs=epochs, batch_size=batch_size, validation_data=(x_test, y_test))

上記コードを実行すると学習が始まります。

# 構築したモデルで予測
test_predict = model.predict(x_test)

そして、構築したモデルから予測を行なっていきます。

精度評価指標

#精度評価指標
# MAE
test_MAE = mean_absolute_error(y_test, test_predict)
print('MAE:', test_MAE)

# MSE
test_MSE = mean_squared_error(y_test, test_predict)
print('MSE:', test_MSE)

# RMSE
test_RMSE = sqrt(mean_squared_error(y_test, test_predict))
print('RMSE:', test_RMSE)

# 決定係数
R2 = r2_score(y_test, test_predict)
print('R2:', R2)

# MAEに対するRMSEの比
print('RMSE/MAE:', test_RMSE / test_MAE)

予測した値から、MAE、MSE、RMSE、決定係数を求めていきます。

ちなみに、実行した時は以下のようなデータが表示されます。

MAE: 0.02991514426947141   # 0に近いほど良い
MSE: 0.001563834395335399   # 0に近いほど良い
RMSE: 0.03954534606417548   # 0に近いほど良い
R2: 0.9988363429433301   # 1に近いほど良い
RMSE / MAE: 1.3219172773481072   # 1.253に近いほど良い

詳細の数値は違うかもですが、おそらく似たような数値がでてくるはずです。

なお、この回帰分析の精度評価指標に関しては、以下の記事を参考にしました。

損失関数グラフの可視化

# 損失関数
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs = len(loss)
plt.plot(range(epochs), loss, marker='.', label='loss')
plt.plot(range(epochs), val_loss, marker='.', label='val_loss')
plt.legend(loc='best')
plt.grid()
plt.xlabel('epoch')
plt.ylabel('loss')
plt.show()

上記コードを実行すると、損失関数のグラフをプロットすることができます。

なお、実際にプロットされたグラフは以下の通り。

損失関数のグラフ
損失関数のグラフ

ここで、lossは訓練データに対する損失値を、val_lossはテストデータに対する損失値を示しています。

Observed-Predicted Plot

# Observed-Predicted Plot
plt.figure()
plt.scatter(y_test, test_predict, c='blue', alpha=0.8)
plt.ylim(plt.ylim())
plt.grid()
plt.xlabel('observed_data')
plt.ylabel('predict_data')
plt.show()

最後に、実データとの当てはまりの良さを調べるために、横軸に実測値を、縦軸に予測値をとったグラフをプロットします。

実際にプロットされたグラフは以下の通り。

Observed-Predicted Plot
Observed-Predicted Plot

上記グラフのように、対角線上にプロットされていれば、良い予測が行えています。

以上、Kerasでニューラルネットワークを構築して、回帰分析を行うコードの解説でした〜

Kerasで回帰ニューラルネットワークの実装まとめ

本記事では、Kerasの単純なSequentialモデルで、回帰分析を実行するニューラルネットワークの実装を解説しました。

本記事で紹介した参考記事もあわせつつ、興味ある方はぜひ実装してみてください。

また、今後ゆる〜いペースで機械学習に関する情報などを発信していくつもりなので、たまにみていただけると嬉しいです〜\(^o^)/

Thank you for sharing my post !!
  • URLをコピーしました!
目次