使用LSTM网络做预报(Forecast)

使用LSTM网络做预报(Forecast)

在一次小小的比赛中需要做趋势预测,当时找了很多种方法,最后也对LSTM的使用做出一定的研究,现在大多数能找到的都是Predict,对于Forecast的做法虽然找到了原理,但由于各种原因自己未能很好写出。最后是完成了,这里也做一个小小的记录。

LSTM

完全不想解释,因为只是调包侠,原理还不懂,调参都是手动调的,很离谱。

代码

导入基础模块,preprocessing用作数据归一化预处理

# 导入模块
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.models import Sequential, load_model
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import MinMaxScaler

下面对疫情数据进行读取,疫情数据分为三列,分别为Date、Confirmed、New,因为只做一维数据,所以先drop掉Date和New,并且将剩下的Confirmed列用values的方式读取出来。

# 读取数据
dataframe = pd.read_csv('./datalab/62612/中国疫情.csv')
dataframe = dataframe.drop(columns=['Date'])
dataframe = dataframe.drop(columns=['New'])
dataset = dataframe.values

为了做归一化,将int转化为float,随后进行归一化处理

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

分割

#分割训练集与测试集
train_size = int(len(dataset)*0.80)
test_size = len(dataset)-train_size
train,test = dataset[0:train_size,:],dataset[train_size:,:]

下面就是Forecast的核心。因为LSTM适用于给出下一刻数据,那么我们就采取时间滑窗的方式,将预测出的下一刻数据加入到数据集中,在进行下一刻预测。其中,create_dataset是LSTM建立数据集的核心,而create_predict是建立滑窗。
look_back也是timesteps,它代表着LSTM的映射关系,例如1就代表着1个X预测1个Y,3就代表3个X预测1个Y,在数据量小时,可以适当调整

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

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

trainX,trainY = create_dataset(train,look_back)
testX,testY = create_dataset(test,look_back)

对训练集与测试集进行转换,因为keras需要。

#转换数据
trainX = np.reshape(trainX,(trainX.shape[0],1,trainX.shape[1]))
testX = np.reshape(testX,(testX.shape[0],1,testX.shape[1]))

初始化LSTM模型,注意input_shape,它决定了投进模型的数据维度,所以设置为look_back与前面设置的映射关系相符合。

model = Sequential()
model.add(LSTM(4, input_shape=(None,look_back)))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
model.fit(trainX, trainY, epochs=100, batch_size=8, verbose=False)

Predict

#预测
trainPredict = model.predict(trainX)
testPredict  = model.predict(testX)

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

Forecast的又一个核心,运用了栈的原理,将Predict的值压入dataset中。
此处尤其注意,这几个操作所需的数据格式不一样,也是我试过很多次试出来的。append无法对array变量作用(或者是ndarray,我也忘了),所以要先将其变成List,同时,predict出的值自带中括号(我也不知道是什么数据类型),所以需要将其扁平化(一顿瞎编,我也不懂)(这一部分尤其重要,很多时候就停滞在此了)

predict_series = []
for i in range(30):
    p = dataset[-(look_back + 1):]
    p1 = create_predict(p, look_back)
    p2 = np.reshape(p1, (p1.shape[0], 1, p1.shape[1]))
    predict = model.predict(p2)
    dataset = np.vstack((dataset,predict))
    predict = scaler.inverse_transform(predict)
    
    predict=predict.flatten()
    predict = predict.tolist()   
    predict_series.append(predict)
  
print(predict_series)

此部分为画图做准备,重新读取数据,并且设定出forecast的范围,因为往后预测了30步,所以此处设置为+1~+31

dataframe = pd.read_csv('./datalab/62612/中国疫情.csv')
future=np.arange(dataframe['Date'].shape[0]+1,dataframe['Date'].shape[0]+31,1)
plt.figure(figsize=(12, 8))

plt.plot(trainPredict)
plt.plot(testPredict)
plt.plot(future,predict_series)

dataframe = pd.read_csv('./datalab/62612/中国疫情.csv')
dataframe = dataframe.drop(columns=['Date'])
dataframe = dataframe.drop(columns=['New'])
dataset = dataframe.values
plt.plot(dataset)

plt.xlabel('天数')
plt.ylabel('感染人群数目')

plt.legend(['trainPredict','testPredict','forecast','data'], loc='best')
plt.show

Finished!
此文章自己观看,单纯当胡编就行了。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值