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

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

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

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

Q&A

解決済

2回答

8106閲覧

kerasを用いたRNNについてpredictがうまく機能しない

yohehe

総合スコア48

Python

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

0グッド

0クリップ

投稿2018/07/13 08:14

編集2018/07/13 15:40

kerasを用いたRNNのプログラミングを勉強しております。

RNNを用いて乗客数のグラフの予測をしているサイトがありましたので、それをkerasで行なってみたいと思って以下のプログラムを作ってみております。predictが全く予測していなく、困っております。
以下RNN学習のために試しておりますプログラムです。

python

1 2df = pd.read_csv('international-airline-passengers.csv',skipfooter=3) 3 4data=np.array(data) 5 6sabun_data=[] 7for i in range(len(data)-1): 8 temp_sabun=data[i+1]-data[i] 9 sabun_data.append(temp_sabun) 10sabun_data=np.array(sabun_data) 11data=sabun_data 12#data.shapeは(143)です。 13 14#sinwaveを予測するプログラミングを参考にしてます。 15 16#5個ずつのデータサイズごとにX,yを作成する。 17X_data=[] 18target=[] 19 20manabu_len=5 21for i in range(0,len(data)-manabu_len): 22 X_data.append(data[i:i+manabu_len]) 23 target.append(data[i+manabu_len]) 24 25from sklearn.model_selection import train_test_split 26X=np.array(X_data).reshape(len(X_data),manabu_len,1) 27y=np.array(target).reshape(len(X_data),1) 28(train_X,test_X,train_y,test_y)=train_test_split(X,y,test_size=0.2) 29 30from keras.layers import LSTM,SimpleRNN 31from keras.models import Sequential 32from keras.optimizers import Adam 33from keras.layers import Dense,Activation 34 35n_in=1 36n_hidden=20 37n_out=1 38model=Sequential() 39model.add(LSTM(n_hidden,input_shape=(manabu_len,n_in),kernel_initializer="random_normal")) 40model.add(Dense(n_out)) 41model.add(Activation("linear")) 42model.compile(loss="mean_squared_error",optimizer="Adam") 43model.fit(X,y,batch_size=20,epochs=100,validation_data=(test_X,test_y)) 44 45 46#modelを参考にして、predictをグラフ化してみる。 47 48#予測したデータをpredictに格納してグラフにしてみる。 49in_=X[:1] 50predicted=[] 51for i in range(len(data)-manabu_len): 52 out_=model.predict(in_) 53 in_ = np.vstack( (in_.reshape(manabu_len,n_in)[1:], out_)).reshape(1, manabu_len, n_in) 54 predicted.append(out_.reshape(-1)) 55plt.plot(data, label="original") 56plt.plot(predicted, label="predicted") 57plt.legend() 58plt.show() 59コード

イメージ説明

他のサイトでは、同じdata数でtensorflow,tflearnでグラフに近似したpredictを出せているみたいなのですが、自分のプログラミングの問題がどこにあるのかわからないでおります。SimpleRNNなどもためしてみましたが同じ状況でした。
RNNについて初心者ですが、アドバイスをいただけますと幸いです。よろしくお願いいたします。

==========================================================
追記

アドバイスをいただきまして差分データから特徴量と教師データにすることで予測できるようになってきました.
ありがとうございます。
#差分データ予想
イメージ説明

差分データから得られた元データと予測の比較
イメージ説明
ただ、手法によるためか精度には課題が多いようです。進むにつれてかなりずれていきました。
精度を上げられるようにするにはどうすべきか、いろいろ調べてみます。

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

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

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

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

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

mkgrei

2018/07/13 11:26 編集

他のサイトとは?同じデータを使っているんですか?
yohehe

2018/07/13 11:56

追記ですが、yを設定する際に使用しているinput_lenの数値を大きくしても同じようになってしまっています。
guest

回答2

0

解決済みですので、参考まで。
時系列データをモデル化する際、以下の考慮について事前分析する必要があります。
1.定常性の有無とその調整
定常性とはおおまかにいうと、一定の数値を中心に一定範囲内で安定的に振幅している状態のことをいいます。この条件を満たしていないと時系列モデルによる予測値がズレやすくなります。今回の場合、時間が進むにつれて振幅幅が大きいのでこれをうまく調整する必要があります。推測でしかありませんが、np.logを適用して振幅が小さくなるようにしたほうがいいかと思います。
2.モデルの構造
通常は自己相関(つまり、過去の値に係数をかけるイメージ)でうまくいくのですが、トレンドが含まれているようなデータの場合は、過去のデータに加算するようなモデルのほうがうまくいきます。mkgreiさんの指摘はこのケースで、本データの場合、右肩上がりというトレンドを含んでいるようなので階差を取るとうまくいきます。ただし、階差がひとつでいいのかそれ以上なのかはケースバイケースなので、事前分析をした上でどの程度の階差を取るべきかを検討したほうがいいでしょう。
3.季節周期性の有無
本データの内容次第のところがありますが、月単位や日単位の場合、観光シーズンや週末は値が大きくなるといった季節周期性があるケースも考慮するべきかと思います。必要に応じて月や曜日などをダミー変数化してモデルに組み込むといいでしょう。

投稿2018/07/14 00:34

R.Shigemori

総合スコア3376

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

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

yohehe

2018/07/14 03:22

R.shigemori様、アドバイス感謝致します。 階差である差分をもとに学習させてみたのですが、 教えていただきましたlogなどで振幅を小さくするという手法なども試してみたいと思います。 モデルの構造を事前に分析する際には、事前の分析が重要だとういうことが今回学べました。時系列分析について調べてみると、自己相関係数の推定などさまざまな手法があるのですね。 ダミー変数などでデータを増やすような手法については今のところやり方がわからないため、教えていただいた方法を一つずつ勉強していこうと思います。 ありがとうございます。
guest

0

ベストアンサー

再現できません。

そもそも質問内のコードは正しく動くはずのないものです。
まず、データの形に問題があります。→エラーになる
そして、推定値の変数名が間違っています。→エラーになる

書き写したのですか?


とりあえず動くものを載せておくので参考にしてみてください。

python

1import pandas as pd 2import numpy as np 3import keras 4from keras.models import Sequential 5from keras.layers import LSTM, Dense, Activation, Dropout 6from keras.optimizers import Adagrad 7import matplotlib.pyplot as plt 8%matplotlib inline 9 10data = pd.read_csv('international-airline-passengers.csv', skipfooter=3) 11data = data.values[:, -1] 12data = data[1:] - data[:-1] 13 14inputdata = [] 15target = [] 16input_len = 5 17 18for i in range(0, len(data)-input_len): 19 inputdata.append(data[i:i+input_len]) 20 target.append(data[i+input_len]) 21 22from sklearn.model_selection import train_test_split 23 24X = np.array(inputdata).reshape(-1, input_len, 1) 25y = np.array(target).reshape(-1, 1) 26(train_X, test_X, train_y, test_y) = train_test_split(X, y, test_size=0.2, shuffle=False) 27 28n_in = 1 29n_hidden = 50 30n_out = 1 31model = Sequential() 32model.add(LSTM(n_hidden, input_shape=(input_len,n_in))) 33model.add(Dense(100, activation='relu')) 34model.add(Dropout(0.5)) 35model.add(Dense(5, activation='relu')) 36model.add(Dense(100, activation='relu')) 37model.add(Dropout(0.5)) 38model.add(Dense(n_out, activation='linear')) 39opt = Adagrad() 40model.compile(loss="mean_squared_error",optimizer=opt) 41 42model.fit(train_X, train_y, batch_size=len(X)//10, epochs=50, validation_data=(test_X, test_y)) 43 44py = model.predict(train_X) 45py_ = model.predict(test_X) 46 47px = np.arange(predicted.shape[0]) 48 49fig, ax = plt.subplots(dpi=200) 50ax.plot(y, label="original") 51ax.plot(px[:len(py)], py, label="predicted_train", color='orange') 52ax.plot(px[len(py):], py_, label="predicted_test", color='red') 53plt.legend() 54plt.grid() 55plt.show()

投稿2018/07/13 12:13

編集2018/07/13 13:04
mkgrei

総合スコア8560

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

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

yohehe

2018/07/13 12:28

すみません。csvで読み込んで df = pd.read_csv('international-airline-passengers.csv',skipfooter=3) data=df['International airline passengers: monthly totals in thousands. Jan 49 ? Dec 60'] で読み込んで、動作はしているのですが。 epochs=1000以上にしたとしても損失係数が一定から低下しないため、手法自体がこれではいけないかもしれません。
mkgrei

2018/07/13 12:39

X=np.array(inputdata).reshape(len(data),input_len,1) これ、エラーになりませんか? ...predicted.append(out_.reshape(-1)) . . . plt.plot(predict, label="predicted") このプロットしているものはなんですか? もしjupyterなどを使用しているのであれば、過去の履歴から持ってきている可能性があるので、 何を見ているのか定かではありませんよ。 正しくコードを書き換えても今のままだとうまく学習できませんが、 そもそも今はそれ以前の状態です。
yohehe

2018/07/13 13:03 編集

プログラム修正しました。変数が変わっていることは何度か試しているだけで、特に意味ありません。jupiternotebook上で動作しています。 model.fitで学習させて、 Xのデータ1つずつをpredictに入れて、predictで分類器が予想したデータをout_としてグラフに起こせていると思ったのですが,,,reshape(-1)は(141,1,1)の3次元になっているため、次元数を落とすために使用しています。 そもそも全てがおかしいかもしれません。最初から検討してみます。。。
yohehe

2018/07/13 12:55

mkgrei様ありがとうございます。
mkgrei

2018/07/13 13:01

ポイントは元のデータの差分を最初に取ることです。 右肩上がりになってしまうので。
yohehe

2018/07/13 13:06

勉強になります。RNNなどではそのままのデータから学習させる方法は望ましくないのですね。元データの差分を分類器に学習させられるようにプログラムを大幅に変更してみます。
mkgrei

2018/07/14 17:11

追記についてですが、 この2枚めのグラフはどのようなものをプロットしているのでしょうか? もし差分データの予測を累積して処理しているのであれば、場合によっては問題設定に難があります。 時系列データというのは未来を知ることはできませんが、過去を知ることができます。 ですので、予測する際にも、過去の実データを使って予測に使っていて、過去の予測データを予測に使っていません。 ですので、純粋な累計データではなく、1ステップ前の値と予測した差分値を算出する必要があります。 任意の時点ではそれ以前の正解値を知ることができるという前提が今のモデルにはあります。 ただ、上記を加味しても、今回のデータでは振幅が時間の経過に伴って増加しますので、振幅の増加率に対するモデルを追加するか、時間も特徴量として取り入れると良いかもしれません。 この点に関してはR.Shigemoriさんの回答を参考にされるとよいかと。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問