LSTM时间序列预测
程序员文章站
2024-03-22 13:21:52
...
(本人最初发布于HackMD:HackMD链接,链接内容在*期间所做,所以为繁体字)
1.问题描述
使用任意一种RNN(SimpleRNN,GRU,LSTM),根据提供的1000笔时间序列数据,预测出1001~1500笔数据。
提供的数据集:
A3_train.txt,其中有1000行,每一行为一个float类型的数值,该txt文件部分内容如下:
2.数据预处理
①读取文件,将文件的1000条数据转化为形状是(1000,)的array
# 读取文件,将1000条数据构造成一个形状为(1000,)的array
import os
import numpy as np
from matplotlib import pyplot as plt
data_dir = r"C:\Users\NOTEBOOK\DeepLearningNote\train_data.txt"
f = open(data_dir)
content = f.read()
f.close()
samples = [float(i) for i in content.split("\n")]
samples = np.array(samples)
plt.plot(range(len(samples)),samples)
将1000条数据展示出来
②定义一个用来产生train_data和train_labels的函数
该函数可以产生(900,100)状的array,作为train_data,产生(900,)状的array,作为train_labels
#定义split_sequence函数,返回值X含有n_steps个之前的值,y是下一时刻的值
def split_sequence(sequence, n_steps):
X, y = list(), list()
for i in range(len(sequence)):
end_ix = i + n_steps
if end_ix > len(sequence)-1:
break
seq_x, seq_y = sequence[i:end_ix], sequence[end_ix]
X.append(seq_x)
y.append(seq_y)
return np.array(X), np.array(y)
③通过split_sequence函数,得到所有的data和labels,并将train_data变形为LSTM可处理的形式
data,labels = split_sequence(samples,100)
data = data.reshape((len(data),100,1))
3.建立模型
模型由三层LSTM层和一个Dense层组成
#建立模型
from keras.models import Sequential
from keras.layers import GRU,LSTM,Dropout,Dense
model = Sequential()
model.add(LSTM(20,activation="relu",input_shape=(100,1),return_sequences=True))
model.add(LSTM(30,activation="relu",return_sequences=True))
model.add(LSTM(30,activation="relu"))
model.add(Dense(1))
model.compile(optimizer='adam', loss='mse')
model.summary()
4.训练模型
将1000笔数据中的20%作为验证数据
history = model.fit(data,labels,epochs=20,batch_size=20,validation_split=0.2)
由于初始的权重是随机的,最好的一次训练过程如下
打印其训练过程的loss和val_loss
loss = history.history['loss']
val_loss = history.history['val_loss']
plt.plot(range(20),loss,"bo",label="loss")
plt.plot(range(20),val_loss,"b",label='val_loss')
plt.legend()
plt.show()
5.预测
①定义预测函数
此函数用来得到1001~1500这500笔预测结果
此函数首先利用9011000这100笔数据得到第1001笔预测结果,然后将1001笔预测结果存入到results中,将9021001这100笔数据加入原始数据中,下一轮预测将以此为输入,得到第1002笔预测结果,依次进行下去,直到运行500次,也就是得到第1500笔预测结果
#定义方法,可以预测从1001到1500的结果
def predict1001_1500(samples):
results = []
for i in range(500):
# print(samples[-1].shape)
result = model.predict(samples[-1].reshape(1,100,1))
results.append(result)
sample = np.append(samples[-1][1:],result)
sample = sample.reshape((1,100,1))
# print(sample.shape)
samples = np.concatenate((samples,sample),axis=0)
return results
②得到1001~1500这500笔预测结果
results = predict1001_1500(data)
将这1500笔预测结果打印出来
plt.plot(range(1000),samples)
plt.plot(range(1000,1500),np.array(results).reshape(500,))
单独打印500笔预测结果
plt.plot(range(500),np.array(results).reshape(500,))
推荐阅读
-
LSTM时间序列预测
-
以秒为单位生成唯一的时间序列号 博客分类: java 时间序列号
-
DL之LSTM:基于tensorflow框架利用LSTM算法对气温数据集训练并预测
-
Pandas时间序列:频率和日期偏移量
-
建模随手记3(1)---时间序列分析
-
2020-11-23 数据科学库(6) pandas时间序列,911、pm2.5数据处理
-
利用时间序列模型进行股价趋势分析——tushare获取股价信息
-
springmvc fastjson 反序列化时间格式化方法(推荐)
-
springmvc fastjson 反序列化时间格式化方法(推荐)
-
java如何利用FastJSON、Gson、Jackson三种Json格式工具自定义时间序列化