Cómo manejar Shift en el valor previsto

Implementé un modelo de pronóstico utilizando LSTM en Keras. El conjunto de datos está separado por 15 minutos y pronostico 12 pasos futuros.

El modelo funciona bien para el problema. Pero hay un pequeño problema con el pronóstico realizado. Está mostrando un pequeño efecto de cambio. Para obtener una imagen más clara, consulte la figura adjunta a continuación.

introduzca la descripción de la imagen aquí

¿Cómo manejar este problema? ¿Cómo se deben transformar los datos para manejar este tipo de problema?

El modelo que utilicé se da a continuación.

init_lstm = RandomUniform(minval=-.05, maxval=.05) init_dense_1 = RandomUniform(minval=-.03, maxval=.06) model = Sequential() model.add(LSTM(15, input_shape=(X.shape[1], X.shape[2]), kernel_initializer=init_lstm, recurrent_dropout=0.33)) model.add(Dense(1, kernel_initializer=init_dense_1, activation='linear')) model.compile(loss='mae', optimizer=Adam(lr=1e-4)) history = model.fit(X, y, epochs=1000, batch_size=16, validation_data=(X_valid, y_valid), verbose=1, shuffle=False) 

Hice las previsiones como esta

 my_forecasts = model.predict(X_valid, batch_size=16) 

Los datos de series de tiempo se transforman a supervisados ​​para alimentar el LSTM utilizando esta función

 # convert time series into supervised learning problem def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = list(), list() # input sequence (tn, ... t-1) for i in range(n_in, 0, -1): cols.append(df.shift(i)) names += [('var%d(t-%d)' % (j+1, i)) for j in range(n_vars)] # forecast sequence (t, t+1, ... t+n) for i in range(0, n_out): cols.append(df.shift(-i)) if i == 0: names += [('var%d(t)' % (j+1)) for j in range(n_vars)] else: names += [('var%d(t+%d)' % (j+1, i)) for j in range(n_vars)] # put it all together agg = concat(cols, axis=1) agg.columns = names # drop rows with NaN values if dropnan: agg.dropna(inplace=True) return agg super_data = series_to_supervised(data, 12, 1) 

Mi serie temporal es multivariable. var2 es el que necesito pronosticar. Dejé caer el futuro var1 como

 del super_data['var1(t)'] 

Tren separado y válido como este.

 features = super_data[feat_names] values = super_data[val_name] ntest = 3444 train_feats, test_feats = features[0:-n_test], features[-n_test:] train_vals, test_vals = values [0:-n_test], values [-n_test:] X, y = train_feats.values, train_vals.values X = X.reshape(X.shape[0], 1, X.shape[1]) X_valid, y_valid = test_feats .values, test_vals .values X_valid = X_valid.reshape(X_valid.shape[0], 1, X_valid.shape[1]) 

No he hecho los datos estacionarios para este pronóstico. También intenté tomar la diferencia y hacer el modelo lo más estacionario posible, pero el problema sigue siendo el mismo.

También he intentado diferentes rangos de escalado para el escalador min-max, con la esperanza de que pueda ayudar al modelo. Pero los pronósticos están empeorando.

 Other Things I have tried => Tried other optimizers => Tried mse loss and custom log-mae loss functions => Tried varying batch_size => Tried adding more past timesteps => Tried training with sliding window and TimeSeriesSplit 

Entiendo que el modelo le está replicando el último valor conocido, lo que minimiza la pérdida lo mejor posible.

La validación y la pérdida de entrenamiento siguen siendo lo suficientemente bajas durante todo el proceso de entrenamiento. Esto me hace pensar si necesito una nueva función de pérdida para este propósito.

Es eso necesario.? Si es así, ¿para qué función de pérdida debo ir?

He probado todos los métodos con los que tropecé. No puedo encontrar ningún recurso que apunte a este tipo de problema. ¿Es este el problema de los datos? ¿Es esto porque el problema es muy difícil de aprender por una LSTM?

me pediste ayuda en:

predicción de stock: el modelo GRU predice los mismos valores dados en lugar del precio de stock futuro

Espero no llegar tarde. Lo que puede intentar es que puede desviar la explicación numérica de sus características . Dejame explicar:

Similar a mi respuesta en el tema anterior; el algoritmo de regresión usará el valor de la ventana de tiempo que proporcione como muestra para minimizar el error. Supongamos que está intentando predecir el precio de cierre de BTC en el momento t. Una de sus características consiste en precios de cierre anteriores y está dando una ventana de series de tiempo de las últimas 20 entradas desde t-20 a t-1. Un regresor probablemente aprenderá a elegir el valor de cierre en el paso de tiempo t-1 o t-2 o un valor de cierre en este caso, el engaño. Piensa así: si el precio de cierre fuera $ 6340 en t-1, predecir $ 6340 o algo cercano a t + 1 minimizaría el error al máximo. Pero en realidad el algoritmo no aprendió ningún patrón; simplemente se replica, así que básicamente no hace nada más que cumplir con su deber de optimización.

Piensa de forma análoga a partir de mi ejemplo: al desviar lo explícito, lo que quiero decir es que no hay que dar los precios de cierre directamente, sino escalarlos o no usarlos de manera explícita. No use ninguna función que muestre explícitamente los precios de cierre del algoritmo, no use abierto, alto, bajo, etc. para cada paso de tiempo. Necesitará ser creativo aquí, diseñar las características para deshacerse de las explícitas; puede dar diferencias al cuadrado (el regresor aún puede robar el pasado con diferencias lineales, con experiencia), su relación con el volumen. O bien, puede hacer que las características sean categóricas al digitalizarlas de una manera que tenga sentido utilizarlas. El punto es que no intuyas directamente lo que debería predecir, solo proporciona patrones para que funcione el algoritmo.

Se puede sugerir un enfoque más rápido dependiendo de su tarea. Puede hacer una clasificación de múltiples clases si predice cuánto porcentaje de cambio es suficiente para sus tags, solo tenga cuidado con las situaciones de desequilibrio de clase. Si solo las fluctuaciones de subida / bajada son suficientes para usted, puede ir directamente a la clasificación binaria. Los problemas de replicación o desplazamiento solo se ven en las tareas de regresión , si no filtra datos del entrenamiento al conjunto de pruebas. Si es posible, deshágase de la regresión para las aplicaciones de ventana de series de tiempo.

Si algo se malinterpreta o falta, estaré cerca. Espero poder ayudar. Buena suerte.

Lo más probable es que su LSTM esté aprendiendo a adivinar aproximadamente cuál fue su valor de entrada anterior (modulado un poco). Es por eso que ves un “cambio”.

Así que digamos que sus datos parecen:

 x = [1, 1, 1, 4, 5, 4, 1, 1] 

Y su LSTM aprendió a generar solo la entrada anterior para el paso de tiempo actual. Entonces su salida se vería como:

 y = [?, 1, 1, 1, 4, 5, 4, 1] 

Debido a que su red tiene una maquinaria complicada, no es tan sencillo, pero en principio el “cambio” que ve es causado por este fenómeno.