工夫序列数据,顾名思义,是一种随着工夫扭转的数据。例如,24 小时气温数据,一个月得分产品价格数据,某一公司股票价格年度数据。高级深度学习模型,比方长短期记忆网络(LSTM),可能捕捉到工夫序列数据中的变动模式,进而可能预测数据的将来趋势。在这篇文章中,你将会看到如何利用 LSTM 算法来对工夫序列数据进行预测。
在我早些时候的文章中,我展现了如何使用 Keras 库并利用 LSTM 进行工夫序列剖析,以预测将来的股票价格。将应用 PyTorch 库,它是最罕用的深度学习的 Python 库之一。
在你持续之前,假设你对 Python 编程语言有中级程度的熟练度,并且你曾经装置了 PyTorch 库。此外,对根本的机器学习概念和深度学习概念的理解也会有所帮忙。如果你还没有装置 PyTorch,你能够通过以下 pip 命令来装置。
$ pip install pytorch
复制代码
数据集和问题定义
咱们将应用 Seaborn 库的内建数据集。首先,让咱们导入须要的库,而后倒入数据集:
import torch
import torch.nn as nn
import seaborn as sns
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
复制代码
让咱们打印一下 Seaborn 的所有内建数据库:
sns.get_dataset_names()
输入:
[‘anscombe’,
‘attention’,
‘brain_networks’,
‘car_crashes’,
‘diamonds’,
‘dots’,
‘exercise’,
‘flights’,
‘fmri’,
‘gammas’,
‘iris’,
‘mpg’,
‘planets’,
‘tips’,
‘titanic’]
复制代码
因为家喻户晓的起因,大家能够在 Github 上先下载整个数据包。
咱们将应用 flights 数据集。如果没有网络问题能够用如下代码导入:
flight_data = sns.load_dataset(“flights”)
flight_data.head()
复制代码
数据集有 3 列:年,月和乘客数量。乘客数量一列形容了单月内航班乘客总数。数据集的形态:
flight_data.shape
output:
(144,3)
复制代码
能够看到,一共有 144 行和 3 列数据,即数据集蕴含 12 年的乘客记录。
咱们的工作是利用前 132 个月的数据预测最初 12 个月乘客数。也就是说前 132 个月的数据用作训练,最初 12 个月的数据用作验证以评估模型。
让咱们来绘制每个月乘客出行的频率。上面的脚本减少了默认的绘图大小。
fig_size = plt.rcParams[“figure.figsize”]
fig_size[0] = 15
fig_size[1] = 5
plt.rcParams[“figure.figsize”] = fig_size
复制代码
而接下来的这个脚本绘制了乘客数量的每月频率。
plt.title(‘Month vs Passenger’)
plt.ylabel(‘Total Passengers’)
plt.xlabel(‘Months’)
plt.grid(True)
plt.autoscale(axis=’x’,tight=True)
plt.plot(flight_data[‘passengers’])
复制代码
如图所示,多年来,乘飞机旅行的均匀人数减少了。一年内旅行的乘客数量是稳定的,这是有情理的,因为在冬季或夏季休假期间,旅行的乘客数量比一年中的其余工夫减少。
数据处理
数据集中列的类型是 object,如上面的代码所示:
flight_data.columns
复制代码
输入:
Index([‘year’, ‘month’, ‘passengers’], dtype=’object’)
复制代码
数据处理的第一步是将乘客数量一列的数据类型转换为 float
all_data = flight_data[‘passengers’].values.astype(float)
复制代码
当初,如果你打印 all_data numpy 数组,你应该看到以下 float 类型的值。
[112. 118. 132. 129. 121. 135. 148. 148. 136. 119. 104. 118. 115. 126.
-
-
-
-
-
-
-
-
-
-
-
-
- 163.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 218.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 272.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 229.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 278.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 301.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 348.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 472.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 606.
-
-
-
-
-
-
-
-
-
-
-
-
-
- 432.]
-
复制代码
接下来,咱们将把咱们的数据集分为训练集和测试集。LSTM 算法将在训练集上进行训练。而后,该模型将被用来对测试集进行预测。预测后果将与测试集的理论值进行比拟,以评估训练模型的性能。
前 132 条记录将被用来训练模型,最初 12 条记录将被用作测试集。上面的脚本将数据分为训练集和测试集。
test_data_size = 12
train_data = all_data[:-test_data_size]
test_data = all_data[-test_data_size:]
复制代码
咱们的数据集目前还没有被规范化(normalization)。最后几年的乘客总数与起初几年的乘客总数相比要少得多。对于工夫序列预测来说,将数据标准化是十分重要的。咱们将对数据集进行最小 / 最大缩放,使数据在肯定的最小值和最大值范畴内正常化。咱们将应用 sklearn.preprocessing 模块中的 MinMaxScaler 类来扩大咱们的数据。对于最小 / 最大缩放器实现的进一步细节,请拜访这个链接。
上面的代码应用最小 / 最大标度器对咱们的数据进行标准化解决,最小值和最大值别离为 - 1 和 1。
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(-1, 1))
train_data_normalized = scaler.fit_transform(train_data .reshape(-1, 1))
复制代码
这里须要提到的是,数据规范化只实用于训练数据,而不是测试数据。如果在测试数据上利用归一化,有可能会有一些信息从训练集泄露到测试集。
下一步是将咱们的数据集转换成张量,因为 PyTorch 模型是应用张量进行训练的。为了将数据集转换为张量,咱们能够简略地将咱们的数据集传递给 FloatTensor 对象的构造函数,如下所示。
train_data_normalized = torch.FloatTensor(train_data_normalized).view(-1)
复制代码
最初的预处理步骤是将咱们的训练数据转换成序列和相应的标签。
你能够应用任何序列长度,这取决于畛域常识。然而,在咱们的数据集中,应用 12 的序列长度是很不便的,因为咱们有月度数据,一年有 12 个月。如果咱们有每日数据,更好的序列长度是 365,即一年中的天数。因而,咱们将训练时的输出序列长度设置为 12。
train_window = 12
复制代码
接下来,咱们将定义一个名为 create_inout_sequences 的函数。该函数将承受原始输出数据,并将返回一个元组列表。在每个元组中,第一个元素将蕴含 12 个我的项目的列表,对应于 12 个月内旅行的乘客数量,第二个元组元素将蕴含一个我的项目,即 12+ 1 个月内的乘客数量。
def create_inout_sequences(input_data, tw):
inout_seq = []
L = len(input_data)
for i in range(L-tw):
train_seq = input_data[i:i+tw]
train_label = input_data[i+tw:i+tw+1]
inout_seq.append((train_seq ,train_label))
return inout_seq
复制代码
运行这个脚本来发明用来训练的列表和相干的标签:
train_inout_seq = create_inout_sequences(train_data_normalized, train_window)
复制代码
如果你打印 train_inout_seq 列表的长度,你会发现它蕴含 120 个我的项目。这是因为尽管训练集蕴含 132 个元素,但序列长度为 12,这意味着第一个序列由前 12 个我的项目组成,第 13 个我的项目是第一个序列的标签。同样地,第二个序列从第二项开始,在第 13 项完结,而第 14 项是第二个序列的标签,以此类推。
当初让咱们打印 train_inout_seq 列表的前 5 项。
train_inout_seq[:5]
复制代码
Output:
[(tensor([-0.9648, -0.9385, -0.8769, -0.8901, -0.9253, -0.8637, -0.8066, -0.8066,
-0.8593, -0.9341, -1.0000, -0.9385]), tensor([-0.9516])),
(tensor([-0.9385, -0.8769, -0.8901, -0.9253, -0.8637, -0.8066, -0.8066, -0.8593,
-0.9341, -1.0000, -0.9385, -0.9516]),
tensor([-0.9033])),
(tensor([-0.8769, -0.8901, -0.9253, -0.8637, -0.8066, -0.8066, -0.8593, -0.9341,
-1.0000, -0.9385, -0.9516, -0.9033]), tensor([-0.8374])),
(tensor([-0.8901, -0.9253, -0.8637, -0.8066, -0.8066, -0.8593, -0.9341, -1.0000,
-0.9385, -0.9516, -0.9033, -0.8374]), tensor([-0.8637])),
(tensor([-0.9253, -0.8637, -0.8066, -0.8066, -0.8593, -0.9341, -1.0000, -0.9385,
-0.9516, -0.9033, -0.8374, -0.8637]), tensor([-0.9077]))]
复制代码
你能够看到,每个我的项目都是一个元组,其中第一个元素由一个序列的 12 个我的项目组成,第二个元组元素蕴含相应的标签。