前回までで、為替データの取得をするプログラムを作りました。
今回は、為替の動きを予測するモデル(予測モデル)を作っていきます。
基礎知識
今回は予測モデルとしてニューラルネットワークを使うのでニューラルネットワークと、
ニューラルネットワークを簡単に実装できる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()を呼ぶことでグラフを表示していきます。
例として以下のようなグラフがプロットされると思います。
青線が正解データ、オレンジが予測モデルが予測したデータです。
どうでしょうか?まぁまぁ良く予測できている気がします。
もちろんこの精度ではトレードで勝つのは中々難しいと思います。
終わりに
お疲れ様です。少し長かったですが、
今回は予測モデルの学習まで終えました。
次回はこの予測モデルを使って適宜データを取得しながら予測するプログラムを作っていきます。
ちなみにこのプロジェクトのトップページは