③予測モデルを学習させる

前回までで、為替データの取得をするプログラムを作りました。
今回は、為替の動きを予測するモデル(予測モデル)を作っていきます。

基礎知識

今回は予測モデルとしてニューラルネットワークを使うのでニューラルネットワークと、

ニューラルネットワークを簡単に実装できるTensorFlowについて説明します。

ニューラルネットワーク(ディープラーニング)とは

まず簡単にニューラルネットワークを紹介します。

ニューラルネットワークとは簡単に言ってしまえば、人間の脳の神経回路網を簡易的にモデル化したものです。
(正しくは人口ニューラルネットワークと言いますが、今回はニューラルネットワークとしています。)

以下はニューラルネットワークの1例です。

ニューラルネットワークのイメージ図
ニューラルネットワークのイメージ

このネットワークは左から値を入力して、そこから右方向に伝搬していくようなモデルです。

今回の為替の例で言えば、過去n日分のチャートのデータを左から入力して、次の日n+1日の為替の予想値を右から出力させます。

このネットワークの層を増やしたもの(ディープにしたもの)をディープラーニングと言います。

ニューラルネットワークの処理は主に学習フェーズと推論フェーズに分かれています。
学習フェーズはニューラルネットワークにデータを入力し学習させます。
推論フェーズでは、実際に未知の情報を入力して、予想させます。

TensorFlow

今回はニューラルネットワークを構築するためのライブラリとしてTensorFlowを用います。

TensorFlowとは数値計算用のオープンソースライブラリで、ニューラルネットワークを実装する際によく用いられます。
Googleの方がメインで開発されていることもあり、広く使われています。

Colabを使っている人はデフォルトでインストールされているので、インストールする必要はありません。

自分のPCで運用している人は以下のコマンドでインストールしてください。

TensorFlowのバージョン2.0を使うのでバージョンが古い人は更新しておいてください。

実装

では、実装していきましょう!前回と同じファイルに追記していきます。

必要なモジュールのインポート

まずは例のごとく、必要なモジュールをインポートします。おまじないと思ってください(笑)。

import tensorflow
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Activation, Flatten
import matplotlib.pyplot as plt
import json

予測モデルの構築と学習

次に予測モデルの構築と学習をするプログラムを作成します。

では、先程作成したメソッドを使って、予測モデルが学習・評価できるようにデータを加工します。

# 学習・テスト用データの作成
X_train, Y_train, X_test, Y_test = create_data_for_model(prices)

trainとついているのが学習用データ、testというのがモデルの評価用データになります。
Xが入力、Yが正解データです。

次に、ニューラルネットワークの構築と学習を行っていきます。

TensorFlowのKerasではニューラルネットワークの構築は簡単です。以下のコードで構築は完了です。

# モデルの作成
model = Sequential()
model.add(Flatten(input_shape=[INPUT_LEN, 1]))
model.add(Dense(32))
model.add(Activation("relu"))
model.add(Dense(32))
model.add(Activation("relu"))
model.add(Dense(1))
model.add(Activation("linear"))

kerasではSequential()を使うことでフィードフォワード型のモデルを簡単に作れます。

今回のコードでは上記のようなモデルを作成しています。Denseによって層を作成し、その作成した層をmodel.add()によってモデルに組み込んでいきます。
Activationは活性化関数です。また別途開設します。

今回は終値を予測するので出力値は1次元としています。

ここでは、これ以上のニューラルネットワークの説明は割愛します。
ニューラルネットワークについては参考文献を参照してください。

最後に以下のようにcompileすることでモデルの誤差関数、最適化手法等を設定します。

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

これでモデルの構築は終了です

学習データと予測モデルの構築は終えたので学習させてみます。
今回の設定であればfit関数を使うことで簡単に実行できます。

model.fit(X_train, Y_train, batch_size=BATCH_SIZE, epochs=EPOCHS)

各引数は

  • X_train : 入力データ
  • Y_train : 正解データ
  • batch_size : バッチサイズ(前回の記事の定数BATCH_SIZEで設定
  • epochs : エポック(前回の記事の定数EPOCHSで設定)

です。

次に学習したモデルの情報(構造と重み)を保存します。
今回はmodelsディレクトリに構造と重みを保存していきます。
以下のコマンドで保存できます。

# 学習結果の保存
model_json = model.to_json()
with open(MODEL_PATH, "w") as f:
    json.dump(model_json, f, indent=4)

model.save_weights(WEIGHTS_PATH)

ここまでで学習は終了です。

予測モデルの評価

まず評価してみましょう。
X_test, Y_testの評価は以下のコードで簡単にできます。

model.evaluate(X_test, Y_test)

これで誤差を計算できます。

ただ、数値だけだとわからなので、図をプロットしてみましょう。

まず予測値の計算をします。これはmodel.predictメソッドを以下のように使います。評価用の入力データX_testを使います。

# 予測値の計算
predicted_y = model.predict(X_test)

0〜1の値が出力されるので、先程正規化したインスタンスscを使って元の値に戻してあげます。sc.inverse_transformメソッドを使います。

predicted_y = sc.inverse_transform(predicted_y)

あと、テスト用データも正規化しているので、同じように元に戻します。

# 実際の値のプロット
Y_test = sc.inverse_transform(Y_test)

後はこれらをプロットしていきます。

# 結果のプロット
fig, ax = plt.subplots()

# 正解データの表示
ax.plot(np.arange(len(Y_test)), Y_test, label="real")
# 予測データの表示
ax.plot(np.arange(len(predicted_y)), predicted_y, label="predicted_value")

# 凡例の表示
ax.legend()

簡単に解説すると、plt.subplots()を呼ぶことで、白紙のキャンバスを表示します。その上にax.plot()を呼ぶことでグラフを表示していきます。

例として以下のようなグラフがプロットされると思います。

青線が正解データ、オレンジが予測モデルが予測したデータです。

どうでしょうか?まぁまぁ良く予測できている気がします。
もちろんこの精度ではトレードで勝つのは中々難しいと思います。

終わりに

お疲れ様です。少し長かったですが、

今回は予測モデルの学習まで終えました。

次回はこの予測モデルを使って適宜データを取得しながら予測するプログラムを作っていきます。

ちなみにこのプロジェクトのトップページは

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