前提・実現したいこと
初めてLSTMを用いて時系列予測を行ってみましたが、得られた予測結果の精度があまりに高く、不思議に思っています。
実際に入力期間を極めて短く設定するなどして検証してみたところ、RMSEおよびMAPEは共に大差の無い値をとりました。
この場合、どういった誤りが考えられるでしょうか?
コードは以下の記事を参考にしています。
Kerasで多変量LSTM-Qiita
予測した対象は下記のDataFrameにおける"Discharge"列です。
該当のソースコード
python
1#ライブラリのインポートとデータの読み込み 2import numpy as np 3import matplotlib.pyplot as plt 4import pandas as pd 5import math 6from keras.models import Sequential 7from keras.layers import Activation, Dense,Dropout,Flatten 8from keras.layers import LSTM 9from keras.utils.np_utils import to_categorical 10from keras.callbacks import EarlyStopping,TensorBoard,ModelCheckpoint 11from sklearn.preprocessing import MinMaxScaler 12from sklearn.metrics import mean_squared_error 13 14df = pd.read_csv('discharge_prediction.csv', index_col='Datetime') 15df = df.iloc[:, [1,0,2]] 16df.head()
|Datetime|Discharge|Inflow|Precipitation|
|:--|:--:|--:|
|2010-01-01 01:00:00|7.28|7.28|0.0|
|2010-01-01 02:00:00|7.28|15.09|0.0|
|2010-01-01 03:00:00|7.28|22.90|0.0|
|2010-01-01 04:00:00|7.28|7.28|0.0|
|2010-01-01 05:00:00|7.28|20.07|0.0|
python
1dataset = df.values 2 3# データセットの正規化 4scaler = MinMaxScaler(feature_range=(0, 1)) 5dataset_scaled = scaler.fit_transform(dataset) 6 7# 訓練データとテストデータに分割 8train_size = int(len(dataset_scaled) * 0.7) 9test_size = len(dataset_scaled) - train_size 10train, test = dataset_scaled[0:train_size,:], dataset_scaled[train_size:len(dataset_scaled),:] 11print(len(train), len(test))
61353 26295
python
1#値の行列をデータセットに用いる形に変換 2def create_dataset(dataset, look_back=1): 3 dataX, dataY = [], [] 4 for i in range(len(dataset)-look_back-1): 5 xset = [] 6 for j in range(dataset.shape[1]): 7 a = dataset[i:(i+look_back), j] 8 xset.append(a) 9 dataY.append(dataset[i + look_back, 0]) 10 dataX.append(xset) 11 return np.array(dataX), np.array(dataY) 12 13# X=t,Y=t+1の形に変換 14look_back = 24 15trainX, trainY = create_dataset(train, look_back) 16testX, testY = create_dataset(test, look_back) 17print(testX.shape) 18print(testX[0]) 19print(testY) 20 21# 入力を [samples, time steps(number of variables), features] にリシェイプ 22trainX = np.reshape(trainX, (trainX.shape[0], trainX.shape[1], trainX.shape[2])) 23testX = np.reshape(testX, (testX.shape[0], testX.shape[1], testX.shape[2])) 24print(testX)
python
1#モデルの構築 2from keras.models import Sequential 3from keras.layers import Activation, Dense,Dropout,Flatten 4from keras.layers import LSTM 5from keras.utils.np_utils import to_categorical 6from keras.callbacks import EarlyStopping,TensorBoard,ModelCheckpoint 7 8es_cb = EarlyStopping(monitor='loss', patience=30, verbose=0, mode='auto') 9modelCheckpoint = ModelCheckpoint(filepath = "weights.hdf5",monitor='loss',verbose=0,save_best_only=True,save_weights_only=False,mode='min',period=1) 10 11model = Sequential() 12model.add(LSTM(50, input_shape=(testX.shape[1], look_back), return_sequences=False,go_backwards=True)) 13model.add(Dense(1)) 14model.add(Activation("linear")) 15model.compile(loss="mean_squared_error", optimizer="rmsprop") 16 17#モデルの学習 18model.fit(trainX, trainY, epochs=1500, batch_size=100,verbose=2, callbacks=[es_cb,modelCheckpoint])
python
1# 予測値を出力 2trainPredict = model.predict(trainX) 3testPredict = model.predict(testX) 4pad_col = numpy.zeros(dataset.shape[1]-1) 5 6# 出力を正規化前に戻す 7def pad_array(val): 8 return numpy.array([numpy.insert(pad_col, 0, x) for x in val]) 9 10trainPredict = scaler.inverse_transform(pad_array(trainPredict)) 11trainY = scaler.inverse_transform(pad_array(trainY)) 12testPredict = scaler.inverse_transform(pad_array(testPredict)) 13testY = scaler.inverse_transform(pad_array(testY)) 14 15# RMSEとMAPEを算出 16trainScore_RMSE = math.sqrt(mean_squared_error(trainY[:,0], trainPredict[:,0])) 17print('Train Score: %.2f RMSE' % (trainScore_RMSE)) 18testScore_RMSE = math.sqrt(mean_squared_error(testY[:,0], testPredict[:,0])) 19print('Test Score: %.2f RMSE' % (testScore_RMSE)) 20 21trainScore_MAPE = np.mean(np.abs((trainPredict[:,0] - trainY[:,0]) / trainY[:,0])) * 100 22print('Train Score: %.2f MAPE' % (trainScore_MAPE)) 23testScore_MAPE = np.mean(np.abs((testPredict[:,0] - testY[:,0]) / testY[:,0])) * 100 24print('Test Score: %.2f MAPE' % (testScore_MAPE))
Train Score: 0.81 RMSE
Test Score: 3.06 RMSE
Train Score: 8.77 MAPE
Test Score: 5.80 MAPE
回答2件
あなたの回答
tips
プレビュー