Bagaimana Memprediksi nilai horizon waktu di masa depan dengan Keras?

11

Saya baru saja membangun jaringan saraf LSTM ini dengan Keras

    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()

kemudian menghasilkan hasil ini: Prediksi pada data uji

Setelah membangun dan melatih model yang baik tentang data historis, saya tidak tahu bagaimana saya bisa menghasilkan prediksi untuk nilai-nilai masa depan? Misalnya permintaan 10 hari ke depan. Data setiap hari.

ini adalah contoh bagaimana data dibentuk

NB: ini adalah contoh bagaimana data dibentuk, hijau adalah label dan yang kuning adalah fitur.
setelah dropna()(hapus nilai nol) tetap 100 baris data, saya telah menggunakan 80 dalam pelatihan dan 20 dalam tes.

Nbenz
sumber
Ketika Anda membagi rangkaian waktu Anda, berapa banyak contoh yang Anda miliki?
JahKnows
Maaf pak, saya tidak mengerti, bisakah Anda menjelaskan lebih lanjut? terima kasih
Nbenz
Setelah merestrukturisasi data Anda untuk masalah perkiraan, berapa banyak baris contoh yang Anda miliki?
JahKnows
Bisakah Anda memberi saya urutan waktu poin tunggal dan saya akan menunjukkan kepada Anda bagaimana melakukan peramalan dengan mereka.
JahKnows
Anda dapat memeriksa kembali pertanyaan yang telah saya edit dengan menambahkan contoh format dan bentuk data. terima kasih
Nbenz

Jawaban:

5
Jawaban ini berjalan sedikit ke arah yang berbeda, tetapi saya harap jawaban ini tetap menjawab pertanyaan Anda. Ini menggunakan ide bergulir ramalan / prediksi.

Karena Anda menggunakan kata horizon , saya akan menganggap Anda bermaksud memprediksi 10 hari ke depan pada langkah waktu tertentu. Ada beberapa cara untuk melakukan ini. Dengan masalah deret waktu semacam ini, adalah umum untuk membuat asumsi bahwa hanya sejarah tertentu yang akan memengaruhi beberapa langkah waktu berikutnya (mengabaikan efek musiman).

Contoh dalam kata-kata:

Jadi, dalam kasus Anda, Anda dapat menggunakan mis. 60 hari sebelumnya, dan memperkirakan 10. hari berikutnya. Mengambil 100 baris data Anda sebagai contoh, ini berarti Anda benar-benar dapat membuat (100 - 60 - 9) = 31prediksi, masing-masing prediksi 10 langkah waktu ke depan (kita akan membutuhkan ini 31 predictive_block nanti). Dari 100 baris kita kehilangan 60 pertama sesuai model pertama. Dari 40 baris data yang tersisa, kita dapat memprediksi 10 langkah di depan (baris 61-70), lalu kita menggeser semuanya satu baris lebih jauh dan ulangi. Prediksi terakhir dari 10 poin mendatang adalah untuk baris 91-100. Setelah itu kami tidak dapat memprediksi 10 langkah lagi, jadi kami berhenti - dan inilah mengapa kami harus mengurangi tambahan itu 9. [Tentu saja ada cara untuk terus membuat prediksi, seperti menggunakan semua data]

Contoh dengan seribu kata:

Biarkan saya melukis gambarnya; untuk membantu menjelaskan gagasan prediksi jendela bergeser.

Untuk setiap set kereta api (mis. Dari t=0ke t=5dalam set kereta merah 1), Anda ingin memprediksi langkah waktu H berikut ini (sesuai dengan t = 6 dalam warna oranye - set tes 1). Dalam hal ini, cakrawala Anda hanyalah satu H=1.

Sketsa dasar dari perkiraan keluar sampel yang bergulir

Dari apa yang saya mengerti, Anda ingin memprediksi 10 hari ke depan, artinya Anda perlu H=10.

Untuk mencoba ini dengan contoh Anda, saya pikir Anda perlu membuat dua perubahan.

Ubah # 1

Bentuk kereta dan set tes Anda harus sesuai dengan cakrawala baru. Setiap sampel input model Anda ( x_traindan x_testdapat tetap sama seperti sebelumnya. Namun, setiap sampel dalam set pengujian Anda harus berisi H=10nilai label berikutnya, bukan hanya nilai tunggal.

Berikut ini adalah contoh kasar bagaimana Anda dapat melakukan ini:

# 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)

Karena Anda melakukan pengujian di luar sampel, prediksi Anda sudah menarik untuk dianalisis. Setelah ini berjalan, Anda kemudian dapat membuat dataset uji yang setara dengan data baru yang Anda sebutkan.

Tanpa mengetahui data Anda dengan baik, saya tidak tahu apakah Anda harus memprediksi nilai-y dari baris yang sama dengan input, atau dari baris berikut. Selain itu, tergantung pada data Anda, Anda bisa menyertakan nilai masa lalu ydi setiap x_trainblok. Dalam hal ini Anda cukup menukar xseluruh tabel yaitu data[cols], di mana new_cols = ['Demand'] + cols.

Ubah # 2

Anda harus membuat model mencerminkan cakrawala ini, dengan memaksakannya ke Hnilai output .

Berikut adalah contoh cara menentukan model:

# 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!

Catatan: Dalam spesifikasi model Anda, Anda tidak perlu menambahkan linear final Activation, karena layer Dense sebelumnya secara default termasuk aktivasi linear. Lihat dokumentasi yang sangat baik di sini .

Ini adalah topik besar dan ada banyak hal yang bisa Anda coba. Saya setuju dengan komentar pada pertanyaan Anda, bahwa Anda akan memerlukan lebih banyak data untuk memungkinkan RNN membuat representasi makna dari model.

Jika Anda tidak hanya melakukan ini untuk mempelajari tentang LSTM dll., Pendekatan praktis lain mungkin untuk melihat ke dalam model time-series yang lebih sederhana seperti model ARIMA (jangan terintimidasi dengan nama yang rumit - itu jauh lebih sederhana daripada LSTM) . Model seperti itu dapat dibangun dengan mudah dengan Python, menggunakan paket statsmodels , yang memiliki implementasi yang bagus .

n1k31t4
sumber