RNN(GRU)を用いて日経平均の予測をしてみました。(参考URLをほぼ引用して作成)
結果のグラフでは未来の予測値が急上昇してしまいます。
恐らく間違っていると思うのですが、どこが間違っているのかわかりません。
間違っている部分があればご指摘いただきたいです。
【参考URL】
ディープラーニングで日経平均株価を予測 その2(RNN)
【アルゴリズムの概要】
学習モデル
過去700~101日分を訓練用データ
過去100~51日分を検証用データ
過去50~0日分をテスト用データ
50日間を学習データとして学習する部分を特徴量としてx
当日の教師データをyとする。
python
1## RNN(GRU) による日経平均株価(終値)の予測 2## 過去50日分の株価より当日の株価を予測 3 4## 過去700~101日分を訓練用データ 5## 過去100~51日分を検証用データ 6## 過去50~0日分をテスト用データ 7 8import numpy as np 9import pandas as pd 10import matplotlib.pyplot as plt 11from keras.models import Sequential 12from keras.layers import Dense, LSTM, GRU 13from keras.optimizers import RMSprop 14from sklearn.preprocessing import StandardScaler 15from sklearn.metrics import mean_squared_error 16 17## 以下の URL より日経平均株価データ(日別)をダウンロードし、 18## このプログラムと同一階層に保存 19## https://indexes.nikkei.co.jp/nkave/historical/nikkei_stock_average_daily_jp.csv 20 21data_file = 'nikkei_stock_average_daily_jp.csv' 22 23## 当日の株価を予測するために必要な過去の日数 24lookback = 50 25 26## エポック数 27epochs = 4000 28 29## 学習データ数 30learning_num = -700 31 32## データファイルを読み込む 33## データ日付を index に設定 34## 最終行はデータではないため、スキップ 35df = pd.read_csv(data_file, index_col=0, encoding='cp932', 36 skipfooter=1, engine='python') 37 38## 終値 39closing_price = df[['終値']].values 40 41## 訓練・検証・テスト用データを作成 42## 過去50日分の株価より当日の株価とする 43def data_split(data, start, end, lookback): 44 length = abs(start-end) 45 46 X = np.zeros((length, lookback)) 47 y = np.zeros((length, 1)) 48 49 for i in range(length): 50 j = start - lookback + i 51 k = j + lookback 52 53 X[i] = data[j:k, 0] 54 y[i] = data[k, 0] 55 56 return X, y 57 58## 訓練・検証・テスト用データ 59(X_train, y_train) = data_split(closing_price, learning_num, -100, lookback) 60(X_valid, y_valid) = data_split(closing_price, -100, -50, lookback) 61(X_test, y_test) = data_split(closing_price, -50, 0, lookback) 62 63## 標準化:scalerは正規化するための関数 64## X のみ次元を変換(2次元 ⇒ 3次元) 65scaler = StandardScaler() 66scaler.fit(X_train) 67X_train_std = scaler.transform(X_train).reshape(-1, lookback, 1) 68X_valid_std = scaler.transform(X_valid).reshape(-1, lookback, 1) 69X_test_std = scaler.transform(X_test).reshape(-1, lookback, 1) 70 71 72scaler.fit(y_train) 73y_train_std = scaler.transform(y_train) 74y_valid_std = scaler.transform(y_valid) 75 76#X_train_std.shape[-1] 行列X_train_stdの列数 77length_of_sequence = X_train_std.shape[-1] 78#隠れ層の数 79n_hidden = 256 80 81## 訓練 RNN(ここでmodelを作る) 82model = Sequential() 83model.add(GRU(n_hidden, 84 dropout=0.2, 85 recurrent_dropout=0.2, 86 return_sequences=False, 87 input_shape=(None, X_train_std.shape[-1]))) 88model.add(Dense(1)) ##ニューロン数 89 90model.compile(optimizer=RMSprop(), loss='mae', metrics=['accuracy']) 91 92result = model.fit(X_train_std, y_train_std, 93 verbose=0, ## 詳細表示モード 94 epochs=epochs, 95 batch_size=64, 96 shuffle=True, 97 validation_data=(X_valid_std, y_valid_std)) 98 99## 訓練の損失値をプロット 100epochs = range(len(result.history['loss'])) 101plt.title('損失値(Loss)') 102plt.plot(epochs, result.history['loss'], 'bo', alpha=0.6, marker='.', label='train', linewidth=1) 103plt.plot(epochs, result.history['val_loss'], 'r', alpha=0.6, label='valid', linewidth=1) 104plt.xlabel('Epoch') 105plt.ylabel('Loss') 106plt.legend() 107plt.grid(True) 108plt.show() 109 110## 予測値 111df_predict_std = pd.DataFrame(model.predict(X_test_std), columns=['予測値']) 112 113## 予測値を元に戻す(正規化の解除) 114predict = scaler.inverse_transform(df_predict_std['予測値'].values) 115 116## 予測結果をプロット 117pre_date = df.index[-len(y_test):].values 118plt.title('実際の終値と予測値') 119plt.plot(pre_date, y_test, 'b', alpha=0.6, marker='.', label='実際の終値', linewidth=1) 120plt.plot(pre_date, predict, 'r', alpha=0.6, marker='.', label='予測値', linewidth=1) 121plt.xticks(rotation=70) 122plt.legend() 123plt.grid(True) 124plt.show() 125 126# RMSEの計算 127print('二乗平均平方根誤差(RMSE) : %.3f' % 128 np.sqrt(mean_squared_error(y_test, predict))) 129 130#未来の株価予想 131future_test = X_test_std[-1].T 132# 1つの学習データの時間の長さ 133time_length = future_test.shape[1] 134# 未来の予測データを保存していく変数 135future_result = np.empty((1)) 136 137#10日間の日経平均の予測をする 138for step2 in range(10): 139 #future_testを3次元に変換 140 test_data = np.reshape(future_test, (1, time_length, 1)) 141 #予測値をbatch_predict_stdに格納 142 batch_predict_std = model.predict(test_data) 143 #batch_predict_stdの正規化を解除する(step2日目の予測) 144 batch_predict = scaler.inverse_transform(batch_predict_std) 145 #最初の要素を消す 146 future_test = np.delete(future_test, 0) 147 #future_testの最後尾にbatch_predict_stdを追加する 148 future_test = np.append(future_test, batch_predict_std) 149 #future_resultにstep2日目のデータを追加 150 future_result = np.append(future_result, batch_predict) 151 152# 未来の予測データを保存していく変数作成時に出来た不要な最初の要素を削除 153future_result = np.delete(future_result, 0) 154 155## 予測結果をプロット 156pre_date = df.index[-len(y_test + future_result):].values 157plt.title('未来の予測値', fontname="MS Gothic") 158plt.plot(pre_date, y_test, 'b', alpha=0.6, marker='.', label='Real', linewidth=1) 159plt.plot(pre_date, predict, 'r', alpha=0.6, marker='.', label='predict', linewidth=1) 160plt.plot(range(len(predict) , len(future_result) + len(predict)), future_result, 'g', alpha=0.6, marker='.', label='future_predict', linewidth=1) 161plt.xticks(rotation=70) 162plt.legend() 163plt.grid(True) 164plt.show()
実行結果
RMSEの出力
943.44
【環境】
windows10
visual studio 2019 community
python 3
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/04/26 12:30