Kerasを使用して時系列の将来の値を予測する方法


11

KerasでこのLSTMニューラルネットワーク構築しました

    import numpy as np
    import pandas as pd 
    from sklearn import preprocessing
    from keras.layers.core import Dense, Dropout, Activation
    from keras.activations import linear
    from keras.layers.recurrent import LSTM
    from keras.models import Sequential
    from matplotlib import pyplot

    #read and prepare data from datafile
    data_file_name = "DailyDemand.csv"
    data_csv = pd.read_csv(data_file_name, delimiter = ';',header=None, usecols=[1,2,3,4,5])
    yt = data_csv[1:]
    data = yt
    data.columns = ['MoyenneTransactHier', 'MaxTransaction', 'MinTransaction','CountTransaction','Demand']
    # print (data.head(10))
    pd.options.display.float_format = '{:,.0f}'.format
    data = data.dropna ()
    y=data['Demand'].astype(int)
    cols=['MoyenneTransactHier', 'MaxTransaction', 'MinTransaction','CountTransaction']
    x=data[cols].astype(int)

    #scaling data
    scaler_x = preprocessing.MinMaxScaler(feature_range =(-1, 1))
    x = np.array(x).reshape ((len(x),4 ))
    x = scaler_x.fit_transform(x)
    scaler_y = preprocessing.MinMaxScaler(feature_range =(-1, 1))
    y = np.array(y).reshape ((len(y), 1))
    y = scaler_y.fit_transform(y)
    print("longeur de y",len(y))
    # Split train and test data
    train_end = 80
    x_train=x[0: train_end ,]
    x_test=x[train_end +1: ,]
    y_train=y[0: train_end]
    y_test=y[train_end +1:] 
    x_train=x_train.reshape(x_train.shape +(1,))
    x_test=x_test.reshape(x_test.shape + (1,))

    print("Data well prepared")
    print ('x_train shape ', x_train.shape)
    print ('y_train', y_train.shape)

    #Design the model - LSTM Network
    seed = 2016
    np.random.seed(seed)
    fit1 = Sequential ()
    fit1.add(LSTM(
        output_dim = 4,
        activation='tanh',
        input_shape =(4, 1)))
    fit1.add(Dense(output_dim =1))
    fit1.add(Activation(linear))
    #rmsprop or sgd
    batchsize = 1
    fit1.compile(loss="mean_squared_error",optimizer="rmsprop")
    #train the model
    fit1.fit(x_train , y_train , batch_size = batchsize, nb_epoch =20, shuffle=True)

    print(fit1.summary ())

    #Model error
    score_train = fit1.evaluate(x_train ,y_train ,batch_size =batchsize)
    score_test = fit1.evaluate(x_test , y_test ,batch_size =batchsize)
    print("in  train  MSE = ",round(score_train,4))
    print("in test  MSE = ",round(score_test ,4))

    #Make prediction
    pred1=fit1.predict(x_test)
    pred1 = scaler_y.inverse_transform(np.array(pred1).reshape ((len(pred1), 1)))
    real_test = scaler_y.inverse_transform(np.array(y_test).reshape ((len(y_test), 1))).astype(int)

    #save prediction
    testData = pd.DataFrame(real_test)
    preddData = pd.DataFrame(pred1)
    dataF = pd.concat([testData,preddData], axis=1)
    dataF.columns =['Real demand','Predicted Demand']
    dataF.to_csv('Demandprediction.csv')

    pyplot.plot(pred1, label='Forecast')
    pyplot.plot(real_test,label='Actual')
    pyplot.legend()
    pyplot.show()

それからこの結果を生成します: テストデータの予測

履歴データに基づいて適切なモデルを構築およびトレーニングした後、将来の値の予測を生成する方法がわかりません。たとえば、次の10日間の需要。データは毎日です。

これは、データの形成方法の例です

注:これは、データがどのように形成されるかの例です。緑はラベル、黄色は特徴です。(null値を削除して)100データ行のままにした
dropna()、トレーニングで80を使用し、テストで20を使用しました。


時系列を分解すると、インスタンスはいくつありますか?
JahKnows、2018

すみません、わかりません。詳しく説明してもらえますか?ありがとう
Nbenz

予測の問題のためにデータを再構成した後、何行の例がありますか?
JahKnows、

ポイントの単一の時系列を教えてもらえますか。それらを使用して予測を行う方法を紹介します。
JahKnows、

データ形式と形状の例を追加して、私が編集した質問をもう一度確認できます。ありがとう
Nbenz

回答:


5
この答えは少し違う方向に進みますが、それでもあなたの質問に答えられることを願っています。それはローリング予測/予測のアイデアを使用しています。

horizo​​nという単語を使用しているので、特定のタイムステップで10日後の未来を予測するとします。これを行うにはいくつかの方法があります。この種の時系列問題では、特定の履歴のみが次のいくつかの時間ステップに影響を与えると仮定することが一般的です(季節的影響を無視します)。

言葉の例:

したがって、あなたのケースでは、たとえば過去60日間を使用して、次の10日を予測することができます。100行のデータを例にとると、これは実際に(100 - 60 - 9) = 31予測を行うことができることを意味します。31 predictive_blocks以降)。100行から、最初のモデルに合うように最初の60行を失います。残りの40行のデータのうち、10ステップ先(行61〜70)を予測してから、全体を1行さらにシフトして繰り返します。10個の将来のポイントの最後の予測は、91〜100行になります。その後、10ステップを予測することができなくなったため、停止します。そのため、余分な9を差し引く必要があります。[もちろん、すべてのデータを使用して、予測を続ける方法があります]

1000語の例:

絵を描いてみましょう。シフティングウィンドウ予測のアイデアを説明するのに役立ちます。

各列車のセット(例えばからt=0t=5赤-電車セット1)、あなたは( -テストセット1トンオレンジ= 6に相当)以下のHの時間ステップを予測します。これでは、あなたの地平線は1つだけH=1です。

ローリングサンプル外予測の基本的なスケッチ

私が理解していることから、あなたは次の10日間を予測したいと考えていますH=10

あなたの例でこれを試すには、2つの変更を行う必要があると思います。

変更#1

列車とテストセットの形状は、新しい地平線と一致する必要があります。モデル入力の各サンプル(x_trainおよびx_testは以前と同じままにすることができます。ただし、テストセットの各サンプルにはH=10、単一の値だけでなく、ラベルの次の値を含める必要があります。

以下は、これを行う方法の大まかな例です。

# Define our horizon
H = 10

# Create data split, using values from my example above
window_size = 60
num_pred_blocks = 31    # as computed above

# Loop over the train and test samples to create the sliding window sets
x_train = []
y_train = []
for i in range(num_pred_blocks):
    x_train_block = x_train[i:(i + window_size)]    # 31 blocks of 60 * num-columns
    x_train.append(x_train_block)
    y_train_block = y_train[(i + window_size):(i + window_size + H)]    # 31 blocks of 10 * 1
    y_train.append(y_train_block)

サンプル外のテストを実行しているので、分析を見て予測はすでに興味深いものになっています。これが実行されると、言及した新しいデータを使用して同等のテストデータセットを作成できます。

データをよく知らなければ、入力と同じ行または次の行のy値を予測する必要があるかどうかはわかりません。さらに、データによってはy、各x_trainブロックにの過去の値を含めることができます。この場合x、テーブル全体data[cols]、つまりをスワップするだけnew_cols = ['Demand'] + colsです。

変更#2

モデルに出力H値を強制することにより、この範囲をモデルに反映させる必要があります。

モデルを指定する方法の例を次に示します。

# Define our horizon
H = 10

# Create the model using the parameterised horizon
fit1 = Sequential ()
fit1.add(LSTM(output_dim = 4, activation='tanh', input_shape =(4, 1)))
fit1.add(Dense(output_dim=30, activation='sigmoid')
fit1.add(Dense(output_dim=H))    # our horizon is produced!

注: モデル仕様ではActivation、前の高密度レイヤーにデフォルトで線形アクティベーションが含まれているため、最後の線形を追加する必要はありません。こちらの優れたドキュメントをご覧ください

これは大きなトピックであり、試すことができる多くのものがあります。私はあなたの質問に対するコメントに同意します。RNNがモデルの意味表現を作成するには、より多くのデータが必要になるということです。

これをLSTMなどについて学ぶためだけに行っているのではない場合、別の実用的なアプローチは、ARIMAモデルなどのより単純な時系列モデルを調べることです(複雑な名前に怯えないでください-LSTMよりもはるかに簡単です)。 。そのようなモデルは、素晴らしい実装を備えstatsmodelsパッケージを使用して Pythonで非常に簡単に構築できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.