循环神经网络预测遵循测试集的形状但向下移动

Recurrent Neural Network predictions follow shape of test set but shifted down

我想知道是否有人见过这样的事情。我的预测似乎总是遵循数据的实际形式,但最终总是向下移动或向上移动。有时它似乎也是正确的。预先感谢您的帮助。

编辑:数据来自 finance.yahoo.com 的亚马逊股票收盘价。

如果你想看的话,我的代码如下所示。我有一个此处未概述的回调,因为即使不使用回调也会出现结果,尽管回调似乎更频繁地发生。

完整的工作代码:

import numpy as np
import pandas as pd
from sklearn import preprocessing
from keras.preprocessing.sequence import TimeseriesGenerator
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import Bidirectional
from keras.layers import SimpleRNN
from keras.layers import Flatten
import matplotlib.pyplot as plt
from keras.utils import plot_model
from numpy.random import seed

from keras.callbacks import ModelCheckpoint

data = pd.read_csv("D:\AMZN2.csv",header=0,usecols=['Date','Close'],parse_dates=True,index_col='Date')

# Scaled data such that it is centered at 0 with unit variance.
scaler = preprocessing.MinMaxScaler(feature_range=(0,1))
scaledData = scaler.fit_transform(data)

train = scaledData[:5000]
validation = scaledData[5000:5250]
test = scaledData[5250:]

# Generator Creation #
trainGen = TimeseriesGenerator(data=train,targets=train,length=1,
                              sampling_rate=1,stride=1,
                              shuffle=False,reverse=False,
                              batch_size=8)

valGen = TimeseriesGenerator(data=validation,targets=validation,length=1,
                              sampling_rate=1,stride=1,
                              shuffle=False,reverse=False,
                              batch_size=8)
testGen = TimeseriesGenerator(data=test,targets=test,length=1,
                              sampling_rate=1,stride=1,
                              shuffle=False,reverse=False,
                              batch_size=8) #length 1 batch_size 500

# Designing the Model #
AMZN = Sequential()
AMZN.add(LSTM(32,return_sequences=False,input_shape=(1,1)))
AMZN.add(Dense(1))

# Compiling and training the model #
steps_per_epoch = np.ceil(train.shape[0]/128)
#RMSprop
AMZN.compile(loss='mean_absolute_error',optimizer='adam',metrics=['mae','mse'])
history = AMZN.fit_generator(trainGen,validation_data=valGen,#steps_per_epoch = steps_per_epoch,
                   epochs=20,verbose = 1)

# Predicting and undoing the scaling #
predictions = AMZN.predict_generator(testGen)
predictions = scaler.inverse_transform(predictions)
test = scaler.inverse_transform(test)

# Plotting the Prediction and Test #
plt.plot(predictions,'--',label='Predictions')
plt.plot(test,label='Actual')
plt.xlabel("Observation")
plt.ylabel("Price")
plt.title("AMZN Stock Prediction Vs. Actual")
plt.legend()
plt.show()

编辑编辑编辑:


predict = np.zeros(len(test)+1)
predict[0] = AMZN.predict(np.asarray([[train[-1]]]))

for i in range(len(test)):
    predict[i+1] = AMZN.predict(test[i].reshape(1,1,1))
    predict[i] = scaler.inverse_transform(predict[i].reshape(1,1))

这种手动方法的训练结果(急剧下降是因为我使用了 np.zeros 和一个额外的零):


编辑:

根据我 运行 的预测方式,我会说长度是用于预测的输入 space 中变量的数量。这是因为当我指定长度为 3 时,我需要提供 model.predict 函数 3 个值。

如果您尝试用随机数据训练 LSTM,您会看到类似的行为。 此短代码将生成与您使用的股票价格类似形式的随机数据:

data = random(5528)-0.5
data[0]=1456
for i in range(1,len(data)):
    data[i]+=data[i-1]
data.resize((5528,1))

使用您的代码,它将生成下图。 https://i.stack.imgur.com/weXXz.png 如您所见,行为与随机数据非常相似。

您使用了 length=1 ,这意味着预测明天将使用今天的价格。预测将包含比测试少一项。

In [31]: len(test)
Out[31]: 278

In [32]: len(predictions)
Out[32]: 267

所以你首先应该纠正的是绘图:

plt.plot(predictions,'--',label='Predictions')
plt.plot(test[1:],label='Actual')

通过该更改,您可以将明天的价格与明天的预测价格进行比较。

第二个问题是 1 值根本无法预测。 你不能说更多可能明天会是同样的价格。

第三件事不是问题,没关系,网络将学习向上或向下移动。