Come prevedere i valori futuri dell'orizzonte temporale con Keras?


11

Ho appena costruito questa rete neurale LSTM con 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()

quindi genera questo risultato: Predizione sui dati del test

Dopo aver costruito e addestrato un buon modello sui dati storici, non so come posso generare la previsione per i valori futuri? Ad esempio la domanda dei prossimi 10 giorni. I dati sono giornalieri.

questo è un esempio di come vengono modellati i dati

NB: questo è un esempio di come sono modellati i dati, il verde è l'etichetta e quello giallo sono le caratteristiche.
dopo dropna()(elimina i valori null) rimane 100 righe di dati, ne ho usate 80 in allenamento e 20 in test.


Quando interrompi le tue serie temporali, quanti casi hai?
JahKnows,

Mi dispiace signore, non ho capito, puoi spiegarmi di più? grazie
Nbenz,

Dopo aver ristrutturato i dati per un problema di previsione, quante righe di esempi hai?
JahKnows

Puoi darmi una singola sequenza temporale di punti e ti mostrerò come fare previsioni con loro.
JahKnows

Puoi ricontrollare la domanda che ho modificato aggiungendo un esempio del formato e della forma dei dati. grazie
Nbenz,

Risposte:


5
Questa risposta va un po 'in un'altra direzione, ma spero che risponda ancora alla tua domanda. Usa l'idea di una previsione / previsione a rotazione.

Poiché usi la parola orizzonte , suppongo che intendi dire che vorresti prevedere 10 giorni nel futuro in un determinato momento. Ci sono alcuni modi per farlo. Con questo tipo di problema con le serie storiche, è comune supporre che solo una certa storia influenzerà i prossimi passi temporali (trascurando gli effetti stagionali).

Esempio in parole:

Quindi, nel tuo caso, potresti usare ad esempio i 60 giorni precedenti e prevedere i prossimi 10. Prendendo ad esempio le tue 100 righe di dati, ciò significa che puoi effettivamente fare (100 - 60 - 9) = 31previsioni, ciascuna previsione di 10 passi temporali in avanti (avremo bisogno di questi 31 predictive_blocks in seguito). Da 100 file perdiamo i primi 60 per adattarci al primo modello. Delle restanti 40 righe di dati, possiamo prevedere 10 passi avanti (righe 61-70), quindi spostiamo il tutto ulteriormente di una riga e ripetiamo. L'ultima previsione di 10 punti futuri sarebbe per le righe 91-100. Dopodiché non possiamo più prevedere 10 passaggi, quindi ci fermiamo - ed è per questo che dobbiamo sottrarre quel 9 in più. [Ci sono ovviamente modi per continuare a fare previsioni, in modo da usare tutti i dati]

Esempio con mille parole:

Fammi dipingere l'immagine; per aiutare a spiegare l'idea di una previsione a finestra mobile.

Per ogni set di treni (ad es. Da t=0a t=5in rosso - set di treni 1), si desidera prevedere le seguenti fasi temporali H (corrispondenti a t = 6 in arancione - set di test 1). In questo, il tuo orizzonte è semplicemente uno, cioè H=1.

Schizzo di base di una previsione di roll out del campione

Da quello che ho capito, ti piacerebbe prevedere i prossimi 10 giorni, il che significa che hai bisogno H=10.

Per provare questo con il tuo esempio, penso che dovrai apportare due modifiche.

Modifica n. 1

La forma del treno e dei set di prova dovrà corrispondere al nuovo orizzonte. Ogni campione del tuo modello di input (il x_traine x_testpuò rimanere lo stesso di prima. Tuttavia, ogni campione nel tuo set di test dovrà contenere i H=10valori successivi dell'etichetta, non solo un singolo valore.

Ecco un esempio approssimativo di come potresti farlo:

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

Poiché stai eseguendo test fuori campione, le tue previsioni sono già interessanti da analizzare. Una volta eseguito, è possibile creare set di dati di test equivalenti con i nuovi dati citati.

Senza conoscere troppo bene i tuoi dati, non so se dovresti prevedere i valori y della stessa riga dell'input o della riga successiva. Inoltre, a seconda dei dati, potresti includere i valori passati di yin ciascuno dei x_trainblocchi. In questo caso dovrai semplicemente scambiare xl'intera tabella data[cols], ad esempio dove new_cols = ['Demand'] + cols.

Modifica n. 2

Dovrai fare in modo che il modello rifletta questo orizzonte, forzandolo ai Hvalori di output .

Ecco un esempio di come specificare il modello:

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

Nota: nelle specifiche del modello, non è necessario aggiungere il lineare finale Activation, poiché il livello Dense precedente per impostazione predefinita include un'attivazione lineare. Vedi l'eccellente documentazione qui .

Questo è un argomento importante e ci sono molte cose che potresti provare. Concordo con i commenti sulla tua domanda, che avrai bisogno di molti più dati per consentire a un RNN di rappresentare in modo significativo il modello.

Se non lo stai solo facendo per conoscere gli LSTM ecc., Un altro approccio pratico potrebbe essere quello di esaminare modelli di serie temporali più semplici come un modello ARIMA (non lasciarti intimidire dal nome complicato - è molto più semplice di un LSTM) . Tali modelli possono essere costruiti abbastanza facilmente con Python, usando il pacchetto statsmodels , che ha una buona implementazione .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.