LSTM时间序列预测

(本人最初发布于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条数据展示出来
将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笔预测结果
此函数首先利用901至1000这100笔数据得到第1001笔预测结果,然后将1001笔预测结果存入到results中,将902~1001这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,))

在这里插入图片描述

  • 7
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 36
    评论
评论 36
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值