多元时间序列预测之LSTM的实现
本文使用keras库实现基于LSTM的多元时间序列预测问题。所谓多元时间序列预测,是指根据多个变量之间的关系预测他们下一时刻的值。
本文仅搭建LSTM模型进行预测,数据的预处理部分自行完成。
keras简单介绍
keras是一个极简的、高度模块化的神经网络库,可以运行在tensorflow上,具体可看keras中文文档。
具体安装可在网上搜索,非常简单。
多变量LSTM预测模型
1.导入所需的包
from math import sqrt
from numpy import concatenate
from matplotlib import pyplot
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_squared_error
from tensorflow.keras import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dropout
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt
2.写一个滑动取数据的函数(网上找的)
def time_series_to_supervised(data, n_in=1, n_out=1,dropnan=True):
"""
:param data:作为列表或2D NumPy数组的观察序列。需要。
:param n_in:作为输入的滞后观察数(X)。值可以在[1..len(数据)]之间可选。默认为1。
:param n_out:作为输出的观测数量(y)。值可以在[0..len(数据)]之间。可选的。默认为1。
:param dropnan:Boolean是否删除具有NaN值的行。可选的。默认为True。
:return:
"""
n_vars = 1 if type(data) is list else data.shape[1]
df = pd.DataFrame(data)
origNames = df.columns
cols, names = list(), list()
cols.append(df.shift(0))
names += [('%s' % origNames[j]) for j in range(n_vars)]
n_in = max(0, n_in)
for i in range(n_in, 0, -1):
time = '(t-%d)' % i
cols.append(df.shift(i))
names += [('%s%s' % (origNames[j], time)) for j in range(n_vars)]
n_out = max(n_out, 0)
for i in range(1, n_out+1):
time = '(t+%d)' % i
cols.append(df.shift(-i))
names += [('%s%s' % (origNames[j], time)) for j in range(n_vars)]
agg = pd.concat(cols, axis=1)
agg.columns = names
if dropnan:
agg.dropna(inplace=True)
return agg
这个函数,给定输入、输出序列的长度,它可以自动地将时间序列数据转型为适用于监督学习的数据, 它可以将单变量或多变量的时间序列数据帧转化为适用于监督学习的数据帧。
它包含4个参数:
- data: 观测序列。格式是一个 list 或 2维 Numpy Array required
- n_in: 观测数据input(X)的步长,范围[1, len(data)], 默认为1
- n_out: 观测数据output(y)的步长, 范围为[0, len(data)-1], 默认为1
- dropnan: 是否删除存在NaN的行,默认为True
它的返回值只有一个, 即转型后适用于监督学习的 DataFrame
新的DataFrame每一列名字都可被变量编号与时间步长适当的命名,我们就可以用它来进行不同时间步长的时间序列预测了
3.加载数据
这里放一下我的数据:
链接:链接:https://pan.baidu.com/s/13Y57gKqtfpmq7-7T1B73Iw
提取码:6tbb
# 加载数据
path1 = r"C:\data.xlsx"#数据所在路径
#我的数据是excel表,若是csv文件用pandas的read_csv()函数替换即可。
datas1 = pd.DataFrame(pd.read_excel(path1))
#我只取了data表里的第3、23、16、17、18、19、20、21、27列,如果取全部列的话这一行可以去掉
data1 = datas1.iloc[:,np.r_[3,23,16: