首页 > 解决方案 > 循环神经网络预测遵循测试集的形状,但向下移动

问题描述

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

编辑:数据来自 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 和一个额外的零):


在此处输入图像描述

编辑:

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

标签: recurrent-neural-network

解决方案


如果您尝试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 值根本无法预测。你不能说更多,明天可能会是同样的价格。

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


推荐阅读