機械学習モデルRNN(LSTM)でビットコイン価格予想をするAIを作る

自動売買

ビットコインの値動きを機械学習で予想するとき、RNN(recurrent neural network:再帰型ニューラルネットワーク)という機械学習の手法が有効らしいです

今回はその中でも、LSTM(Long Short Term Memory : 長期短期記憶)というモデルを使って、ビットコインの価格予想に挑戦します

LSTMとは

LSTMとは、過去の値動きから規則性を見つけて、次の値を予想することです

出典:https://toeming.hatenablog.com/entry/2020/06/02/231233

機械学習モデルRNN(LSTM)でビットコイン価格予想をするAIを作る

LSTMを使ってビットコインの値動きを予想している人は少なく、

気温や企業の売り上げ予想(同じ時系列データ)をしている人を参考に、ビットコインに応用してみます

飛行機の乗客者数を予想している人がいたので、この記事を参考にして実装しました

やっていることは、過去30時間のデータをもとに1時間後の値段を予想させることです

データの取得

※ビットコイン自動売買プログラムのサンプルを載せますが、以下の点をご注意ください

注意事項

・取引における損失について、責任は負いかねます

・API Keyの流出など、セキュリティ面での責任は負いかねます

・上記以外のいかなる障害・トラブルにおいても責任を負いかねます

暗号資産取引所bitbankのAPIを使って、ビットコイン時間足のデータを取得します

詳しくはこの記事をご覧ください

2019/1/1~2019/5/1までのデータを取得しました

hourly_data()関数は、上の記事をご覧ください

start = "20190101"
end = "20190501"
pair = "btc_jpy"
candle_type = "1hour"
df = hourly_data(start,end,pair,candle_type)

データを取得し、CSVファイルに出力します

df.to_csv("btc_data.csv")

データの読み込み

上で取得したデータを読み込みます

import pandas
df = pandas.read_csv("btc_data.csv", index_col=0)

必要なライブラリをインストールします

#ライブラリ
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline
from matplotlib.pylab import rcParams
rcParams["figure.figsize"] = 15, 6

グラフを描画します

#グラフを描画する
x = df.index.values
y = df["Close"].values
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y)
plt.show()

データの前処理

0〜1になるように正規化

#正規化
input_data = df["Close"].values.astype(float)
print("input_data : ", input_data.shape, type(input_data))

norm_scale = input_data.max()
input_data /= norm_scale
print(input_data[0:5])

ラベル(答え)を作る

#教師データの分割
def make_dataset(low_data, maxlen):
    
    data, target = [], []
    
    for i in range(len(low_data) - maxlen):
        data.append(low_data[i:i+maxlen])
        target.append(low_data[i+maxlen])
    
    re_data = np.array(data).reshape(len(data), maxlen, 1)
    re_target = np.array(target).reshape(len(data), 1)
    
    return re_data, re_target

window_size = 12

X, y = make_dataset(input_data, window_size)
print("shape X : ", X.shape)
print("shape y : ", y.shape)

学習用データとテストデータに分割します

#学習データとテストデータの分割
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)
#train:学習データ、test:テストデータ

print("X_train : ", X_train.shape)
print("X_test : ", X_test.shape)
print("y_train : ", y_train.shape)
print("y_test : ", y_test.shape)

LSTMモデルの構築

kerasという機械学習ライブラリを使って、LSTMモデルを構築します

ライブラリのインポート

tensorflowは、python3.8に対応していないので、anacondaでpython3.6の仮想環境を作って実行しました

#ライブラリ
import keras
from keras.models import Sequential
from keras.layers import Dense, Activation, LSTM
from keras.optimizers import Adam
import tensorflow as tf

LSTMネットワークの構築

#ネットワークの構築
lstm_model = Sequential()
lstm_model.add(LSTM(50, batch_input_shape=(None, window_size, 1)))
lstm_model.add(Dense(1))

#コンパイル
lstm_model.compile(loss="mean_squared_error", optimizer=Adam(), metrics = ["accuracy"])
lstm_model.summary()

学習

パラメータを決める

#学習用パラメータ
batch_size = 30
n_epoch = 150

学習させます

#学習
hist = lstm_model.fit(X_train, y_train,
                     epochs=n_epoch,
                     validation_data=(X_test, y_test),
                     verbose=0,
                     batch_size=batch_size)

学習状況をプロット

#損失値の遷移をプロット
plt.plot(hist.history["loss"], label="train set")
plt.plot(hist.history["val_loss"], label="test set")
plt.title("model loss")
plt.xlabel("epoch")
plt.ylabel("loss")
plt.legend()
plt.show

価格予想

これまでの学習結果をもとに、実際にビットコインの価格を予想してみます

#予想
y_pred_train = lstm_model.predict(X_train)
y_pred_test = lstm_model.predict(X_test)
#train:学習データ、test:テストデータ
#X:データ、y:答え

# RMSEで評価
# 参考:https://deepage.net/deep_learning/2016/09/17/tflearn_rnn.html
def rmse(y_pred, y_true):
    return np.sqrt(((y_true - y_pred) ** 2).mean())
print("RMSE Score")
print("  train : " , rmse(y_pred_train, y_train))
print("  test : " , rmse(y_pred_test, y_test))

# 推定結果のプロット
plt.plot(X[:, 0, 0], color='blue',  label="observed")  # 元データ
plt.plot(y_pred_train, color='red',  label="train")   # 予測値(学習)
plt.plot(range(len(X_train),len(X_test)+len(X_train)),y_pred_test, color='green',  label="test")   # 予測値(検証)
plt.legend()
#plt.xticks(np.arange(0, 145, 12)) # 12ヶ月ごとにグリッド線を表示
plt.grid()
plt.show()

予想結果がこちらです

青:実際のビットコインの値動き

赤:訓練データに対する予想結果

緑:テストデータに対する予想結果

評価

青色の線と赤色(緑色)が一致していないので、あんまり値動きを予想できていないように見えます

例えば、下の図の黒丸の時間では、次の時間に下がると予想しているのに対して、実際のビットコイン価格は上がっています

この誤差を数字で表すと、訓練データに対して(赤色)は0.012(=1.2%)、テストデータに対して(緑色)は0.008(=0.8%)生じています

これらは、ビットコイン価格予想の精度としては悪すぎると言えます

また、訓練データに対して誤差は0.012(=1.2%)、テストデータに対しては0.008(=0.8%)となっている過学習は起こしていないと言えます

※過学習:訓練データにのみ適応してしまうこと(人間で言うと、参考書の問題は完璧に解けるけど、本番のテストは解けないみたいな感じ)

考察

ビットコインの価格予想は一筋縄ではいかないと言うことがわかりました

ここで、ビットコイン価格予想以外の例を見てみましょう

下の図は、航空機の乗客予想です

僕がやったビットコイン価格予想と同じパラメータ(学習回数)で学習させています

出典:https://toeming.hatenablog.com/entry/2020/06/02/231233

青:実際の飛行機の乗客者数

赤、緑:予想値

上の図より、航空機の乗客は明らかな規則性があり、ある程度予測ができていることが読み取れます

対してビットコインの価格遷移から規則性を読み解くことは難しく、予想も難しいことがわかります

LSTM単体でビットコイン価格を予想するのは難しいのではないかと考えられます

冒頭で示した図のように、LSTMでは、過去の値動きのみをもとに価格予想をしています

ビットコインの値動きは、人間でも全く規則性が読めないものです

今回使用したLSTMはニューラルネットワークを使っていて、ニューラルネットワークは人間の脳を模したものです

いくらニューラルネットワークを使っても、明らかにランダムウォークである値動きを予測するのは難しいと考えます

次にやること

上の理由のように、LSTMのみでのビットコイン価格予想は難しいと考えます

なので、次は、特徴量を加えて別のモデルで価格予想しようと思います

特徴量を加える

値動きのみを頼りに、1時間後のビットコイン価格を予想している状態です

そのため、人間で言うと、ニュースで情報を集めたり(ファンダメンタルズ分析)、テクニカル指標を参考にしたり(テクニカル分析)を一切せずに、チャートだけ見てトレードしているようなものです

もう少し情報を与えれば、ビットコイン価格予想の的中率が上がると思います

具体的には

・移動平均

・MACD

・ボリンジャーバンド

などのテクニカル的な指標や

・アルトコイン価格

・「ビットコイン」という言葉のGoogle検索数

などのファンダメンタル的な指標を、特徴量として加えてみたいと思います

参考

サイト

TensorFlow(LSTM)で株価予想 〜 株予想その1 〜 - Qiita
はじめに 新しく株投資の勉強を始めるのでそのメモを残していきます。 目標、機械学習やディープラーニングを使って株価予想します。 勉強を始めるにあたり、先ずは以下の本を確認。 ※ 株が動く条件は「業績がよい」「PERが低い」「...

書籍


コメント

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