LSTM实现时序问题预测(Tensorflow版本)

前言

前面写了一个RNN对股票走势的预测,可以看到循环神经网络在时序问题上面的表现还是非常不错的,本次就用RNN的改进版本LSTM(长短时记忆神经网络)再做一个时间序列问题,看看LSTM的效果怎么样。

数据集可视化

本次数据集采用statsmodels库中的二氧化碳数据集,数据集可以通过导入statsmodels库直接获取,首先导入本次任务可能用到的库:

import tensorflow.compat.v1 as tf
tf.disable_v2_behavior()
import numpy as np
import itertools
from tensorflow import keras
from tensorflow.keras import layers
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
from sklearn.preprocessing import MinMaxScaler
import statsmodels.api as sm
import matplotlib.dates as dates
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import math
from keras.models import Sequential
from keras.layers import Dense, Activation, Dropout, LSTM
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras import optimizers
import time

读入数据,并对数据集进行可视化

#数据读入可视化
data=sm.datasets.co2.load()
index = pd.date_range(start=data.data['date'][0].decode('utf-8'),periods=len(data.data),freq='W-SAT')
data=pd.DataFrame(data.data['co2'], index=index, columns=['co2'])
data = data['co2'].resample('MS').mean()
data = data.fillna(data.bfill())
plt.figure(figsize=(20, 10))
plt.plot(data,color='r')
plt.ylabel('co2')
plt.xlabel('date')
plt.show()

整体数据呈下图趋势:
LSTM实现时序问题预测(Tensorflow版本)_第1张图片

数据预处理

数据预处理方面主要进行归一化处理,其他操作也可以自己进行尝试,数据归一化后就进行训练集和测试集的划分,直接选取train_test_split函数进行划分,训练集占全部数据集的70%,测试集占全部数据集的30%,代码如下:

#数据预处理和训练集,测试集构建
data = data.values
scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(data.reshape(-1, 1))
x=[]
y=[]
time_back=1
for i in range(len(data)-time_back-1):
    x.append(data[i:i+time_back])
    y.append(data[i+time_back])
x=np.array(x) 
y=np.array(y)  
from sklearn.model_selection import train_test_split
trainX, testX, trainY, testY = train_test_split(x, y, test_size=0.3)

LSTM模型构建及训练

模型构建方面还是采取简单构建,中间层数都可以自行添加或者删减,激活函数全部都是采用sigmoid函数,因为数据集比较简单且量小,所以模型差异不会太大。

#LSTM模型构建以及训练
model=tf.keras.models.Sequential([
    tf.keras.layers.LSTM(input_dim=1, units=50, return_sequences=True),
    tf.keras.layers.LSTM(input_dim=50, units=100, return_sequences=True),
    tf.keras.layers.LSTM(input_dim=100, units=200, return_sequences=True),
    tf.keras.layers.LSTM(300, return_sequences=False),
    tf.keras.layers.Dense(units=100),
    tf.keras.layers.Dense(units=1)
])
model.add(Activation('sigmoid'))    #激活函数可以自选
start = time.time()
model.summary()
model.compile(optimizer=keras.optimizers.Adam(0.01),loss=keras.losses.mean_squared_error)
model_information=model.fit(trainX,trainY,epochs=100,verbose=1)	#模型训练

打印模型结构看看:
LSTM实现时序问题预测(Tensorflow版本)_第2张图片
可以看到模型简单,一共也不到一百万参数,训练非常快。

模型训练中损失可视化:

#模型损失可视化
information_loss=model_information.history['loss']  #模型训练损失
def loss(information_loss):
    plt.figure(figsize=(12, 8))
    plt.plot(information_loss)
    plt.title('model loss')
    plt.ylabel('loss')
    plt.xlabel('epoch')
    plt.show()
loss(information_loss)

模型损失如下图:
LSTM实现时序问题预测(Tensorflow版本)_第3张图片
可以看到损失函数收敛,最终也是趋于平稳,稳定在0.001左右。

测试集预测

最后用训练好的模型对测试集进行预测,然后对比预测结果和真实值的对比。

#对测试集进行预测
testPredict = model.predict(testX)#这里预测出的结果也是在0-1之间的,这次就没做反归一化了,做不做效果都一样
#测试集进行可视化
plt.figure(figsize=(15, 5))
plt.plot(range(len(testPredict)), testPredict, label='prediction', lineWidth=1)
plt.plot(range(len(testY)), testY, label='true', lineWidth=1)
plt.ylabel('co2')
plt.xlabel('date')
plt.legend()
plt.title("prediction and true")
plt.show()

预测结果和真实值的可视化对比,可以看到效果还是非常好的,趋势和范围基本一致,大家也可以自己尝试一下。
LSTM实现时序问题预测(Tensorflow版本)_第4张图片
源码也可以通过以下地址获取:https://github.com/CquptDJ/CquptDJ/tree/main

写在最后

上次RNN遇到了一个预测结果滞后问题,这次其实开始也是这样,后来找了一下问题,发现问题出在测试集划分上,上次是直接按时间顺序划分测试集,前面80%是训练集,后面20%作为测试集,这样划分就出现了一个滞后问题(可以看前面那篇RNN文章),但是这次我采用train_test_split函数进行随机划分后就没有出现这种问题了,我也有点懵逼,暂时还没想通是怎么回事,如果有大佬知道欢迎评论!本人才疏学浅,如果有错误或者理解不到位的地方请指正!

你可能感兴趣的:(深度学习,数据挖掘,机器学习,深度学习,神经网络,机器学习,python,时序模型)