LSTM时间序列预测,预测结果出现一条直线

LSTM时间序列预测,预测值画出来结果成了一条直线,下面是原数据的大概样子

在anacanda里写的代码,python版本为3.6

以下为代码部分

# 导入库
import numpy
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
import  pandas as pd
import  os
from keras.models import Sequential, load_model
from sklearn.preprocessing import MinMaxScaler
#导入数据文件
df = pd.read_excel("E:/graduation project/clear_data/访问量数据.xlsx")

#变形
dataset = df['y'].values
dataset = dataset.reshape(-1, 1)

#归一化
scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)

#划分训练集和测试集
trainlist = dataset[:-365]
testlist = dataset[-365:]

#自定义划分函数
def create_dataset(dataset, look_back):
#这里的look_back与timestep相同
    dataX, dataY = [], []
    for i in range(len(dataset)-look_back-1):
        a = dataset[i:(i+look_back)]
        dataX.append(a)
        dataY.append(dataset[i + look_back])
    return numpy.array(dataX),numpy.array(dataY)
#训练数据太少 look_back并不能过大
look_back = 1
trainX,trainY  = create_dataset(trainlist,look_back)
testX,testY = create_dataset(testlist,look_back)

trainX = numpy.reshape(trainX, (trainX.shape[0], trainX.shape[1], 1))
testX = numpy.reshape(testX, (testX.shape[0], testX.shape[1] ,1 ))

# create and fit the LSTM network
model = Sequential()
model.add(LSTM(24, input_shape=(None,1)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=100, batch_size=1, verbose=2)
model.save(os.path.join("DATA","Test" + ".h5"))
# make predictions

#model = load_model(os.path.join("DATA","Test" + ".h5"))
trainPredict = model.predict(trainX)
testPredict = model.predict(testX)

#反归一化
trainPredict = scaler.inverse_transform(trainPredict)
trainY = scaler.inverse_transform(trainY)
testPredict = scaler.inverse_transform(testPredict)
testY = scaler.inverse_transform(testY)

以下为结果图

看起来是不是还不错?然后我想干什么事情呢?我把实际数据除以预测数据,就得到预测数据应该调整的比例(预测数据 ✖ 比例 = 实际数据)

得到了这样的一条曲线

然后我按照上边划分的那个训练集和测试集的比例划分了这条曲线,然后用训练集去训练LSTM模型,预测测试集这条曲线的走势。

以下为代码部分

wtrainlist = trainY/trainPredict
wtestlist = testY/testPredict
dataset = numpy.append(wtrainlist,wtestlist)  
dataset = dataset.reshape(-1, 1)
nu = len(trainY/trainPredict)

scaler = MinMaxScaler(feature_range=(0, 1))
dataset = scaler.fit_transform(dataset)

wtrainlist = dataset[:nu]
wtestlist = dataset[nu:]

wtrainX,wtrainY  = create_dataset(wtrainlist,1)
wtestX,wtestY = create_dataset(wtestlist,1)

wtrainX = numpy.reshape(wtrainX, (wtrainX.shape[0], wtrainX.shape[1], 1))
wtestX = numpy.reshape(wtestX, (wtestX.shape[0], wtestX.shape[1] ,1 ))

model2 = Sequential()
model2.add(LSTM(24, input_shape=(None,1)))
model2.add(Dense(1))
model2.compile(loss='mean_squared_error', optimizer='adam')
model2.fit(wtrainX, wtrainY, epochs=100, batch_size=1, verbose=2)
model2.save(os.path.join("DATA","Test" + ".h5"))

model2 = load_model(os.path.join("DATA","Test" + ".h5"))
wtrainPredict = model2.predict(wtrainX)
wtestPredict = model2.predict(wtestX)

#反归一化
wtrainPredict = scaler.inverse_transform(wtrainPredict)
wtrainY = scaler.inverse_transform(wtrainY)
wtestPredict = scaler.inverse_transform(wtestPredict)
wtestY = scaler.inverse_transform(wtestY)

plt.figure(figsize = (20,5))
plt.plot(wtestPredict,color = 'r',label='prediction')
plt.plot(wtestY,color = 'b',label='real')
plt.show()

以下为预测结果

本来红色的线应该跟着蓝线走的,不知道为什么变成了一条直线

同这个问题,不知道怎么解决

请问解决了吗?

你好,不知道你现在是否还需要解答,目前我也遇到了这些问题,然后我发现如果我把训练数据从之前的前50%变成前80%甚至90%,拟合情况会有明显好转,换句话说,需要牺牲预测的提前性换来预测的准确性。

你好,我是有问必答小助手,非常抱歉,本次您提出的有问必答问题,技术专家团超时未为您做出解答

本次提问扣除的有问必答次数,将会以问答VIP体验卡(1次有问必答机会、商城购买实体图书享受95折优惠)的形式为您补发到账户。

​​​​因为有问必答VIP体验卡有效期仅有1天,您在需要使用的时候【私信】联系我,我会为您补发。