基于LSTM的时间序列数据(多步)预测

LSTM原理

LSTM结构

LSTM的原理,这里不做多余描述,具体可以参照这几个博客,介绍的很好。
blog1:Understanding LSTM Networks
blog2:Long Short-Term Memory Units (LSTMs)
blog3:LSTM详解 反向传播公式推导
blog4:LSTM详解

数据集

构造数据集

数据为单变量数据,上图显示的是,如何构造sequence to sequece。有点滑动窗口的思想。
网络博客上面,大多参照这篇文章Time Series Prediction with LSTM Recurrent Neural Networks in Python with Keras.这位博主,有很多时间方面预测的文章,可以去他博客里面学习。这是中文版的Time Series Prediction with LSTM Recurrent Neural Networks in Python with Keras(博客里面有数据集)
在学习上述博客,以及上述博客的中文翻译基础上,对我的时间序列数据进行多步预测。

代码

本案例主要是,我自己做项目练习多步预测使用,具体公司数据集,不能提供。想要做练习,大家可以参照我给的连接,去他们的博客中学习。
这个代码部分可以不用细看。主要有几个地方希望初学者理解。
第一个:如何构造sequence to sequence,请参照上图;
第二个:多步预测的时候,这里面采用的事循环预测的方式。即上次预测的值y,添加到数据集中当做X,然后在预测新的y。如此往复,直到达到预测数据为止。
第三个:注意keras中,输入的维度关系。这篇文章介绍的比较好Keras中的LSTM
第四个:下面代码的测试集被省去了。可以参照上面的博客,一样可以学习。


import pandas as pd
import numpy as np
import matplotlib.pylab as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error

#读取数据
data = pd.read_csv("./data/data_complete.csv")[['sump']]
dataf = data.values[0:-288]
def create_dataset(dataset, timesteps=36,predict_size=6):#构造数据集
    datax=[]#构造x
    datay=[]#构造y
    for each in range(len(dataset)-timesteps - predict_steps):
        x = dataset[each:each+timesteps,0]
        y = dataset[each+timesteps:each+timesteps+predict_steps,0]
        datax.append(x)
        datay.append(y)
    return datax, datay#np.array(datax),np.array(datay)
#构造train and predict
scaler = MinMaxScaler(feature_range=(0,1))
dataf = scaler.fit_transform(dataf)
train = dataf.copy()
timesteps = 72#构造x,为72个数据,表示每次用前72个数据作为一段
predict_steps = 12#构造y,为12个数据,表示用后12个数据作为一段
length = 288#预测多步,预测288个数据,每次预测12个,想想要怎么构造预测才能满足288?
trainx, trainy = create_dataset(train, timesteps, predict_steps)
trainx = np.array(trainx)
trainy = np.array(trainy)

#变换
trainx = np.reshape(trainx,(trainx.shape[0],timesteps,1))#变换shape,以满足keras
#lstm training
model = Sequential()
model.add(LSTM(128,input_shape=(timesteps,1),return_sequences= True))
model.add(Dropout(0.5))
model.add(LSTM(128,return_sequences=True))
#model.add(Dropout(0.3))
model.add(LSTM(64,return_sequences=False))
#model.add(Dropout(0.2))
model.add(Dense(predict_steps))
model.compile(loss="mean_squared_error",optimizer="adam")
model.fit(trainx,trainy, epochs= 50, batch_size=200)
#predict
#因为每次只能预测12个数据,但是我要预测288个数据,所以采用的就是循环预测的思路。每次预测的12个数据,添加到数据集中充当预测x,然后在预测新的12个y,再添加到预测x列表中,如此往复。最终预测出288个点。
predict_xlist = []#添加预测x列表
predict_y = []#添加预测y列表
predict_xlist.extend(dataf[dataf.shape[0]-timesteps:dataf.shape[0],0].tolist())#已经存在的最后timesteps个数据添加进列表,预测新值(比如已经有的数据从1,2,3到288。现在要预测后面的数据,所以将216到288的72个数据添加到列表中,预测新的值即288以后的数据)
while len(predict_y) < length:
    predictx = np.array(predict_xlist[-timesteps:])#从最新的predict_xlist取出timesteps个数据,预测新的predict_steps个数据(因为每次预测的y会添加到predict_xlist列表中,为了预测将来的值,所以每次构造的x要取这个列表中最后的timesteps个数据词啊性)
    predictx = np.reshape(predictx,(1,timesteps,1))#变换格式,适应LSTM模型
    #print("predictx"),print(predictx),print(predictx.shape)
    #预测新值
    lstm_predict = model.predict(predictx)
    #predict_list.append(train_predict)#新值y添加进列表,做x
    #滚动预测
    #print("lstm_predict"),print(lstm_predict[0])
    predict_xlist.extend(lstm_predict[0])#将新预测出来的predict_steps个数据,加入predict_xlist列表,用于下次预测
    # invert
    lstm_predict = scaler.inverse_transform(lstm_predict)
    predict_y.extend(lstm_predict[0])#预测的结果y,每次预测的12个数据,添加进去,直到预测288个为止
    #print("xlist", predict_xlist, len(predict_xlist))
    #print(lstm_predict, len(lstm_predict))
    #print(predict_y, len(predict_y))
#error

y_ture = np.array(data.values[-288:])
train_score = np.sqrt(mean_squared_error(y_ture,predict_y))
print("train score RMSE: %.2f"% train_score)
y_predict = pd.DataFrame(predict_y,columns=["predict"])
y_predict.to_csv("y_predict_LSTM.csv",index=False)
#plot
#plt.plot(y_ture,c="g")
#plt.plot(predict_y, c="r")
#plt.show()

结果

预测结果

预测的效果不好。涉及的构建数据的X和y的长度,以及搭建的网络等等原因。
还在学习中,欢迎指教下我。

参考文献

多步预测
多变量预测
多变量预测2
多层LSTM预测

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容