【数据分析】利用机器学习算法进行预测分析(六):长短时记忆网络(LSTM)(2021-01-22)

时间序列预测中的机器学习方法(六):长短时记忆网络(LSTM)

本文是“时间序列预测中的机器学习方法”系列文章的第六篇,如果您有兴趣,可以先阅读前面的文章:
【数据分析】利用机器学习算法进行预测分析(一):移动平均(Moving Average)
【数据分析】利用机器学习算法进行预测分析(二):线性回归(Linear Regression)
【数据分析】利用机器学习算法进行预测分析(三):最近邻(K-Nearest Neighbours)
【数据分析】利用机器学习算法进行预测分析(四):自回归差分移动平均模型(AutoARIMA)
【数据分析】利用机器学习算法进行预测分析(五):Prophet

1.LSTM 简介

长短期记忆(Long Short-Term Memory,LSTM)是一种在深度学习领域中使用的人工循环神经网络(RNN)架构。与标准前馈神经网络不同,LSTM具有反馈连接。它不仅可以处理单个数据点(例如图像),而且可以处理整个数据序列(例如语音或视频)。

LSTM网络非常适合基于时间序列数据进行分类、处理和预测,因为在时间序列中的重要事件之间可能存在未知持续时间的滞后。开发LSTM是为了处理在训练传统RNN时可能遇到的爆炸和消失的梯度问题。对于间隙长度的相对不敏感性是LSTM相较于RNN,隐马尔可夫模型和其他序列学习方法在许多应用中的优势。

2.“股价预测”实例

数据集和前面提到的文章相同,目的是为了比较不同算法对同一数据集的预测效果。数据集和代码放在了我的GitHub上,需要的朋友可以自行下载。

导入包,并读入数据。请确保正确安装了sklearn、keras包。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import Dense, Dropout, LSTM
df = pd.read_csv('NSE-TATAGLOBAL11.csv')

设置索引。为了不破坏原始数据,重新构建一个new_data。

# setting the index as date
df['Date'] = pd.to_datetime(df.Date,format='%Y-%m-%d')
df.index = df['Date']

#creating dataframe
data = df.sort_index(ascending=True, axis=0)
new_data = pd.DataFrame(index=range(0,len(df)),columns=['Date', 'Close'])
for i in range(0,len(data)):
    new_data['Date'][i] = data['Date'][i]
    new_data['Close'][i] = data['Close'][i]

new_data.index = new_data.Date
new_data.drop('Date', axis=1, inplace=True)

看一下new_data的格式。

new_data

在这里插入图片描述

#creating train and test sets
dataset = new_data.values
dataset

在这里插入图片描述
将数据划分为训练集和测试集。

train = dataset[0:987,:]
valid = dataset[987:,:]

对数据集进行归一化。

#converting dataset into x_train and y_train
scaler = MinMaxScaler(feature_range=(0, 1))
scaled_data = scaler.fit_transform(dataset)
scaled_data

在这里插入图片描述
我们训练模型的方法是,使用每个数前面的60个值来进行训练。

x_train, y_train = [], []
for i in range(60,len(train)):
    x_train.append(scaled_data[i-60:i,0])
    y_train.append(scaled_data[i,0])
    
x_train, y_train = np.array(x_train), np.array(y_train)
x_train.shape

在这里插入图片描述

y_train.shape

在这里插入图片描述

x_train = np.reshape(x_train, (x_train.shape[0],x_train.shape[1],1))

构建LSTM网络。Sequential表示顺序模型,核心操作是向其中添加layer(图层),除了LSTM,还可以添加卷积层Conv2D,最大池化层MaxPooling,展平层Flatten等。

# create and fit the LSTM network
model = Sequential() # 顺序模型,核心操作是添加layer(图层)
model.add(LSTM(units=50, return_sequences=True, input_shape=(x_train.shape[1],1)))
model.add(LSTM(units=50))
model.add(Dense(1)) #全连接层

model.compile(loss='mean_squared_error', optimizer='adam') #选择优化器,并指定损失函数
model.fit(x_train, y_train, epochs=1, batch_size=1, verbose=2)

在这里插入图片描述
我们将借助每个数据前面的60个数来预测这个数。一共预测248个数。

#predicting 248 values, using past 60 from the train data
inputs = new_data[len(new_data) - len(valid) - 60:].values # 1235 - 927 - 60 = 308
inputs = inputs.reshape(-1,1)
inputs  = scaler.transform(inputs)
inputs.shape

在这里插入图片描述
X_test代表的是预测集在模型上的输入。

X_test = []
for i in range(60,inputs.shape[0]):
    X_test.append(inputs[i-60:i,0])
X_test = np.array(X_test)

X_test = np.reshape(X_test, (X_test.shape[0],X_test.shape[1],1))
X_test.shape

在这里插入图片描述
开始用模型预测,并将标准化后的数据转化为原始数据。

closing_price = model.predict(X_test)
closing_price = scaler.inverse_transform(closing_price)

看一下这次的RMSE值,比之前的集中预测方法得出的值要小很多,说明误差比较小。

rmse = np.sqrt(np.mean(np.power((valid - closing_price),2)))
rmse

在这里插入图片描述
通过绘图看一下预测情况。

#for plotting
train = new_data[:987]
valid = new_data[987:]
valid['Predictions'] = closing_price

plt.figure(figsize=(16,8))
plt.plot(train['Close'])
plt.plot(valid[['Close','Predictions']])
plt.show

在这里插入图片描述
可以看到LSTM在这个股市收盘价数据集上的预测比较准确。当然,我们也可以针对各种参数对LSTM模型进行调整,例如更改LSTM层数,增加训练代数等。

通过这几次的实验结果可以看到,在对这支股票的预测上,移动平均算法、线性回归算法、Arima算法等都没有显示出很好的预测效果,但LSTM算法的预测结果比较符合我们的预期值。当然,这并不意味着LSTM算法是最佳的时间序列预测算法。对于不同的问题,还需要具体分析。比如一个超市想预测不同商品的未来销量,肯定找不到一个一劳永逸的算法使其满足所有的品类。一个比较好的解决办法,对于每个品类我们用不同的算法预测一遍,找到最符合该品类的预测曲线。

即使有机器学习算法的支持,大部分情况下,我们也很难做到精准预测。对股市的预测是非常困难,不确定的因素太多。并且随着时间序列的推移,对于某种商品货物的销量预测,即使找出了暂时最佳的预测算法,也不代表着这种预测算法在未来可用。时间转折点会出现在什么地方,这也是需要考虑的问题。

写在后面:《Stock Prices Prediction Using Machine Learning and Deep Learning Techniques》这篇文章对我学习如何基于时间序列使用机器学习方法来进行预测分析帮助很大。这几篇博客相当于是我的学习笔记,以写促学。

猜你喜欢

转载自blog.csdn.net/be_racle/article/details/112999853