python - example - lstm trading
¿Cómo trabajar con múltiples entradas para LSTM en Keras? (3)
Cambio
a = dataset[i:(i + look_back), 0]
A
a = dataset[i:(i + look_back), :]
Si quieres las 3 características en tus datos de entrenamiento.
Entonces use
model.add(LSTM(4, input_shape=(look_back,3)))
Para especificar que tiene pasos de tiempo look_back
en su secuencia, cada uno con 3 funciones.
Debería funcionar
EDITAR:
De hecho, la función de inverse_transform()
: inverse_transform()
toma una entrada que tiene la misma forma que el objeto que ajustó. Así que necesitas hacer algo como esto:
# Get something which has as many features as dataset
trainPredict_extended = np.zeros((len(trainPredict),3))
# Put the predictions there
trainPredict_extended[:,2] = trainPredict
# Inverse transform it and select the 3rd column.
trainPredict = scaler.inverse_transform(trainPredict_extended)[:,2]
Supongo que tendrá otros problemas como este a continuación en su código, pero nada que no pueda solucionar :) la parte de ML está solucionada y usted sabe de dónde proviene el error. Solo revisa las formas de tus objetos y trata de hacerlos coincidir.
Estoy tratando de predecir el uso de agua de una población.
Tengo 1 entrada principal:
- Volumen de agua
y 2 entradas secundarias:
- Temperatura
- Lluvia
En teoría tienen una relación con el suministro de agua.
Hay que decir que los datos de cada lluvia y temperatura corresponden al volumen de agua. Así que este es un problema de series de tiempo.
El problema es que no sé cómo usar 3 entradas de un solo archivo .csv, con 3 columnas, cada una para cada entrada, ya que se crea el siguiente código. Cuando solo tengo una entrada (por ejemplo, volumen de agua), la red funciona más o menos bien con este código, pero no cuando tengo más de una. (Entonces, si ejecuta este código con el archivo csv a continuación, mostrará un error de dimensión).
Leyendo algunas respuestas de:
- Predicción de series de tiempo con redes neuronales recurrentes LSTM en Python con Keras
- Estudio de caso de pronóstico de series temporales con Python: uso anual del agua en Baltimore
Parece ser que muchas personas tienen el mismo problema.
El código:
EDITAR: Código ha sido actualizado
import numpy
import matplotlib.pyplot as plt
import pandas
import math
from keras.models import Sequential
from keras.layers import Dense, LSTM, Dropout
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
# convert an array of values into a dataset matrix
def create_dataset(dataset, look_back=1):
dataX, dataY = [], []
for i in range(len(dataset) - look_back - 1):
a = dataset[i:(i + look_back), 0]
dataX.append(a)
dataY.append(dataset[i + look_back, 2])
return numpy.array(dataX), numpy.array(dataY)
# fix random seed for reproducibility
numpy.random.seed(7)
# load the dataset
dataframe = pandas.read_csv(''datos.csv'', engine=''python'')
dataset = dataframe.values
# normalize the dataset
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)
# split into train and test sets
train_size = int(len(dataset) * 0.67)
test_size = len(dataset) - train_size
train, test = dataset[0:train_size, :], dataset[train_size:len(dataset), :]
# reshape into X=t and Y=t+1
look_back = 3
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
# reshape input to be [samples, time steps, features]
trainX = numpy.reshape(trainX, (trainX.shape[0], look_back, 3))
testX = numpy.reshape(testX, (testX.shape[0],look_back, 3))
# create and fit the LSTM network
model = Sequential()
model.add(LSTM(4, input_dim=look_back))
model.add(Dense(1))
model.compile(loss=''mean_squared_error'', optimizer=''adam'')
history= model.fit(trainX, trainY,validation_split=0.33, nb_epoch=200, batch_size=32)
# Plot training
plt.plot(history.history[''loss''])
plt.plot(history.history[''val_loss''])
plt.title(''model loss'')
plt.ylabel(''pérdida'')
plt.xlabel(''época'')
plt.legend([''entrenamiento'', ''validación''], loc=''upper right'')
plt.show()
# make predictions
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)
# Get something which has as many features as dataset
trainPredict_extended = numpy.zeros((len(trainPredict),3))
# Put the predictions there
trainPredict_extended[:,2] = trainPredict[:,0]
# Inverse transform it and select the 3rd column.
trainPredict = scaler.inverse_transform(trainPredict_extended) [:,2]
print(trainPredict)
# Get something which has as many features as dataset
testPredict_extended = numpy.zeros((len(testPredict),3))
# Put the predictions there
testPredict_extended[:,2] = testPredict[:,0]
# Inverse transform it and select the 3rd column.
testPredict = scaler.inverse_transform(testPredict_extended)[:,2]
trainY_extended = numpy.zeros((len(trainY),3))
trainY_extended[:,2]=trainY
trainY=scaler.inverse_transform(trainY_extended)[:,2]
testY_extended = numpy.zeros((len(testY),3))
testY_extended[:,2]=testY
testY=scaler.inverse_transform(testY_extended)[:,2]
# calculate root mean squared error
trainScore = math.sqrt(mean_squared_error(trainY, trainPredict))
print(''Train Score: %.2f RMSE'' % (trainScore))
testScore = math.sqrt(mean_squared_error(testY, testPredict))
print(''Test Score: %.2f RMSE'' % (testScore))
# shift train predictions for plotting
trainPredictPlot = numpy.empty_like(dataset)
trainPredictPlot[:, :] = numpy.nan
trainPredictPlot[look_back:len(trainPredict)+look_back, 2] = trainPredict
# shift test predictions for plotting
testPredictPlot = numpy.empty_like(dataset)
testPredictPlot[:, :] = numpy.nan
testPredictPlot[len(trainPredict)+(look_back*2)+1:len(dataset)-1, 2] = testPredict
#plot
serie,=plt.plot(scaler.inverse_transform(dataset)[:,2])
prediccion_entrenamiento,=plt.plot(trainPredictPlot[:,2],linestyle=''--'')
prediccion_test,=plt.plot(testPredictPlot[:,2],linestyle=''--'')
plt.title(''Consumo de agua'')
plt.ylabel(''cosumo (m3)'')
plt.xlabel(''dia'')
plt.legend([serie,prediccion_entrenamiento,prediccion_test],[''serie'',''entrenamiento'',''test''], loc=''upper right'')
Este es el archivo csv que he creado, si ayuda.
Después de cambiar el código, arreglé todos los errores, pero no estoy muy seguro de los resultados. Este es un zoom en la gráfica de predicción:
lo que demuestra que hay un "desplazamiento" en los valores predichos y en los reales. Cuando hay un máximo en la serie de tiempo real, hay un mínimo en el pronóstico para el mismo tiempo, pero parece que corresponde al paso de tiempo anterior.
El desplazamiento podría deberse al retraso en la predicción de máximos / mínimos dada la aleatoriedad en los datos.
Puede cambiar lo que está optimizando, para obtener mejores resultados. Por ejemplo, intente predecir 0,1 binario si habrá un ''aumento'' para el día siguiente. Luego alimente la probabilidad de un ''aumento'' como una característica para predecir el uso en sí mismo.