如何将时间序列转换为Python中的监督学习问题(2)

接着我的上篇博客:如何将时间序列转换为Python中的监督学习问题(1)点击打开链接中遗留下来的问题继续讨论:

我们如何利用shift()函数创建出过去和未来的值。

在本节中,我们将定义一个名为series_to_supervised()的新Python函数,该函数采用单变量或多变量时间序列并将其构建为监督学习数据集。

该函数有四个参数:

  • data:作为列表或2D NumPy数组的观察序列。需要。
  • n_in:作为输入的滞后观察数(X)。值可以在[1..len(数据)]之间可选。默认为1。
  • n_out:作为输出的观测数量(y)。值可以在[0..len(数据)-1]之间。可选的。默认为1。
  • dropnan:Boolean是否删除具有NaN值的行。可选的。默认为True。

该函数返回一个值:

  • 返回:系列的Pandas DataFrame用于监督学习。

新数据集构造为DataFrame,每列适当地由变量数和时间步命名。这允许您根据给定的单变量或多变量时间序列设计各种不同的时间步长序列类型预测问题。

返回DataFrame后,您可以决定如何将返回的DataFrame的行拆分为X和y组件,以便以任何方式进行监督学习。

该函数是使用默认参数定义的,因此如果仅使用数据调用它,它将构造一个数据框,其中t-1为X,t为y。

该函数被确认与Python 2和Python 3兼容。

下面列出了完整的功能,包括功能注释。

from pandas import DataFrame
from pandas import concat

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
	"""
	Frame a time series as a supervised learning dataset.
	Arguments:
		data: Sequence of observations as a list or NumPy array.
		n_in: Number of lag observations as input (X).
		n_out: Number of observations as output (y).
		dropnan: Boolean whether or not to drop rows with NaN values.
	Returns:
		Pandas DataFrame of series framed for supervised learning.
	"""
	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)]
	# forecast sequence (t, t+1, ... t+n)
	for i in range(0, n_out):
		cols.append(df.shift(-i))
		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

现在我们已经拥有了整个功能,我们可以探索如何使用它。

扫描二维码关注公众号,回复: 2899814 查看本文章

一步式单变量预测

时间序列预测的标准做法是使用滞后观测值(例如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):
	"""
	Frame a time series as a supervised learning dataset.
	Arguments:
		data: Sequence of observations as a list or NumPy array.
		n_in: Number of lag observations as input (X).
		n_out: Number of observations as output (y).
		dropnan: Boolean whether or not to drop rows with NaN values.
	Returns:
		Pandas DataFrame of series framed for supervised learning.
	"""
	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)]
	# forecast sequence (t, t+1, ... t+n)
	for i in range(0, n_out):
		cols.append(df.shift(-i))
		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)
print(data)

运行该示例将打印重新构建的时间序列的输出。

我们可以看到观察结果被命名为“ var1 ”,输入观察值被恰当地命名为(t-1),输出时间步长被命名为(t)。

我们还可以看到具有NaN值的行已自动从DataFrame中删除。

我们可以用任意数字长度的输入序列重复这个例子,例如3.这可以通过将输入序列的长度指定为参数来完成。例如:

data = series_to_supervised(values, 3)

下面列出了完整的示例。

from pandas import DataFrame
from pandas import concat

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
	"""
	Frame a time series as a supervised learning dataset.
	Arguments:
		data: Sequence of observations as a list or NumPy array.
		n_in: Number of lag observations as input (X).
		n_out: Number of observations as output (y).
		dropnan: Boolean whether or not to drop rows with NaN values.
	Returns:
		Pandas DataFrame of series framed for supervised learning.
	"""
	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)]
	# forecast sequence (t, t+1, ... t+n)
	for i in range(0, n_out):
		cols.append(df.shift(-i))
		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, 3)
print(data)

再次,运行该示例打印重构系列。我们可以看到输入序列是从正确的从左到右的顺序,输出变量在最右边预测。

多步或序列预测

不同类型的预测问题是使用过去的观测来预测未来观测的序列。

这可称为序列预测或多步预测。

我们可以通过指定另一个参数来构建序列预测的时间序列。例如,我们可以使用2个过去观测的输入序列构建预测问题,以预测2个未来观测,如下所示:

data = series_to_supervised(values, 2, 2)

完整示例如下:

from pandas import DataFrame
from pandas import concat

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
	"""
	Frame a time series as a supervised learning dataset.
	Arguments:
		data: Sequence of observations as a list or NumPy array.
		n_in: Number of lag observations as input (X).
		n_out: Number of observations as output (y).
		dropnan: Boolean whether or not to drop rows with NaN values.
	Returns:
		Pandas DataFrame of series framed for supervised learning.
	"""
	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)]
	# forecast sequence (t, t+1, ... t+n)
	for i in range(0, n_out):
		cols.append(df.shift(-i))
		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)

运行该示例显示输入(tn)和输出(t + n)变量的区别,其中当前观察(t)被视为输出。

多变量预测

另一种重要的时间序列称为多变量时间序列。

在这里,我们可能会观察到多种不同的测量方法,并且有兴趣预测其中的一种或多种。

例如,我们可能有两组时间序列观测值obs1和obs2,我们希望预测其中一个或两个。

我们可以用完全相同的方式调用series_to_supervised()。

例如:

from pandas import DataFrame
from pandas import concat

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
	"""
	Frame a time series as a supervised learning dataset.
	Arguments:
		data: Sequence of observations as a list or NumPy array.
		n_in: Number of lag observations as input (X).
		n_out: Number of observations as output (y).
		dropnan: Boolean whether or not to drop rows with NaN values.
	Returns:
		Pandas DataFrame of series framed for supervised learning.
	"""
	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)]
	# forecast sequence (t, t+1, ... t+n)
	for i in range(0, n_out):
		cols.append(df.shift(-i))
		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


raw = DataFrame()
raw['ob1'] = [x for x in range(10)]
raw['ob2'] = [x for x in range(50, 60)]
values = raw.values
data = series_to_supervised(values)
print(data)

运行该示例将打印数据的新框架,显示两个变量的一个时间步长的输入模式和两个变量的一个时间步的输出模式。

同样,根据问题的具体情况,可以任意选择将列划分为X和Y分量,例如,如果还提供var1的当前观察作为输入,并且仅预测var2。

通过指定输入和输出序列的长度,您可以看到如何通过多变量时间序列轻松地将其用于序列预测。

例如,下面是一个重构的示例,其中1个时间步长作为输入,2个时间步长作为预测序列。

from pandas import DataFrame
from pandas import concat

def series_to_supervised(data, n_in=1, n_out=1, dropnan=True):
	"""
	Frame a time series as a supervised learning dataset.
	Arguments:
		data: Sequence of observations as a list or NumPy array.
		n_in: Number of lag observations as input (X).
		n_out: Number of observations as output (y).
		dropnan: Boolean whether or not to drop rows with NaN values.
	Returns:
		Pandas DataFrame of series framed for supervised learning.
	"""
	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)]
	# forecast sequence (t, t+1, ... t+n)
	for i in range(0, n_out):
		cols.append(df.shift(-i))
		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


raw = DataFrame()
raw['ob1'] = [x for x in range(10)]
raw['ob2'] = [x for x in range(50, 60)]
values = raw.values
data = series_to_supervised(values, 1, 2)
print(data)

运行该示例显示了大型重构的DataFrame。

试验您自己的数据集并尝试多种不同的框架,看看哪种方法效果最好。

概要

在本教程中,您了解了如何将时间序列数据集重新定义为Python的监督学习问题。

具体来说,你学到了:

  • 关于Pandas shift()函数以及它如何用于从时间序列数据中自动定义监督学习数据集。
  • 如何将单变量时间序列重构为一步和多步监督学习问题。
  • 如何将多变量时间序列重构为一步和多步监督学习问题

..................................接下来请看如何将时间序列转换为Python中的监督学习问题(3).....................................

注:本文如若有错误或者涉及版权问题或原文链接错误,请指正,必会马上修改。

本文主要翻译自https://machinelearningmastery.com/convert-time-series-supervised-learning-problem-python/

猜你喜欢

转载自blog.csdn.net/qq_27280237/article/details/80980946
今日推荐