¿Cómo predecir los valores futuros del horizonte temporal con Keras?

11

Acabo de construir esta red neuronal 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()

entonces genera este resultado: Predicción sobre los datos de la prueba.

Después de construir y entrenar un buen modelo sobre los datos históricos, no sé cómo puedo generar la predicción de valores futuros. Por ejemplo, la demanda de los próximos 10 días. Los datos son diarios.

este es un ejemplo de cómo se forman los datos

NB: este es un ejemplo de cómo se forman los datos, el verde es la etiqueta y el amarillo son las características.
después dropna()(eliminar valores nulos) quedan 100 filas de datos, he usado 80 en el entrenamiento y 20 en la prueba.

Nbenz
fuente
Cuando rompes tu serie temporal, ¿cuántas instancias tienes?
JahKnows
Lo siento señor, no lo tengo, ¿puede explicar más? gracias
Nbenz
Después de haber reestructurado sus datos para un problema de pronóstico, ¿cuántas líneas de ejemplos tiene?
JahKnows
¿Me puede dar una secuencia de puntos única y le mostraré cómo hacer pronósticos con ellos?
JahKnows
Puede verificar nuevamente la pregunta que la edité agregando un ejemplo del formato y la forma de los datos. gracias
Nbenz

Respuestas:

5
Esta respuesta va un poco en una dirección diferente, pero espero que aún responda a su pregunta. Utiliza la idea de un pronóstico continuo / predicción.

Debido a que usa la palabra horizonte , supondré que quiere decir que le gustaría predecir 10 días en el futuro en un paso de tiempo dado. Hay algunas formas de hacer esto. Con este tipo de problema de series de tiempo, es común suponer que solo un cierto historial influirá en los próximos pasos de tiempo (descuidando los efectos estacionales).

Ejemplo en palabras:

Entonces, en su caso, puede usar, por ejemplo, los 60 días anteriores y predecir los próximos 10. Tomando sus 100 filas de datos como ejemplo, esto significa que puede hacer (100 - 60 - 9) = 31predicciones, cada predicción de 10 pasos de tiempo por delante (necesitaremos estos 31 predictive_blocks después). De 100 filas perdemos los primeros 60 para adaptarse al primer modelo. De las 40 filas de datos restantes, podemos predecir 10 pasos adelante (filas 61-70), luego cambiamos todo el asunto una fila más y repetimos. La última predicción de 10 puntos futuros sería para las filas 91-100. Después de eso, ya no podemos predecir 10 pasos, por lo que nos detenemos, y es por eso que tenemos que restar ese 9. adicional [Por supuesto, hay formas de continuar haciendo predicciones, para usar todos los datos]

Ejemplo con mil palabras:

Déjame pintar el cuadro; para ayudar a explicar la idea de una predicción de ventana cambiante.

Para cada conjunto de trenes (por ejemplo, de t=0a t=5en rojo - conjunto de trenes 1), desea predecir los siguientes pasos de tiempo H (correspondientes a t = 6 en naranja - conjunto de prueba 1). En esto, su horizonte es simplemente uno, es decir H=1.

Bosquejo básico de un pronóstico fuera de muestra

Por lo que entiendo, le gustaría predecir los próximos 10 días, lo que significa que necesita H=10.

Para probar esto con su ejemplo, creo que tendrá que hacer dos cambios.

Cambio n. ° 1

La forma de su tren y conjuntos de prueba deberá coincidir con el nuevo horizonte. Cada muestra de su entrada de modelo ( x_trainy x_testpuede permanecer igual que antes. Sin embargo, cada muestra en su conjunto de prueba tendrá que contener los siguientes H=10valores de la etiqueta, no solo un valor único.

Aquí hay un ejemplo aproximado de cómo podría hacer esto:

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

Debido a que está haciendo pruebas fuera de la muestra, sus predicciones ya son interesantes para analizar. Una vez que esto se ejecuta, puede crear los conjuntos de datos de prueba equivalentes con los nuevos datos que mencionó.

Sin conocer sus datos demasiado bien, no sé si debería predecir los valores y de la misma fila que la entrada o de la siguiente fila. Además, dependiendo de sus datos, podría incluir los valores pasados ​​de yen cada uno de los x_trainbloques. En este caso, simplemente cambiaría xpor la tabla completa, es decir data[cols], dónde new_cols = ['Demand'] + cols.

Cambio n. ° 2

Deberá hacer que el modelo refleje este horizonte, forzándolo a Hvalores de salida .

Aquí hay un ejemplo de cómo especificar el modelo:

# 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: En la especificación de su modelo, no necesita agregar el lineal final Activation, ya que la capa Densa precedente por defecto incluye una activación lineal. Vea la excelente documentación aquí .

Este es un gran tema y hay muchas cosas que puedes probar. Estoy de acuerdo con los comentarios sobre su pregunta, que necesitará muchos más datos para permitir que un RNN haga una representación significativa del modelo.

Si no solo está haciendo esto para aprender sobre LSTM, etc., otro enfoque práctico podría ser buscar modelos de series de tiempo más simples como un modelo ARIMA (no se deje intimidar por el nombre complicado, es mucho más simple que un LSTM) . Tales modelos se pueden construir con bastante facilidad con Python, utilizando el paquete statsmodels , que tiene una buena implementación .

n1k31t4
fuente