预测的测试用例数小于LSTM中的实际测试数据

时间:2018-04-16 15:27:36

标签: python keras time-series lstm

我一直在尝试使用 LSTM Keras根据时间序列数据预测订单数量。

我将样本数据与训练集分开包含282条记录,而测试集包含82条记录。我正在使用回顾30 的窗口来预测测试数据的预测。

但由于某些原因,预测数据集仅包含40个记录,而不是预期的测试数据中的71个记录。它背后的原因是什么?是导致问题的查找窗口?我觉得回头看窗户造成了这个问题。但我该如何纠正呢?

保持如此高的回顾窗口非常重要

def create_LSTM(trainX,testX,trainY,testY,look_back):
    model = Sequential()
    model.add(LSTM(6, input_shape=(1, look_back),activation= 'relu'))
    model.add(Dense(1))
    model.compile(loss='mean_squared_error', optimizer='RMSProp')
    model.fit(trainX, trainY, epochs=300, batch_size=4, verbose=1)
    trainpredict = model.predict(trainX,batch_size=4)
    testpredict  = model.predict(testX,batch_size=4) 
    testpredict = np.array(testpredict).reshape(len(testpredict),1)      
    print(testpredict) 
    print(len(testpredict))
    return trainpredict,testpredict

我正在使用以下函数为LSTM创建导致实际问题的数据。我怎么能纠正它?

def create_dataset(dataset, look_back=1):
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
    #for i in range(len(dataset)-look_back):
        a = dataset[i:(i+look_back), 0]
        dataX.append(a)
        dataY.append(dataset[i + look_back, 0])
    return np.array(dataX), np.array(dataY)

1 个答案:

答案 0 :(得分:1)

create_dataset

的问题

当你得到ndarray的一个元素时,你会失去与该元素相关的等级。这是因为如果您对该单个元素感兴趣,那么您不需要保留维1

x = np.random.randn(4, 4)
print(x, x.shape)
array([[ 1.37938213, -0.10407424, -0.356567  , -1.5032779 ],
   [-0.53166922,  0.98204605, -0.62052479,  0.99265612],
   [ 0.23046477, -0.17742399,  0.38283412,  0.24104468],
   [-0.78093724,  1.06833765, -1.22112772, -0.78429717]])
(4, 4)

print(x[0:3, 0], x[0:3, 0].shape)
array([ 1.37938213, -0.53166922,  0.23046477])
(3,)

因此,当您编写a = dataset[i:(i + look_back), 0]时,您正在获取形状(samples, features)的数据集,并获得一块形状(look_back,)。将所有内容添加到dataX后,它将变为形状(samples, look_back) = (len(dataset) - look_back - 1, look_back)的ndarray。但是,LSTM期望形状为(samples, look_back, features),在您的情况下为(samples, look_back, 1)

如果您将其更改为a = dataset[i:(i + look_back)],那么事情就会开始奏效。但是,更好的解决方案是使用TimeseriesGenerator

from keras.preprocessing.sequence import TimeseriesGenerator

batch_size = 4
look_back = 1
features = 1

d = np.random.randn(364, features)
train = TimeseriesGenerator(d, d,
                            length=look_back,
                            batch_size=batch_size,
                            end_index=282)
test = TimeseriesGenerator(d, d,
                           length=look_back,
                           batch_size=batch_size,
                           start_index=282)

model = Sequential()
model.add(LSTM(6, input_shape=[look_back, features], activation='relu'))
model.add(Dense(1))
model.compile(loss='mse', optimizer='rmsprop')
model.fit_generator(train, epochs=1, verbose=1)
p_train = model.predict_generator(train)
p_test = model.predict_generator(test)

关于其他部分的进一步评论

  1. model.add(LSTM(6, input_shape=(1, look_back),activation= 'relu')) - 输入形状应符合(length, features)。在这种情况下,length == features,事情就会成功。如果您想要更大的input_shape=(look_back, 1),则需要将此代码更新为look_back

  2. testpredict = np.array(testpredict).reshape(len(testpredict), 1) - 这是不必要的。如果您有一个输出,则Model#predict已输出ndarray,其形状已为(samples, output_units) = (len(testX), 1)

  3. LSTM(activation='relu')在处理非常大的序列时通常会导致不稳定。将它留在tanh

  4. 通常是个好主意