Keras LSTM RNN预测 - 向后移动拟合预测

时间:2016-08-25 07:44:22

标签: time-series deep-learning forecasting keras lstm

我正在尝试使用Keras的LSTM Recurrent Neural Net来预测未来的购买。我的输入变量是前5天购买的时间窗口,以及我编码为虚拟变量A, B, ...,I的分类变量。我的输入数据如下所示:

>>> dataframe.head()
          day      price  A  B  C  D  E  F  G  H  I  TS_bigHolidays
0  2015-06-16   7.031160  1  0  0  0  0  0  0  0  0               0
1  2015-06-17  10.732429  1  0  0  0  0  0  0  0  0               0
2  2015-06-18  21.312692  1  0  0  0  0  0  0  0  0               0

我的问题是我的预测/拟合值(训练和测试数据)似乎向前移动。这是一个情节: enter image description here

我的问题是我应该更改LSTM Keras中的哪个参数来更正此问题?或者我是否需要更改输入数据中的任何内容?

这是我的代码:

    import numpy as np
    import os
    import matplotlib.pyplot as plt
    import pandas
    import math
    import time
    import csv
    from keras.models import Sequential
    from keras.layers.core import Dense, Activation, Dropout
    from keras.layers.recurrent import LSTM
    from sklearn.preprocessing import MinMaxScaler
    np.random.seed(1234)

    exo_feature = ["A","B","C","D","E","F","G","H","I", "TS_bigHolidays"]

    look_back = 5 #this is number of days we are looking back for sliding window of time series
    forecast_period_length = 40


    # load the dataset
    dataframe = pandas.read_csv('processedDataframeGameSphere.csv', header = 0, engine='python', skipfooter=6)



    dataframe["price"] = dataframe['price'].astype('float32')
    scaler = MinMaxScaler(feature_range=(0, 100))
    dataframe["price"] = scaler.fit_transform(dataframe['price'])

 # this function is used to make sliding window for time series data
    def create_dataframe(dataframe, look_back=1):
        dataX, dataY = [], []
        for i in range(dataframe.shape[0]-look_back-1):
            price_lookback = dataframe['price'][i: (i + look_back)] #i+look_back is exclusive here
            exog_feature = dataframe[exo_feature].ix[i + look_back - 1] #Y is i+ look_back ,that's why
            row_i = price_lookback.append(exog_feature)
            dataX.append(row_i)
            dataY.append(dataframe["price"][i + look_back])
        return np.array(dataX), np.array(dataY)




    window_dataframe, Y  = create_dataframe(dataframe, look_back)


    # split into train and test sets
    train_size = int(dataframe.shape[0] - forecast_period_length) #28 is the number of days we want to forecast , 4 weeks
    test_size = dataframe.shape[0] - train_size
    test_size_start_point_with_lookback = train_size - look_back

    trainX, trainY = window_dataframe[0:train_size,:], Y[0:train_size]

    print(trainX.shape)
    print(trainY.shape)

    #below changed datawindowY indexing, since it's just array.
    testX, testY = window_dataframe[train_size:dataframe.shape[0],:], Y[train_size:dataframe.shape[0]]

    # reshape input to be [samples, time steps, features]
    trainX = np.reshape(trainX, (trainX.shape[0], 1, trainX.shape[1]))
    testX = np.reshape(testX, (testX.shape[0], 1, testX.shape[1]))
    print(trainX.shape)
    print(testX.shape)

    # create and fit the LSTM network
    dimension_input = testX.shape[2]
    model = Sequential()
    layers = [dimension_input, 50, 100, 1]
    epochs = 100
    model.add(LSTM(
                input_dim=layers[0],
                output_dim=layers[1],
                return_sequences=True))
    model.add(Dropout(0.2))

    model.add(LSTM(
                layers[2],
                return_sequences=False))
    model.add(Dropout(0.2))

    model.add(Dense(
                output_dim=layers[3]))
    model.add(Activation("linear"))
    start = time.time()
    model.compile(loss="mse", optimizer="rmsprop")
    print "Compilation Time : ", time.time() - start

    model.fit(
                trainX, trainY,
                batch_size= 10, nb_epoch=epochs, validation_split=0.05,verbose =2)

    # Estimate model performance
    trainScore = model.evaluate(trainX, trainY, verbose=0)
    trainScore = math.sqrt(trainScore)
    trainScore = scaler.inverse_transform(np.array([[trainScore]]))
    print('Train Score: %.2f RMSE' % (trainScore))
    testScore = model.evaluate(testX, testY, verbose=0)
    testScore = math.sqrt(testScore)
    testScore = scaler.inverse_transform(np.array([[testScore]]))
    print('Test Score: %.2f RMSE' % (testScore))
    # generate predictions for training
    trainPredict = model.predict(trainX)
    testPredict = model.predict(testX)
    # shift train predictions for plotting
    np_price = np.array(dataframe["price"])
    print(np_price.shape)
    np_price = np_price.reshape(np_price.shape[0],1)

    trainPredictPlot = np.empty_like(np_price)
    trainPredictPlot[:, :] = np.nan
    trainPredictPlot[look_back:len(trainPredict)+look_back, :] = trainPredict

    testPredictPlot = np.empty_like(np_price)
    testPredictPlot[:, :] = np.nan
    testPredictPlot[len(trainPredict)+look_back+1:dataframe.shape[0], :] = testPredict 


    # plot baseline and predictions
    plt.plot(dataframe["price"])
    plt.plot(trainPredictPlot)
    plt.plot(testPredictPlot)
    plt.show()

1 个答案:

答案 0 :(得分:1)

这不是LSTM的问题,如果你只使用简单的前馈网络,效果将是相同的。 问题是网络倾向于模仿昨天的价值,而不是你期望的“预测”。 (这是减少MSE损失的好策略)

您需要更多“关注”以避免此问题,这不是一个简单的问题。