質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

676閲覧

LSTMにおいてテストデータのRMSEが不自然に高くなる

multinguish

総合スコア6

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/01/10 13:20

編集2021/01/11 13:21

TensorFlow 2.x での多変量LSTMとデータの前処理
こちらを参考にLSTMによる「flow」の予測モデルを打ち込みました。

python

1import numpy as np 2import pandas as pd 3from matplotlib import pyplot as plt 4%matplotlib inline 5import seaborn as sns 6import time 7 8df = pd.read_csv('12.22min.csv') 9df['time'] = pd.to_datetime(df['time']) 10df

イメージ説明

python

1#ルックバック数 2look_back =15 3 4#データ数 5sample_size = len(df) - look_back 6 7#予測に用いる期間 8past_size = int(sample_size*0.8) 9future_size = sample_size - past_size +1 10 11#データセットを作る関数 12def make_dataset(raw_data, look_back=15): 13 _X = [] 14 _y = [] 15 16 for i in range(len(raw_data) - look_back): 17 _X.append(raw_data[i : i + look_back]) 18 _y.append(raw_data[i + look_back]) 19 _X = np.array(_X).reshape(len(_X), look_back, 1) 20 _y = np.array(_y).reshape(len(_y), 1) 21 22 return _X, _y 23 24from sklearn import preprocessing 25 26columns = list(df.columns) 27 28# 最小0、最大1に正規化 29Xs =[] 30for i in range(len(columns)): 31 Xs.append(preprocessing.minmax_scale(df[columns[i]])) 32Xs = np.array(Xs) 33 34# 各数値データを作成 35X_flow, y_flow = make_dataset(Xs[0], look_back=look_back) 36X_sBP, y_sBP = make_dataset(Xs[1], look_back=look_back) 37X_mBP, y_mBP = make_dataset(Xs[2], look_back=look_back) 38X_dBP, y_dBP = make_dataset(Xs[3], look_back=look_back) 39X_HR, y_HR = make_dataset(Xs[4], look_back=look_back)

ここでは多変量として各因子を定義していますが、今回はflowのみからflowの予測を試みました。

python

1X = X_flow 2y = y_flow 3 4# データを過去分(訓練に用いる分)と未来分(未来の予測に用いる分)に分割 5X_past = X[:past_size] 6X_future = X[past_size-1:] 7y_past = y[:past_size] 8y_future = y[past_size-1:] 9 10# 訓練データを定義 11X_train = X_past 12y_train = y_past 13 14import tensorflow as tf 15from tensorflow.keras.layers import Input, LSTM, Dense, BatchNormalization 16from tensorflow.keras.models import Model 17from tensorflow.keras.optimizers import SGD, Adam 18 19# LSTMモデルを作成する関数 20def create_LSTM_model(): 21 input = Input(shape=(np.array(X_train).shape[1], np.array(X_train).shape[2])) 22 x = LSTM(64, return_sequences=True)(input) 23 x = BatchNormalization()(x) 24 x = LSTM(64)(x) 25 output = Dense(1, activation='relu')(x) 26 model = Model(input, output) 27 return model 28 29model = create_LSTM_model() 30model.summary() 31model.compile(optimizer=Adam(learning_rate=0.0001), loss='mean_squared_error') 32 33# 学習 34history = model.fit(X_train, y_train, epochs=200, batch_size=64, verbose=1) 35 36predictions = model.predict(X_past) 37future_predictions = model.predict(X_future) 38 39plt.figure(figsize=(18, 9)) 40plt.plot(df['time'][look_back:], y, color="b", label="flow") 41plt.plot(df['time'][look_back:look_back + past_size], predictions, color="r", linestyle="dashed", label="prediction") 42plt.plot(df['time'][-future_size:], future_predictions, color="g", linestyle="dashed", label="future_prediction") 43plt.legend() 44plt.show()

イメージ説明

python

1from sklearn.metrics import mean_squared_error 2trainScore_RMSE = math.sqrt(mean_squared_error(y_train[:,0], predictions[:,0])) 3print('Train Score: %.5f RMSE' % (trainScore_RMSE)) 4testScore_RMSE = math.sqrt(mean_squared_error(y_future[:,0], future_predictions[:,0])) 5print('Test Score: %.5f RMSE' % (testScore_RMSE))

Train Score: 0.04890 RMSE
Test Score: 0.08405 RMSE

多変量で行った場合は10~20%程度でしたが、flowのみにすると急に精度が不自然に上がっていまいます。
過去の同様の質問も参照しました。→LSTMで得られた予測精度が不自然に高い
確かに予測が1期前のデータに強く依存していることが読み取れました。
しかし今の自分のレベルではこれをどう改善すべきかがわかりませんでした。

・現在のモデルのまま一部書き換えることで適正なRMSEの算出が可能か
・future_prediction部分を参照しないでこの部分の予測を立てる場合の書き方
・flowデータを差分や対数で変換して予測する場合の書き方

について、実際の書き方、もしくは参考になるサイトや書籍などをご教授いただければ幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

aokikenichi

2021/01/11 03:06

RSMEとありますがRMSEでよろしいですよね。 multinguishさんのおっしゃる「適正なRMSE」とは何でしょうか?その定義があるのであればその通りに書くしかないです。 コードを拝見しますと 予測値と実績値の MSE の平方根を取っているようなので正しいRMSEと思います。
multinguish

2021/01/11 13:28

コメント誠にありがとうございます。 RMSEは適正であれば、モデル定義の問題になるということですね。 http://www.river.or.jp/report_sympo_h2905.pdf こちらの論文のP5-6にかかれている「ワンステップスアヘッド問題」が起きていると考えており、これを避けるにはどのような手法を用いれば良いか、という趣旨の質問と捉えていただければ幸いです。
aokikenichi

2021/01/16 04:25

「RMSEは適正であれば、モデル定義の問題になるということですね。」 そういったことは全く申しておりません。 「適正なRMSE」とはなにか伺っております。「RMSE」というのは通常は予測値と実績値により計算式から導き出されるもので、適正なもなにもないと私は理解しております。 「「ワンステップスアヘッド問題」が起きていると考えており、これを避けるにはどのような手法を用いれば良いか、という趣旨の質問と捉えて」 ならばそう質問に書いていただかないと分からないです。 この減少を「ワンステップスアヘッド問題」と言うのは初めて知りました。ありがとうございます。 これは通常、過去データから学習してもまともな予測値が出ず、前日の値をそのまま次の予測値としたほうがマシな場合に発生するものです。ですので、これを解決したいのは「書き方」ではなく学習のさせ方、アルゴリズムの選択、あるいはこのデータからはこれ以上の予測は出ないのかも知れません。
multinguish

2021/01/20 05:31

コメントまことにありがとうございます。 「これは通常、過去データから学習してもまともな予測値が出ず、前日の値をそのまま次の予測値としたほうがマシな場合に発生するものです。」 自分の誤解に気づくことができました。ありがとうございます。 色々な学習のさせ方を試してみて、やはりこの現象が起きる場合は予測不能として判断しようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問