注:该文章是翻译于詹姆斯.布朗利的一篇论文。如若参考原文请点击原文链接,查看。
像深度学习这样的机器学习方法(RNN,比如LSTM)可用于时间序列预测。
在使用机器学习之前,时间序列预测问题必须重新构建为监督学习问题。从一个输入序列对到一个输出序列对。
本教程中,您将了解如何将单变量和多变量时间序列预测问题转换为机器学习算法一起使用监督学习问题。
完成本教程后,将会知道:
- 如何开发一个函数将时间序列数据集转换为监督学习数据集
- 如何变换用于机器学习的单变量时间序列数据
- 如何变换用于机器学习的多元时间序列数据
时间序列与监督学习
时间序列是按时间索引排序的一系列数字,可以被认为是有序值得列表或列
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
监督学习问题由输入模式(X)和输出模式(Y)组成,这样算法可以学习如何根据输入吗模式预测输出模式。
例如:
X | y |
1 | 2 |
2 | 3 |
3 | 4 |
4 | 5 |
5 | 6 |
6 | 7 |
7 | 8 |
8 | 9 |
有关此主题的更多信息,请参阅帖子:
Pandas shift()函数
帮助将时间序列数据转换为监督学习问题的关键功能是pandas shift()函数
给定一个DataFrame,可以使用shift()函数创建向前推送的列的副本(NaN值的行添加到前面)或拉回(添加到最后最后的
NaN值的行)。
这是需要创建滞后观察列的行为,以及监督学习格式的时间序列数据集的预测观测列。
我们可以看看一些实际的移位功能。
我们可以将一个模拟时间序列数据集定义为一个由10个数字组成的序列,在这种情况下,DataFrame中的单个列,如下所示
from pandas import DataFrame
df = DataFrame()
df['t'] = [x for x in range(10)]
print(df)
运行该示例将为每个观察值打印具有行索引的时间序列数据
t
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
我们可以通过在顶部插入一个新行来将所有观察结果向下移动一个时间步。由于新行没有数据,我们可以使用NaN来表示“无数据”。
移位功能可以为我们做到这一点,我们可以将这个移位的列插入到我们原来的列旁边。
from pandas import DataFrame
df = DataFrame()
df['t'] = [x for x in range(10)]
df['t-1'] = df['t'].shift(1)
print(df)
该示例会为我们提供数据集中的两列。第一个与原始数据和一个新的列。将序列向前移动一个步骤给了我们一个原始的监督学习问题,尽管X和y的顺序是错误的,忽略列标签由Nan代替。第一行必须丢弃。第二行的第二列的输入值0和第一列的中的值1
t t-1
0 0 NaN
1 1 0.0
2 2 1.0
3 3 2.0
4 4 3.0
5 5 4.0
6 6 5.0
7 7 6.0
8 8 7.0
9 9 8.0
我们可以看到,如果我们可以通过2,3和更多的移位重复这样的过程,我们如何创建用于预测输出值Y的长输入序列X
移位运算符也可以接受一个负整数值。这具有通过在最后插入新行来提取观察结果的效果。看下面的列子:
from pandas import DataFrame
df = DataFrame()
df['t'] = [x for x in range(10)]
df['t-1'] = df['t'].shift(-1)
print(df)
运行该示例将显示一个NaN值作为最后一个值得新列。
我们可以看做预测列作为第一列作为输入,第二列作为输出。即,输入0,预测1的值
t t+1
0 0 1.0
1 1 2.0
2 2 3.0
3 3 4.0
4 4 5.0
5 5 6.0
6 6 7.0
7 7 8.0
8 8 9.0
9 9 NaN
在时间序列预测术语中,当前时间t和未来时间(t+1....,t+n)是预测时间,过去的观测值(t-1,t-2,....,t-n)用于预测。
我们可以看到积极和消极的变化可以用来创建一个新的数据帧从时间序列的输入和输出模式序列监督学习问题。
此外,移位函数也适用于所谓的多变量时间序列问题。那是一个时间序列,而不是一组观察值,我们有多个(比如,温度,压力).时间序列 中的所有变量可以向前或向后移动以创建多变量输入和输出序列。
series_to_supervised()函数
我们可以使用Pandas中的shift()函数根据输入和输出序列的期望长度自动创建时间序列问题的帧。这将是一个有用的工具,因为他尅让我们利用机器学习算法探索时间序列问题的不同帧,以查看那些可能会导致更好的模型。
我们换可以定义一个名为series_to_supervised()的函数,他采用单变量或多变量时间序列,并将其作为监督学习数据集。该函数有四个参数:
数据:作为列表或2DNumpy数组的观察徐磊,必须
n_in:作为输入X的滞后观测值的数量,值可能介于1---len(data)-1,可选默认为1
n_out:作为输出的观察次数y。值可以在0--len(datra)-1之间,默认为1
dropnan:布尔型,是否删除具有nan值得行,可选。默认为True
该函数返回单个值:为监督学习构筑的pandas DataFrame
新的数据集被构造成一个DataFrame,每一列都适当地可变数量和时间步长命名。这允许您根据给定的单变量
或多变量时间序列设计各种不同的时间步长序列类型预测问题。
返回DataFrame后,您可以约定如何将返回的DataFrame的行纷纷称X和Y组件,以便任何您希望的方式监督学习
该函数使用默认参数定义的,如果仅用数据调用他,他将构造一个DataFrame,其中t-1为X t为Y,完成功能如下:
from pandas import DataFrame
from pandas import concat
def series_to_supervised(data,n_in=1,n_out=1,dropnan=True):
n_vars = 1 if type(data) is list else data.shape[1]
df = DataFrame(data)
cols,names = list(),list()
# input sequence(t-n,...t-1)
for i in range(n_in,0,-1):
cols.append(df.shift(i))
names+= [('var%d(t-%d)'%(j+1,i))for j in range(n_vars)]
#forecase sequence (t t+1,....,t+n)
for i in range(0,n_out):
cols.append(df.shift(-1))
if i==0:
names += [('var%d(t)'%(j+1))for j in range (n_vars)]
else
names+=[('var%d(t+%d)'%(j+1,i))for j in range(n_vars)]
#put it all together
agg = concat(cols,axis=1)
agg.columns = names
#drop rows with nan values
if dropnan:
agg.dropna(inplace=True)
return agg
我们有了全部的功能,我们可以探索他是如何使用的
一步单变量预测
在时间序列预测中,标准做法是使用滞后观察值(t-1),作为输入变量来预测当前时间步长(t)。这称之为一步预测。
下面的例子演示了预测当前时间步长T的一个滞后时间步长t-1
from pandas import DataFrame
from pandas import concat
def series_to_supervised(data,n_in=1,n_out=1,dropnan=True):
n_vars = 1 if type(data) is list else data.shape[1]
df = DataFrame(data)
cols,names = list(),list()
# input sequence(t-n,...t-1)
for i in range(n_in,0,-1):
cols.append(df.shift(i))
names+= [('var%d(t-%d)'%(j+1,i))for j in range(n_vars)]
#forecase sequence (t t+1,....,t+n)
for i in range(0,n_out):
cols.append(df.shift(-1))
if i==0:
names += [('var%d(t)'%(j+1))for j in range (n_vars)]
else:
names+=[('var%d(t+%d)'%(j+1,i))for j in range(n_vars)]
#put it all together
agg = concat(cols,axis=1)
agg.columns = names
结果:
var1(t-1) var1(t)
1 0.0 2.0
2 1.0 3.0
3 2.0 4.0
4 3.0 5.0
5 4.0 6.0
6 5.0 7.0
7 6.0 8.0
8 7.0 9.0
我们可以看到,观察结果被命名为VAr1 ,并且输入观察值被命名为t-1,输出时间步命名为t,而且NaN值得行已经从DataFrame中自动删除。我们也可以指定输入序列的长度来完成。
data = series_to_supervised(values,3)
var1(t-3) var1(t-2) var1(t-1) var1(t)
3 0.0 1.0 2.0 4.0
4 1.0 2.0 3.0 5.0
5 2.0 3.0 4.0 6.0
6 3.0 4.0 5.0 7.0
7 4.0 5.0 6.0 8.0
8 5.0 6.0 7.0 9.0
多步或序列预测
我们可以通过指定另一个参数来构建序列预测的时间序列。比如,我们可以用2个过去的观测值得输入序列来构造预测问题,来预测2个未来的观测值,如下所示:
data = series_to_superised(values,2,2)
完整代码如下:
from pandas import DataFrame
from pandas import concat
def series_to_supervised(data,n_in=1,n_out=1,dropnan=True):
n_vars = 1 if type(data) is list else data.shape[1]
df = DataFrame(data)
cols,names = list(),list()
# input sequence(t-n,...t-1)
for i in range(n_in,0,-1):
cols.append(df.shift(i))
names+= [('var%d(t-%d)'%(j+1,i))for j in range(n_vars)]
#forecase sequence (t t+1,....,t+n)
for i in range(0,n_out):
cols.append(df.shift(-1))
if i==0:
names += [('var%d(t)'%(j+1))for j in range (n_vars)]
else:
names+=[('var%d(t+%d)'%(j+1,i))for j in range(n_vars)]
#put it all together
agg = concat(cols,axis=1)
agg.columns = names
#drop rows with nan values
if dropnan:
agg.dropna(inplace=True)
return agg
values = [x for x in range(10)]
data = series_to_supervised(values,2,2)
print(data)
结果如下:
var1(t-2) var1(t-1) var1(t) var1(t+1)
2 0.0 1.0 3.0 3.0
3 1.0 2.0 4.0 4.0
4 2.0 3.0 5.0 5.0
5 3.0 4.0 6.0 6.0
6 4.0 5.0 7.0 7.0
7 5.0 6.0 8.0 8.0
8 6.0 7.0 9.0 9.0
多变量预测
另外一种重要的时间序列称之为多变量时间序列。
我们可以在这里观察多种不同的度量值,并且对预测其中的一个或多个有兴趣。
比如,我们可能有两组时间序列观测obs1 和 obs2,我们希望预测其中的一个或者两个。
我们可以用完全相同的方式调用series_to_superied()
比如:
from pandas import DataFrame
from pandas import concat
def series_to_supervised(data,n_in=1,n_out=1,dropnan=True):
n_vars = 1 if type(data) is list else data.shape[1]
df = DataFrame(data)
cols,names = list(),list()
# input sequence(t-n,...t-1)
for i in range(n_in,0,-1):
cols.append(df.shift(i))
names+= [('var%d(t-%d)'%(j+1,i))for j in range(n_vars)]
#forecase sequence (t t+1,....,t+n)
for i in range(0,n_out):
cols.append(df.shift(-1))
if i==0:
names += [('var%d(t)'%(j+1))for j in range (n_vars)]
else:
names+=[('var%d(t+%d)'%(j+1,i))for j in range(n_vars)]
#put it all together
agg = concat(cols,axis=1)
agg.columns = names
#drop rows with nan values
if dropnan:
agg.dropna(inplace=True)
return agg
#values = [x for x in range(10)]
row = DataFrame()
row['ob1'] = [x for x in range(10)]
row['ob2'] = [x for x in range(50,60)]
values = row.values
data = series_to_supervised(values)
print(data)
我们可以根据任意列分为X和Y变量,运行结果如下:
var1(t-1) var2(t-1) var1(t) var2(t)
1 0.0 50.0 2.0 52.0
2 1.0 51.0 3.0 53.0
3 2.0 52.0 4.0 54.0
4 3.0 53.0 5.0 55.0
5 4.0 54.0 6.0 56.0
6 5.0 55.0 7.0 57.0
7 6.0 56.0 8.0 58.0
概要
在本教程中,您了解如何将时间序列数据转化为用于监督学习的数据。具体:
关于pandas的shift()的使用和含义
如何将单变量时间数据重构为一步和多步监督学习问题
如何将多元时间序列重构为一步和多步监督学习问题。