像深度学习这样的机器学习方法可以用于时间序列预测。
在可以使用机器学习之前,必须将时间序列预测问题重新构建为监督学习问题。从一个序列到输入和输出序列的对。
在本教程中,您将发现如何将单变量和多变量时间序列预测问题转换为监督学习问题,以用于机器学习算法。
完成本教程后,您将了解:
- 如何开发一个函数来将时间序列数据集转换为监督学习数据集。
- 如何为机器学习转换单变量时间序列数据。
- 如何为机器学习转换多变量时间序列数据。
通过我的新书 《Python 时间序列预测入门》,循序渐进的教程和所有示例的Python源代码文件,开启您的项目。
让我们开始吧。

如何在 Python 中将时间序列转换为监督学习问题
照片作者:Quim Gil,保留部分权利。
时间序列 vs 监督学习
在开始之前,让我们花点时间更好地理解时间序列和监督学习数据的形式。
时间序列是按时间索引排序的一系列数字。这可以被认为是按顺序排列的值的列表或列。
例如
1 2 3 4 5 6 7 8 9 10 |
0 1 2 3 4 5 6 7 8 9 |
监督学习问题由输入模式 (X) 和输出模式 (y) 组成,以便算法能够学习如何从输入模式预测输出模式。
例如
1 2 3 4 5 6 7 8 9 |
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 值行)的列副本。
这就是将滞后观测值列以及预测观测值列以监督学习格式创建为时间序列数据集所需的功能。
让我们看一些 shift 函数的实际示例。
我们可以将一个模拟时间序列数据集定义为 10 个数字的序列,在本例中是一个 DataFrame 中的单列,如下所示:
1 2 3 4 |
from pandas import DataFrame df = DataFrame() df['t'] = [x for x in range(10)] print(df) |
运行此示例将打印出带有每个观测值的行索引的时间序列数据。
1 2 3 4 5 6 7 8 9 10 11 |
t 0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 |
我们可以通过在顶部插入一行新行,将所有观测值向下移动一个时间步。因为新行没有数据,我们可以使用 NaN 来表示“无数据”。
shift 函数可以为我们做到这一点,我们可以将这个移位的列插入到原始序列旁边。
1 2 3 4 5 |
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 值,第一行将被丢弃。第二行显示第二列(输入或 X)中的输入值为 0.0,第一列(输出或 y)中的值为 1。
1 2 3 4 5 6 7 8 9 10 11 |
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 或更多次来重复这个过程,我们就能创建长输入序列 (X) 来预测输出值 (y)。
shift 运算符还可以接受负整数值。这会通过在末尾插入新行来向上拉动观测值。下面是一个例子:
1 2 3 4 5 |
from pandas import DataFrame df = DataFrame() df['t'] = [x for x in range(10)] df['t+1'] = df['t'].shift(-1) print(df) |
运行示例会显示一个新列,其最后一个值是 NaN。
我们可以看到,预测列可以作为输入 (X),第二个作为输出值 (y)。也就是说,输入值 0 可以用来预测输出值 1。
1 2 3 4 5 6 7 8 9 10 11 |
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-n) 用于进行预测。
我们可以看到正向和负向的移位如何用于从时间序列创建新的 DataFrame,其中包含监督学习问题的输入和输出模式序列。
这不仅允许经典的 X -> y 预测,还允许 X -> Y,其中输入和输出都可以是序列。
此外,shift 函数也适用于所谓的多元时间序列问题。也就是说,我们不需要只有一套时间序列观测值,而是有多个(例如温度和压力)。时间序列中的所有变量都可以向前或向后移位,以创建多元输入和输出序列。我们将在本教程后面更详细地探讨这一点。
series_to_supervised() 函数
我们可以使用 Pandas 中的 shift() 函数,根据所需的输入和输出序列长度,自动创建新的时间序列问题框架。
这将是一个有用的工具,因为它允许我们使用机器学习算法探索时间序列问题的不同框架,看看哪些可能导致更好的模型性能。
在本节中,我们将定义一个名为 series_to_supervised() 的新 Python 函数,该函数接受单变量或多变量时间序列,并将其构建为监督学习数据集。
该函数接受四个参数:
- data:作为列表或 2D NumPy 数组的观测值序列。必需。
- n_in:作为输入的滞后观测值数量 (X)。值可以介于 [1..len(data)] 之间。可选。默认为 1。
- n_out:作为输出的观测值数量 (y)。值可以介于 [0..len(data)-1] 之间。可选。默认为 1。
- dropnan:一个布尔值,表示是否删除带有 NaN 值的行。可选。默认为 True。
该函数返回一个值:
- return:用于监督学习的序列框架的 Pandas DataFrame。
新数据集构造为一个 DataFrame,每个列都根据变量编号和时间步进行了适当命名。这使您可以从给定的单变量或多变量时间序列构建各种不同时间步序列类型的预测问题。
一旦返回 DataFrame,您就可以决定如何将返回 DataFrame 的行拆分为监督学习的 X 和 y 组件。
该函数使用默认参数定义,因此如果您仅使用数据调用它,它将构造一个以 t-1 作为 X 和 t 作为 y 的 DataFrame。
该函数已确认与 Python 2 和 Python 3 兼容。
完整的函数列在下面,包括函数注释。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
from pandas import DataFrame 从 pandas 导入 concat def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): """ 将时间序列构建为监督学习数据集。 参数 data: 作为列表或 NumPy 数组的观测值序列。 n_in: 作为输入的滞后观测值数量 (X)。 n_out: 作为输出的观测值数量 (y)。 dropnan: 一个布尔值,表示是否删除带有 NaN 值的行。 返回值 用于监督学习的序列框架的 Pandas DataFrame。 """ n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = list(), list() # 输入序列 (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)] # 预测序列 (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)] # 将它们组合在一起 agg = concat(cols, axis=1) agg.columns = names # 删除包含 NaN 值的行 if dropnan: agg.dropna(inplace=True) return agg |
您能看出使函数更健壮或更具可读性的明显方法吗?
请在下面的评论中告诉我。
现在我们有了完整的函数,我们可以探索如何使用它。
一步单变量预测
在时间序列预测中,使用滞后观测值(例如 t-1)作为输入变量来预测当前时间步长 (t) 是标准做法。
这被称为一步预测。
下面的示例演示了一个滞后时间步长 (t-1) 来预测当前时间步长 (t)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
from pandas import DataFrame 从 pandas 导入 concat def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): """ 将时间序列构建为监督学习数据集。 参数 data: 作为列表或 NumPy 数组的观测值序列。 n_in: 作为输入的滞后观测值数量 (X)。 n_out: 作为输出的观测值数量 (y)。 dropnan: 一个布尔值,表示是否删除带有 NaN 值的行。 返回值 用于监督学习的序列框架的 Pandas DataFrame。 """ n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = list(), list() # 输入序列 (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)] # 预测序列 (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)] # 将它们组合在一起 agg = concat(cols, axis=1) agg.columns = names # 删除包含 NaN 值的行 if dropnan: agg.dropna(inplace=True) return agg values = [x for x in range(10)] data = series_to_supervised(values) print(data) |
运行此示例将打印重构时间序列的输出。
1 2 3 4 5 6 7 8 9 10 |
var1(t-1) var1(t) 1 0.0 1 2 1.0 2 3 2.0 3 4 3.0 4 5 4.0 5 6 5.0 6 7 6.0 7 8 7.0 8 9 8.0 9 |
我们可以看到观测值被命名为“var1”,并且输入观测值被恰当地命名为 (t-1),输出时间步被命名为 (t)。
我们还可以看到带有 NaN 值的行已自动从 DataFrame 中删除。
我们可以通过指定输入序列的长度作为参数来重复这个示例,使用任意长度的输入序列,例如 3。例如:
1 |
data = series_to_supervised(values, 3) |
完整的示例如下所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
from pandas import DataFrame 从 pandas 导入 concat def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): """ 将时间序列构建为监督学习数据集。 参数 data: 作为列表或 NumPy 数组的观测值序列。 n_in: 作为输入的滞后观测值数量 (X)。 n_out: 作为输出的观测值数量 (y)。 dropnan: 一个布尔值,表示是否删除带有 NaN 值的行。 返回值 用于监督学习的序列框架的 Pandas DataFrame。 """ n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = list(), list() # 输入序列 (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)] # 预测序列 (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)] # 将它们组合在一起 agg = concat(cols, axis=1) agg.columns = names # 删除包含 NaN 值的行 if dropnan: agg.dropna(inplace=True) return agg values = [x for x in range(10)] data = series_to_supervised(values, 3) print(data) |
再次运行示例将打印重构的序列。我们可以看到输入序列以正确的从左到右顺序排列,要预测的输出变量在最右边。
1 2 3 4 5 6 7 8 |
var1(t-3) var1(t-2) var1(t-1) var1(t) 3 0.0 1.0 2.0 3 4 1.0 2.0 3.0 4 5 2.0 3.0 4.0 5 6 3.0 4.0 5.0 6 7 4.0 5.0 6.0 7 8 5.0 6.0 7.0 8 9 6.0 7.0 8.0 9 |
多步或序列预测
一种不同的预测问题是使用过去的观测值来预测未来观测值的序列。
这可能被称为序列预测或多步预测。
我们可以通过指定另一个参数来构建用于序列预测的时间序列。例如,我们可以构建一个预测问题,其中输入序列是 2 个过去的观测值,用于预测 2 个未来观测值,如下所示:
1 |
data = series_to_supervised(values, 2, 2) |
完整的示例列在下面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
from pandas import DataFrame 从 pandas 导入 concat def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): """ 将时间序列构建为监督学习数据集。 参数 data: 作为列表或 NumPy 数组的观测值序列。 n_in: 作为输入的滞后观测值数量 (X)。 n_out: 作为输出的观测值数量 (y)。 dropnan: 一个布尔值,表示是否删除带有 NaN 值的行。 返回值 用于监督学习的序列框架的 Pandas DataFrame。 """ n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = list(), list() # 输入序列 (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)] # 预测序列 (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)] # 将它们组合在一起 agg = concat(cols, axis=1) agg.columns = names # 删除包含 NaN 值的行 if dropnan: agg.dropna(inplace=True) return agg values = [x for x in range(10)] data = series_to_supervised(values, 2, 2) print(data) |
运行示例将显示输入 (t-n) 和输出 (t+n) 变量的差异,并将当前观测值 (t) 视为输出。
1 2 3 4 5 6 7 8 |
var1(t-2) var1(t-1) var1(t) var1(t+1) 2 0.0 1.0 2 3.0 3 1.0 2.0 3 4.0 4 2.0 3.0 4 5.0 5 3.0 4.0 5 6.0 6 4.0 5.0 6 7.0 7 5.0 6.0 7 8.0 8 6.0 7.0 8 9.0 |
多变量预测
另一个重要类型的时间序列称为多变量时间序列。
这意味着我们可能有多种不同度量的观测值,并对预测其中一个或多个感兴趣。
例如,我们可能有两组时间序列观测值 obs1 和 obs2,我们希望预测其中一个或两个。
我们可以以完全相同的方式调用 series_to_supervised()。
例如
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
from pandas import DataFrame 从 pandas 导入 concat def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): """ 将时间序列构建为监督学习数据集。 参数 data: 作为列表或 NumPy 数组的观测值序列。 n_in: 作为输入的滞后观测值数量 (X)。 n_out: 作为输出的观测值数量 (y)。 dropnan: 一个布尔值,表示是否删除带有 NaN 值的行。 返回值 用于监督学习的序列框架的 Pandas DataFrame。 """ n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = list(), list() # 输入序列 (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)] # 预测序列 (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)] # 将它们组合在一起 agg = concat(cols, axis=1) agg.columns = names # 删除包含 NaN 值的行 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 3 4 5 6 7 8 9 10 |
var1(t-1) var2(t-1) var1(t) var2(t) 1 0.0 50.0 1 51 2 1.0 51.0 2 52 3 2.0 52.0 3 53 4 3.0 53.0 4 54 5 4.0 54.0 5 55 6 5.0 55.0 6 56 7 6.0 56.0 7 57 8 7.0 57.0 8 58 9 8.0 58.0 9 59 |
您可以看到,通过指定上述输入和输出序列的长度,如何轻松地将此用于多变量时间序列的序列预测。
例如,下面是一个重构的示例,其中 1 个时间步作为输入,2 个时间步作为预测序列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
from pandas import DataFrame 从 pandas 导入 concat def series_to_supervised(data, n_in=1, n_out=1, dropnan=True): """ 将时间序列构建为监督学习数据集。 参数 data: 作为列表或 NumPy 数组的观测值序列。 n_in: 作为输入的滞后观测值数量 (X)。 n_out: 作为输出的观测值数量 (y)。 dropnan: 一个布尔值,表示是否删除带有 NaN 值的行。 返回值 用于监督学习的序列框架的 Pandas DataFrame。 """ n_vars = 1 if type(data) is list else data.shape[1] df = DataFrame(data) cols, names = list(), list() # 输入序列 (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)] # 预测序列 (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)] # 将它们组合在一起 agg = concat(cols, axis=1) agg.columns = names # 删除包含 NaN 值的行 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。
1 2 3 4 5 6 7 8 9 |
var1(t-1) var2(t-1) var1(t) var2(t) var1(t+1) var2(t+1) 1 0.0 50.0 1 51 2.0 52.0 2 1.0 51.0 2 52 3.0 53.0 3 2.0 52.0 3 53 4.0 54.0 4 3.0 53.0 4 54 5.0 55.0 5 4.0 54.0 5 55 6.0 56.0 6 5.0 55.0 6 56 7.0 57.0 7 6.0 56.0 7 57 8.0 58.0 8 7.0 57.0 8 58 9.0 59.0 |
尝试使用您自己的数据集,并尝试多种不同的框架,看看哪种效果最好。
总结
在本教程中,您学习了如何使用 Python 将时间序列数据集重构为监督学习问题。
具体来说,你学到了:
- 关于 Pandas shift() 函数及其如何用于自动从时间序列数据定义监督学习数据集。
- 如何将单变量时间序列重构为一步和多步监督学习问题。
- 如何将多变量时间序列重构为一步和多步监督学习问题。
你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。
Jason,感谢您这篇非常有价值的文章!:)
我很难理解数据集的结构。我理解 t-n、t-1、t、t+1、t+n 等的基本原理。但是,t 和 t-1 列究竟描述的是什么?如果是某个解释变量随时间的变化?如果是这样,将数据转置,使时间描述在行而不是列中,是不是更有意义?
另外,您将如何描述以下数据:
Customer_ID Month Balance
1 01 1,500
1 02 1,600
1 03 1,700
1 04 1,900
2 01 1,000
2 02 900
2 03 700
2 04 500
3 01 3,500
3 02 1,500
3 03 2,500
3 04 4,500
假设,我们想通过监督学习来预测他们的余额,或者将客户分类为“储蓄者”或“支出者”。
是的,它是转置每个变量,但允许控制每行回到时间的时间长度。
Jason,感谢您提供非常有用的教程,我也有和 Mikkel 同样的问题。
您将如何描述以下数据?
假设我们有一个与以下类似的数据集。
如果我们想预测第四个月每个客户的余额,我应该如何处理这个问题?
提前非常感谢!
Customer_ID Month Balance
1 01 1,500
1 02 1,600
1 03 1,700
1 04 1,900
2 01 1,000
2 02 900
2 03 700
2 04 500
3 01 3,500
3 02 1,500
3 03 2,500
3 04 4,500
测试不同的问题框架。
尝试将所有客户一起建模作为第一步。
Jason,我也有一个类似的数据集,我们观察了数周的交易活动,并记录了在特定时间段内是否提前付款。我想预测谁可能提前付款(0 表示否,1 表示是)。您能多解释一下您所说的“尝试将所有客户一起建模作为第一步”是什么意思吗?请看下面的示例数据:
Deal Date Portfolio Prepaid
1 1/1/18 A 0
1 1/8/18 A 0
1 1/15/18 A 0
1 1/22/18 A 1
2 1/1/18 B 0
2 1/8/18 B 0
2 1/15/18 B 0
2 1/22/18 B 0
3 1/1/18 A 0
3 1/8/18 A 0
3 1/15/18 A 0
3 1/22/18 A 1
4 1/1/18 B 0
4 1/8/18 B 0
4 1/15/18 B 0
4 1/22/18 B 1
想法是,是否应该跨主体/站点/公司等进行建模。或者单独建模。也许跨主体建模对您的项目没有意义。
时间序列预测问题是:输入 X 是距离和角度,预测结果 y 是二维坐标。是每列一个数据,还是距离和角度作为一个列 z=(距离,角度)?如果是一个完整的列,如何生成监督序列对?
嗨 JOJO... 我建议您为此目的研究序列到序列技术。
https://machinelearning.org.cn/develop-encoder-decoder-model-sequence-sequence-prediction-keras/
嗨 Mostafa,
我现在正在处理一个类似的问题。您是否找到了一个简单而连贯的答案来解决您的问题?是否有任何文章、代码示例或视频讲座?
如果您找到了什么,请告诉我,我将不胜感激。
谢谢,此致。
这与我的流体力学问题类似,其中客户 ID 被替换为 2D 域中的唯一点的位置(点的 x,y 坐标),余额可以被速度替换。我也无法在线找到有关处理这些类型数据的帮助。
我曾建议为此目的使用 LSTM。您应该为每个单独的时间步长假设 (t-1) 输入 [Customer_ID Month Balance],并且 LSTM 的每个单元输出一个对应于 Balance 的一维假设值。
我想问一下,如果我有前 5 小时的数据,如何获取第六小时的数据?谢谢
我该如何检测时间序列数据中的模式?假设我有一个时间序列 influx db box,我在这里存储每分钟在线玩家的总数,并且我想知道玩家数量何时显示出平稳行为。平稳线可能在 100 万、100 或 1000...
也许您可以对时间间隔内的绝对变化进行建模?
嗨,Jason,
这是一篇很棒的文章!我一直在寻找这个。
唯一的问题是我通常使用 R 编程,所以我只找到了与您的代码类似的东西,但我不太确定它是否相同。我从 https://www.r-bloggers.com/generating-a-laglead-variables/ 获得这个,它处理滞后和超前值。输出也包含 NA 值。
shift1)
return(sapply(shift_by,shift, x=x))
out 0 )
out<-c(tail(x,-abs_shift_by),rep(NA,abs_shift_by))
else if (shift_by < 0 )
out<-c(rep(NA,abs_shift_by), head(x,-abs_shift_by))
else
out<-x
out
}
输出
x df_lead2 df_lag2
1 1 3 NA
2 2 4 NA
3 3 5 1
4 4 6 2
5 5 7 3
6 6 8 4
7 7 9 5
8 8 10 6
9 9 NA 7
10 10 NA 8
我也尝试用 R 重新编译您的代码,但失败了。
我建议联系您引用的 R 代码的作者。
您能用 Go、Java、C# 和 COBOL 也回答这个问题吗???谢谢,我真的什么都不想做。
我尽力帮忙,有些人比其他人需要更多的帮助。
哈哈
我知道。你应该看看我收到的那些“能不能帮我做作业/项目/工作”的邮件 🙂
Jason,文章写得很好,但如果能用一些实际的时间序列数据来说明会更好。另外,也不需要重复五次函数代码 😉 抛开这些小缺点不谈,这篇文章来得正是时候,因为我正要开始做一些时间序列预测,所以非常感谢这篇文章!!!
感谢 Lee 的建议。
嗨,Jason,
谢谢你写了这篇好文章!我真的很喜欢用滑动的方法来重构训练数据!
但是关于这个话题我的问题是:你认为单步单变量预测的下一步是什么?哪种机器学习方法最适合?
很明显,回归器是最佳选择,但我该如何确定训练的滑动窗口大小呢?
非常感谢你的帮助和付出
~ Christopher
我的建议是尝试一系列不同的窗口大小,然后看看哪种效果最好。
你可以使用 ACF/PACF 图作为启发式方法。
https://machinelearning.org.cn/gentle-introduction-autocorrelation-partial-autocorrelation/
你好 Jason:
在这篇文章中,你创建了时间序列的新框架,例如 t-1、t、t+1。但是,这些时间序列的用途是什么?你的意思是这些时间序列会对模型产生好的影响吗?也许
我的问题可能太简单了,因为我是新手,请理解!谢谢!
我正在提供一种技术来帮助你将序列转换为监督学习问题。
这很有价值,因为这样你就可以将时间序列问题转化为监督学习问题,并应用一系列标准的分类和回归技术来做出预测。
哇,你的回答总让我学到很多。谢谢 Jason!
不客气。
你好 Jason。太棒的文章和有用的代码。我有一个问题。一旦我们添加了额外的特征,有了 t, t-1, t-2 等,我们能像平常一样将数据分割成训练/测试集吗?(例如,随机打乱)。我的想法是是的,因为时间信息现在已经包含在特征(t-1, t-2 等)中了。
很想听听你的想法。
我喜欢你的工作!
是的,没错。转换的全部目的是从时间序列中创建间隔,模型只考虑间隔,而不考虑其他任何东西(以及间隔外的数据没有记忆)。在这种情况下,打乱间隔是可以的。但在间隔内打乱则不行。
如果有多个变量 varXi 用于训练,只有一个变量 varY 用于预测,那么是否会以以下方式使用相同的技术?
varX1(t-1) varX2(t-1) varX1(t) varX2(t) … varY(t-1) varY(t)
.. .. .. .. .. ..
然后使用线性回归,并将 Response 设置为 varY(t)?
提前感谢
不确定我是否理解你的问题 Brad,也许你可以再说一遍?
如果存在多个测量值,然后进行转换以便只预测 varXn
var1(t-1) var2(t-1) var1(t) var2(t) … varN(t-1) varN(t)
线性回归应该将 varN(t) 用作响应变量吗?
当然可以。
嗨,Jason,
在我参加训练营的毕业项目期间,我发现你的文章非常有帮助。我有两个问题,希望你能建议我在哪里可以找到更多信息。
首先,我在对新监督数据运行 PCA 时遇到了一个问题。PCA 能识别出滞后序列实际上是相同的数据吗?如果一个人要运行 PCA,他们需要在监督化数据之前进行 PCA 吗?
其次,你建议使用哪些最佳学习算法以及如何正确地在数据上进行训练测试分割?
再次感谢,
抱歉,我没有在时间序列数据上使用过 PCA。我认为需要仔细处理数据的框架。
我在那里有关于时间序列回测的技巧。
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
嗨 Jason
很棒的文章。
只有一个问题。如果某些输入变量是连续的,而某些是分类的,其中一个是二元的,预测两个输出变量。
那么移位是如何工作的?
谢谢
Kushal
是一样的,但请先考虑对分类变量进行编码(例如,数字编码或独热编码)。
谢谢
我应该使用预测变量的滞后版本吗?
Kushal
也许吧,我不明白你的问题,也许你可以提供更多信息再说一遍?
Jason,很棒的文章!
谢谢,希望它有帮助。
非常有用的文章!!
我正在开发一种算法来预测餐厅未来的客流量。我使用的特征是:日期、是否有节日、温度、气候条件、当前评分、是否有假期、服务评分、评论数量等。我能否使用时间序列分析以及这些特征来解决这个问题?如果可以,怎么做。
请指导我
这个过程会指导你。
https://machinelearning.org.cn/start-here/#process
Jason,文章写得很好。只是一个新手问题:这个方法与移动平均平滑有什么不同?我有点困惑!
谢谢
这篇文章只是关于问题框架的。
移动平均是在数据被框架化后要做的事情。
Jason!一如既往的好文章~
我有一个问题。
“运行示例显示了输入(t-n)和输出(t+n)变量的区分,当前观测值(t)被视为输出。”
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 2 3.0
3 1.0 2.0 3 4.0
4 2.0 3.0 4 5.0
5 3.0 4.0 5 6.0
6 4.0 5.0 6 7.0
7 5.0 6.0 7 8.0
8 6.0 7.0 8 9.0
那么上面的例子,var1(t-2) var1(t-1) 是输入,var1(t) var1(t+1) 是输出,我说的对吗?
那么,下面的例子。
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。
var1(t-1) var2(t-1) var1(t) var2(t) var1(t+1) var2(t+1)
1 0.0 50.0 1 51 2.0 52.0
2 1.0 51.0 2 52 3.0 53.0
3 2.0 52.0 3 53 4.0 54.0
4 3.0 53.0 4 54 5.0 55.0
5 4.0 54.0 5 55 6.0 56.0
6 5.0 55.0 6 56 7.0 57.0
7 6.0 56.0 7 57 8.0 58.0
8 7.0 57.0 8 58 9.0 59.0
var1(t-1) var2(t-1) 是输入,var1(t) var2(t) var1(t+1) var2(t+1) 是输出。
你能回答我的问题吗?我将非常感激!
是的,或者你可以按照你希望的方式来解释和使用这些列。
谢谢你,Jason!!
你是有史以来最好的老师
谢谢 Thabet。
Jason,
我喜欢你的文章!继续努力!我有一个泛化问题。在这个数据集中
var1(t-1) var2(t-1) var1(t) var2(t)
1 0.0 50.0 1 51
2 1.0 51.0 2 52
3 2.0 52.0 3 53
4 3.0 53.0 4 54
5 4.0 54.0 5 55
6 5.0 55.0 6 56
7 6.0 56.0 7 57
8 7.0 57.0 8 58
9 8.0 58.0 9 59
如果我想从其他 3 个数据预测 var2(t),输入数据 X 的形状会是 (9,1,3),目标数据 Y 的形状会是 (9,1) 吗?泛化来说,如果这是一个我想使用的多个时间序列的单个实例。假设我有 1000 个时间序列实例。我的数据 X 的形状会是 (1000,9,3) 吗?而输入目标集 Y 的形状会是 (1000,9) 吗?
我的推理是否出错?我是否将问题框架错了?
谢谢!
查尔斯
这篇文章提供了关于如何为 LSTMs 重塑数据的帮助。
https://machinelearning.org.cn/reshape-input-data-long-short-term-memory-networks-keras/
嗨,Jason!
我非常难以在模型构建后进行新预测。你能举个例子吗?我一直在尝试编写一个方法,该方法接收过去的时间数据并返回下一个时间的 yhat。
谢谢你。
是的,请看这篇文章
https://machinelearning.org.cn/make-sample-forecasts-arima-python/
附注:我在如何缩放新输入值方面是最卡壳的。
在训练数据上执行的任何数据转换都必须在新数据上执行,以便你想要做出预测。
但是,如果数据集中没有那个目标变量呢?例如,以空气污染问题为例,现在我想根据其他变量的某些预期来预测未来值,就像我们在回归中那样,我们在训练集上训练模型,然后测试它,然后为我们不知道目标变量的新数据进行预测。但是,在 Keras 的 lstm 中,当我们预测新数据时,它的变量比训练数据集少一个,例如空气污染,我们会遇到形状不匹配的问题……
我为这个问题挣扎了一个星期,还没有找到解决方案……
你可以按照你希望的方式来构建问题。
从一个样本的角度来思考,例如,输入是什么,输出是什么。
一旦你清楚了这一点,就将训练数据塑造成代表它,然后拟合模型。
嗨,Jason,
这很棒,但如果我有大约十个特征(例如 4 个分类和 6 个连续),每天有几千个数据点,训练集中有大约 200 天的数据呢?理论上移位函数可以工作,但你会添加数十万个列,这在计算上是极其困难的。
在这些情况下,推荐的方法是什么?
是的,你会得到很多列。
嗨,Jason,
我将我的时间序列问题转化为回归问题,并使用 GradientBoostingRegressor 对数据进行建模。我发现我的调整后的 R 方在每次运行模型时都在不断变化。我相信这是因为自变量(滞后变量)之间存在相关性。如何处理这种情况?尽管波动的范围很小,但我担心这可能是一个糟糕的模型。
这可能是由于算法的随机性质。
https://machinelearning.org.cn/randomness-in-machine-learning/
嗨,Jason,
我应用了你解释的概念,并使用了线性回归。我能否通过对 t-1 项进行平方来将此概念扩展到多项式回归?
当然,让我知道你的进展。
嗨,Jason,
非常感谢你的文章!我已经读了很多你的文章。这些文章都很棒,它们确实帮了我很多。
但我仍然有一个相当普遍的问题,我似乎无法理解。
问题基本上是
在什么情况下,我将监督学习问题视为时间序列问题,反之亦然?
为了更深入地了解,这是我目前正在努力解决的问题。
我拥有工厂的数据(数百个特征),可以用作我的输入。
此外,工厂的能源需求是我的输出。
所以我已经有很多输入-输出对。
工厂的能源需求也是我想预测的数量。
每个数据点都有自己的时间戳。
我可以将时间戳转换为几个特征,以考虑趋势和季节性。
随后,我可以使用不同的回归模型来预测工厂的能源需求。
这将是一个经典的监督回归问题。
但是,正如我从你的时间序列文章中理解的那样,我也可以将同样的问题视为时间序列问题。
我可以使用时间戳来提取时间值,这些值可以用于多变量时间序列预测。
在你给出的许多示例中,你的时间序列文章都有输出随时间变化的情况。
https://machinelearning.org.cn/reframe-time-series-forecasting-problem/
在这篇文章中,你移动了时间序列以获得输入,以便将问题视为监督学习问题。
所以,假设你在两种情况下都有相同数量的特征。
将监督学习问题改变为时间序列问题是否是一个有希望的解决方案?
这样做的好处和坏处是什么?
因为大多数回归输出都是随时间变化的。
是否有通用规则,何时使用哪种框架(监督或时间序列)来解决问题?
我希望我能够以有序的方式表述我的困惑。
非常感谢你的时间和帮助,我非常感激!
致礼 Samuel
要使用监督学习算法,你必须将时间序列表示为监督学习问题。
我不确定你说的“将监督学习问题调整为序列”是什么意思?
亲爱的 Jason,
感谢你的快速回复。
很抱歉我无法清晰地表述我的问题,我对机器学习还很新。
我将尝试用一个例子来解释。
假设你有以下数据,我从你的文章中改编的
https://machinelearning.org.cn/time-series-forecasting-supervised-learning/
input1(时间), input2, output
1, 0.2, 88
2, 0.5, 89
3, 0.7, 87
4, 0.4, 88
5, 1.0, 90
这些数据是你认为是时间序列。但由于你已经有了 2 个输入和 1 个输出,你已经可以为监督机器学习使用这些数据了。
为了预测数据的未来输出,你必须在时间步长 6 时知道 input1 和 input2。假设你从工厂的生产计划中知道,在时间步长 6 时 input2 的值为 0.8 (input1)。有了这些数据,你可以从模型中获得 y_pred。你将数据完全视为监督机器学习问题。
input1(时间), input2, output
1, 0.2, 88
2, 0.5, 89
3, 0.7, 87
4, 0.4, 88
5, 1.0, 90
6, 0.8, y_pred
但根据你的文章,你也可以用相同的数据进行时间序列预测。
input1(时间), input2, output
nan, nan, 88
1, 0.2, 89
2, 0.5, 87
3, 0.7, 88
4, 0.4, 90
5, 1.0, y_pred
这引出了我的问题
在什么情况下,我将数据视为监督学习问题,在什么情况下视为时间序列问题?
将监督学习问题改变为时间序列问题是否是一个有希望的解决方案?
这样做的好处和坏处是什么?
因为我的回归输出是随时间变化的。
是否有通用规则,何时使用哪种框架(监督或时间序列)来解决问题?
我希望我更清楚地陈述了我的问题。
提前非常感谢你的帮助!
诚挚的 Samuel
我大部分理解你的第一种情况,但时间不会是输入,它会被移除并假定。我不理解你的第二种情况。
我认为它将是
对你的特定数据哪种最好,我一无所知。尝试一系列不同的框架(包括更多或更少的滞后观测值),看看哪些模型在你的问题上能提供最好的技能。这才是唯一需要考虑的权衡。
非常有帮助,谢谢!
很高兴听到这个消息。
Jason
感谢您花费大量时间和精力分享您在深度学习、神经网络等方面的知识。做得好。
我修改了你的 series_to_supervised 函数,可能对其他新手有用
(1)返回的列名基于原始数据
(2)始终包含当前周期的数据,以便前导和滞后周期计数可以为 0。
(3)selLag 和 selFut 参数可以限制要移位的列的子集。
在此列表的底部有一个简单的测试代码集。
Michael,太棒了,感谢分享!
非常有帮助,谢谢!
@ Michael 感谢分享您对 Jason 函数的扩展版本。但是我发现了一个小限制,因为实际值位于结果的第一列,即列的最终顺序看起来像
values values(t-N) […] values(t-1) values(t+1) […] values(t+M)
在 Jason 的版本中,您可以轻松地选择前 N 列作为输入特征(例如,在此处:https://machinelearning.org.cn/multi-step-time-series-forecasting-long-short-term-memory-networks-python/),其他列作为目标(包括实际值)。但是,使用您的代码,以下列被选为输入
values values(t-N) […] values(t-2)
以及作为目标
values(t-1) values[t+1] […] values(t+M)。
解决方案:将第 26-28 行移动到两个 for 循环之间,即移动到第 41 行。
当我进行预测时,比如说只向前预测一步,作为第一个输入值,我应该使用任何属于验证数据的值(以便设置预测的初始状态)。在第二个、第三个及后续的预测步骤中,我应该使用预测的先前输出作为神经网络的输入。我的理解正确吗?
我想是的。
好的,那么另一个问题。在这篇博文:https://machinelearning.org.cn/time-series-forecasting-long-short-term-memory-network-python/ 中,您将测试值用作神经网络的输入。预测值仅被保存到列表中,并未用于进一步预测时间序列的值。
我的问题是。是否有可能仅通过第一个值来预测一系列值?
例如。我训练了一个网络来预测正弦波的值。是否可以从值零开始预测正弦波的下一个 N 个值,并将预测结果馈送到神经网络以预测 t + 1、t + 2 等?
如果我上面理解错误,那么这意味着,如果您的测试值与用于训练网络的值完全不同,我们将得到更糟糕的预测。
是的。递归模型中的糟糕预测会导致后续预测更糟糕。
理想情况下,您希望将实际值作为输入。
是的,这称为多步预测。这是一个例子
https://machinelearning.org.cn/multi-step-time-series-forecasting-long-short-term-memory-networks-python/
这是否意味着在使用多步预测(假设我将预测 4 个值)时,我可以通过仅提供初始步骤(例如,仅提供时间序列的前两个值)来预测包含 100 个样本的时间序列?
是的,但我预计效果会很差——从如此少的信息预测如此多的时间步长是一个非常困难的问题。
您好,布朗利先生,
感谢您提供的所有精彩教程。它们真的很有帮助!
我有两个关于用于多步预测的 LSTM 的输入数据的问题。
1. 如果我有多个特征用于预测,并且在某个点(t)我没有任何新值。我是否必须预测所有输入特征才能进行多步预测?
2. 如果我的部分输入数据是二进制数据而不是连续数据,我仍然可以用同一个 LSTM 预测它吗?还是我需要单独进行分类?
抱歉,这可能非常基础,我是 LSTM 的新手。
此致 丽兹
不,您可以使用任何您选择的输入。
当然,您可以使用二进制输入。
感谢您的快速答复。
不幸的是,我在实现方面仍然遇到一些麻烦。
如果我使用 feature_1 和 feature_2 作为 LSTM 的输入,但只预测时间 (t+1) 的 feature_1,那么下一步我如何知道时间 (t+2) 的 feature_1 呢?
不知何故,我似乎在这个方法中缺少时间 (t+1) 的 feature_2。
你能告诉我哪里出了问题吗?
此致 丽兹
也许仔细检查一下您的输入数据是否完整?
你好,谢谢你的文章,我学到了很多。
现在我有一个关于它的问题。
该方法可以理解为使用之前的值来预测下一个值。如果我需要预测 t+1,…t+N 时刻的值,是否需要先使用模型预测 t+1 时刻的值,然后用该值预测 t+2,然后……直到 t+N?
或者你有什么其他方法?
你好,
我正在处理能源消耗数据,并且我有同样的问题。您是否找到了预测 t+1、t+2、t+3 + …… t+N 值的高效方法?
布朗利博士你好,
我计划购买您的《时间序列预测入门》一书。我想知道您是否涵盖了多元和多步 LSTM。
不,只有单变量。
嗨,Jason,
感谢这篇文章。我有一个关于回溯 n 个周期以选择特征的问题。如果我有一个特征并基于某个滞后时间创建了例如 5 个新特征,我的新特征之间高度相关(在 0.7 到 0.95 之间)。我的模型产生了 1 的训练得分和 0.99 的测试得分。我担心所有滞后特征之间的多重共线性导致我的模型过拟合。这是一个合理的问题吗?如果是,我该如何解决?谢谢!
尝试移除相关的特征,训练一个新模型并比较模型技能。
亲爱的Jason
衷心感谢您所做的一切。当我开始 ML 之旅时,您的博客非常有帮助。
我为我正在处理的一个时间序列问题阅读了这篇博文。虽然我很喜欢“series_to_supervised”函数,但我通常在使用 ML 时使用数据框来存储和检索数据。因此,我认为我会修改代码,使其能够接收一个数据框并返回一个仅添加了新列的数据框。请看看我修改后的代码。
用法
请看看并告诉我。希望这对其他人有帮助,
Ram
Ram,非常酷,感谢分享!
非常感谢Ram!你真是救星
亲爱的 Jason,
一如既往的精彩文章!
我可以问个问题吗?
一旦使用上述代码准备好时间序列数据(例如用于多步单变量预测),它是否已准备好(并处于3D结构中)用于馈入LSTM RNN的第一隐藏层?
也许是愚蠢的问题!
提前非常感谢。
Marius。
这真的取决于你的数据和你如何构建问题。
输出将是2D的,你可能仍然需要将其转换为3D。请参阅这篇文章
https://machinelearning.org.cn/prepare-univariate-time-series-data-long-short-term-memory-networks/
还有这篇文章
https://machinelearning.org.cn/reshape-input-data-long-short-term-memory-networks-keras/
Jason,感谢这篇文章。它足够简单易懂。但是,在转换我的时间序列数据后,我发现一些特征值来自未来,在尝试进行预测时将不可用。你建议我如何解决这个问题?
也许删除那些特征?
我的数据集是这样的
accno dateofvisit
12345 12/05/15 9:00:00
123345 13/06/15 13:00:00
12345 12/05/15 13:00:00
我将如何预测该客户何时会再次访问?
您可以从这里开始学习时间序列预测:
https://machinelearning.org.cn/start-here/#timeseries
你好,
我需要开发一个输入向量,它使用时间t之前的每30分钟,例如
输入向量为 (t-30,t-60,t-90,…,t-240) 来预测 t。
如果我想使用你的函数来完成我的任务,将shift函数更改为df.shift(3*i) 是否正确?
谢谢
一种方法可能是转换后选择性地检索/删除列。
你好,
所以我应该采取这些步骤
1- 转换不同的滞后值
2-选择与第一个滞后值相关的列(例如,30分钟)
3-转换其他滞后值
4-沿轴=1连接
当我执行这些步骤时,结果似乎与按3移位相同?
我有一些问题
哪种方法更好?(按3移位或执行上述步骤)
我是否应该在每次转换后删除时间 t,只保留最后一个滞后值的时间 t?
谢谢
使用一种你认为对你的问题最有意义的方法。
嗨,Jason,
创建监督序列的精彩文章。但我有一个疑问,
假设我想通过每日销售历史数据预测未来14天的销售额。这是否需要我计算14个滞后值来预测未来14天?
例如:(t-14, t-13……t-1) 预测 (t,t+1,t+2,t+14)
不,输入/输出观测值是分开的。如果你真的想,你可以有一个输入和14个输出。
感谢Jason的快速回复!
仍然感到困惑。
请更详细地谈谈。
例如,现在是t时刻,想预测t+5,作为一个例子,
我们需要先有t+1,t+2,t+3,t+4的数据吗?
谢谢,Jason
是的。
嗨,Jason,
我想预测下一个值会比前一个值高还是低。我能用同样的方法将其构建为一个分类问题吗?
例如
V(t) 类
0.2 0
0.3 1
0.1 0
0.5 0
2.0 1
1.5 0
其中类零表示下降,类1表示上升?
谢谢,
Sanketh
当然可以。
Jason,你的博客中有非常好的解释。当我得到一个移位数据框的形状,例如(180,20)时,我如何将其恢复到原始数据形状(200,1)?
你将不得不编写自定义代码来反转变换。
嗨,Jason,
精彩的文章。
我有一个问题,假设我想将窗口移动24步而不是只移动一步,在这种情况下我需要做哪些修改?
例如,我有每小时一次的能源数据,我想预测未来24小时(1天),看过去21天(504小时),那么对于下一次预测,我想将窗口移动24小时(1天)。
也许重新阅读函数的描述,以了解要提供给函数的参数。
对这样指定的数据进行盲目拟合的模型肯定会过拟合。
假设你使用交叉验证程序来估计模型性能,并且你有几个折
Fold1 (一月)
Fold2 (二月)
Fold3 (三月)
Fold4 (四月)
考虑拟合在fold 1、2和4上的模型。现在你基于四月份某个特征的值来预测三月份的该特征!
如果你选择使用像这样的滞后回归量矩阵,请务必研究适当的模型验证。
一个很好的理由是Hyndman的教科书,可以在网上免费获得:https://otexts.org/fpp2/accuracy.html
确实,对于时间序列,永远不应该使用交叉验证。
相反,应该使用前向验证
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
Jason,非常好的博客,我从你那里学到了很多。我实现了一个带有滑动窗口的LSTM编码器-解码器。预测结果与输入几乎相同,这在使用滑动窗口时是否常见?我有点惊讶,因为模型在训练中只看到了很少一部分数据,而之后模型预测的结果几乎与输入相同。这让我怀疑我可能错了。我不想发布代码,这只是标准的LSTM编码器-解码器代码,但模型在训练中只看到很少一部分数据这一事实让我感到困惑。
这听起来像是模型学习了持久性预测,这可能表明需要进一步的调优。我在这里概述了更多内容
https://machinelearning.org.cn/faq/single-faq/why-is-my-forecasted-time-series-right-behind-the-actual-time-series
你好Jason,你的代码非常好,但我的问题是,我改变了窗口大小(reframed = series_to_supervised(scaled, 1, 1) 为 reframed = series_to_supervised(scaled, 2, 1)),然后我的预测变差了,我该如何解决或是什么原因?
请看看我修改后的代码。
from math import sqrt
from numpy import concatenate
from matplotlib import pyplot
from pandas import read_csv
from pandas import DataFrame
from pandas import concat
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_squared_error
来自 keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
# 将序列转换为监督学习
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()
# 输入序列 (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)]
# 预测序列 (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)]
# 将它们放在一起
agg = concat(cols, axis=1)
agg.columns = names
# 删除包含NaN值的行
if dropnan
agg.dropna(inplace=True)
return agg
# 加载数据集
dataset = read_csv(‘pollution.csv’, header=0, index_col=0)
values = dataset.values
# 整型编码方向
encoder = LabelEncoder()
values[:,4] = encoder.fit_transform(values[:,4])
# 确保所有数据都是浮点型
values = values.astype('float32')
# 归一化特征
scaler = MinMaxScaler(feature_range=(0, 1))
scaled = scaler.fit_transform(values)
# 构架为监督学习
reframed = series_to_supervised(scaled, 2, 1)
# 删除我们不想预测的列
reframed.drop(reframed.columns[[9,10,11,12,13,14,15]], axis=1, inplace=True)
print(reframed.head())
# 拆分为训练集和测试集
values = reframed.values
n_train_hours = 365*24
train = values[:n_train_hours, :]
test = values[n_train_hours:, :]
# 分割输入和输出
train_X, train_y = train[:, :-1], train[:, -1]
test_X, test_y = test[:, :-1], test[:, -1]
# 将输入重塑为 3D [样本, 时间步, 特征]
train_X = train_X.reshape((train_X.shape[0], 1, train_X.shape[1]))
test_X = test_X.reshape((test_X.shape[0], 1, test_X.shape[1]))
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
# 设计网络
model = Sequential()
model.add(LSTM(50, input_shape=(train_X.shape[1], train_X.shape[2])))
model.add(Dense(1))
model.compile(loss='mae', optimizer='adam')
# 拟合网络
history = model.fit(train_X, train_y, epochs=50, batch_size=72, validation_data=(test_X, test_y), verbose=2, shuffle=False)
# 绘制历史记录
pyplot.plot(history.history[‘loss’], label=’训练’)
pyplot.plot(history.history[‘val_loss’], label=’测试’)
pyplot.legend()
pyplot.show()
# 进行预测
yhat = model.predict(test_X)
test_X = test_X.reshape((test_X.shape[0], test_X.shape[2]))
# 反向缩放以进行预测
inv_yhat = concatenate((yhat, test_X[:, 1:8]), axis=1)
inv_yhat = scaler.inverse_transform(inv_yhat)
inv_yhat = inv_yhat[:,0]
# 反向缩放以获得实际值
inv_y = scaler.inverse_transform(test_X[:,:8])
inv_y = inv_y[:,0]
# 计算 RMSE
rmse = sqrt(mean_squared_error(inv_y, inv_yhat))
print('Test RMSE: %.3f' % rmse)
# 绘制预测值和实际值
pyplot.plot(inv_yhat[:100], label=’prediction’)
pyplot.plot(inv_y[:100], label=’actual’)
pyplot.legend()
pyplot.show()
模型可能需要进一步调整以适应问题变化。
我注意到你的代码考虑了最后一个时间点对当前时间点的影响。但这在许多情况下不适用。有什么优化思路?
大多数方法都假定t时刻的观测值是先前时间步(t-1, t-2, …)的函数。你为什么认为情况并非如此?
哦,也许我没有把我的问题说清楚,我的问题是为什么只考虑t-1,当考虑(t-1,t-2,t-3)时,你给出的例子表现很差。
没有好理由,只是演示。你可以修改模型以包含你想要的任何一组特征。
尊敬的先生
我有70个输入时间序列。我只需要预测输入(70个特征)时间序列中的1、2或3个。我的问题是。
->我应该为这样的问题使用LSTM吗?
->我应该预测所有70个时间序列吗?
->如果不是LSTM,我应该使用什么方法?
(外汇交易预测问题)
很好的问题!
- 尝试一系列方法,看看哪种有效。
- 尝试不同数量的历史数据和不同数量的前瞻时间步,找到适合你项目目标的最佳点。
- 尝试经典的时间序列方法、机器学习方法和深度学习方法。
Jason,我有很多数据,数据时间序列之间的时间步很小,直到最后几个周期它们几乎没有变化。我考虑也许不仅仅是移位1,我如何移位更多,例如t-1和t移位20步。这有意义吗?
我不确定我是否理解,抱歉。也许给个小例子?
假设我有这些数据
5
6
7
8
9
10
11
12
并且通常如果你制作滑动窗口,它们会从t-2移位1到t
5 6 7
6 7 8
7 8 9
8 9 10
9 10 11
10 11 12
11 12
12
我如何才能做到不移位1,而是移位3,例如查看第一行(本例中)或更多从t-2到t?
5 8 11
6 9 12
7 10
8 11
9 12
10
11
12
我问这个是因为我的数据范围太小,移位1并没有多大效果,我想也许这样的东西会有帮助。我需要如何调整你的监督学习代码来实现这一点?你认为这是一个好主意吗?
向函数指定滞后(n_in)为3。
嗨,Jason!
应用此函数到我的数据后,我该如何最好地分割训练和测试集?
正常情况下,我会使用sklearn的train_test_split,它可以随机打乱数据并根据用户设定的比例进行分割。但是,直觉告诉我这是不正确的,我需要根据shift()的程度来分割数据。你能澄清一下吗?
最好的方法取决于你的具体预测问题和你的项目目标。
这篇文章提供了一些关于如何在时间序列问题上评估模型的建议
https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/
当我给函数一个20的滑动窗口 series_to_supervised(values, 20) 时,我的新数据形状是(None,21),None是可变的。为什么我会得到21?我需要删除最后一列吗?或者我该如何进行?非常感谢你的文章。
我猜是20个输入,1个输出。
通过打印返回的数据框的head()来确认这一点。
为什么我们需要将它转换为监督学习以用于LSTM问题?
因为LSTM是一种监督学习算法。
Jason,我喜欢这些文章。非常感谢。
我看到你有多输入时间序列来预测输出时间序列。
我有一个不同的输入特征设置,并试图弄清楚如何实现它们并使用RNN来预测输出时间序列。
假设我有7个输入特征,feature1到feature7,其中feature1是一个时间序列。
feature2到feature5是标量值,feature6和feature7是标量向量。
问题的另一种描述方式是,对于feature2到feature5的给定单个值(例如,2,500、7Mhz、10000),以及feature6和feature7的给定值范围(例如,feature6是数组[2,6,40,12……,100],feature7是数组[200,250,700,900,800……,12]。然后,我需要从时间序列输入feature1预测时间序列输出。
我如何为RNN设计所有这7个特征输入?
如果你有涵盖这方面的书,请告诉我。谢谢。
如果你有一个序列和一个模式作为输入(是这样吗?),你可以有一个模型,其中一个RNN用于序列,另一个输入用于模式,例如一个多头模型。
或者,你可以将模式作为输入,与序列数据一起,在序列的每个时间步提供。
尝试这两种方法,也许还有其他方法,看看哪种最适合你的问题。
感谢Jason的这篇文章,非常有帮助。
如果对其他人有帮助,我修改了该函数,用于处理整个数据框的时间序列数据,以供多元数据使用,当数据框包含多个时间序列数据列时,[可在此处找到](https://gist.github.com/monocongo/6e0df19c9dd845f3f465a9a6ccfcef37)。
谢谢,詹姆斯。
嗨,Jason,
这篇文章对我开始LSTM预测之旅非常有帮助。结合你其他几篇文章,我能够创建一个多元多时间步LSTM模型。关于你文章本身的看法:你使用了非常复杂的数据结构(我认为我很快就得到了数组的数组和单个值),而更简单的数据结构就可以完成工作并且更容易适应。总的来说,这是一篇非常好的教程,有助于理解我项目的基本原理。
谢谢,詹姆斯。
你有什么更简单的建议吗?
喜欢并感谢这篇文章——它在我的硕士工作初期对我帮助很大。我还有很多工作和学习要做,但这个教程以及“使用Keras进行多元时间序列预测”帮助我理解了Keras和数据准备的基础。继续加油:)
谢谢,很高兴听到这个。
嗨,Jason,
感谢你为我们所有人付出的所有博客的努力。
我想分享一个更简单的series_to_supervised函数的贡献。我认为它只在Python 3中工作。
太棒了,谢谢分享!
嗨,Jason,
感谢你的文章。我的问题是:对于分类问题,使用相同的方法来重构数据是否可以?
祝好
徐
是的。
嗨,Jason,
您的网站总是非常有帮助!我在这里有点困惑。如果我的时间序列数据集中已经包含一些输入变量(VarIn_1到VarIn_3)和相应的输出值(Out_1和Out_2),那么在拟合我的LSTM模型之前,我是否仍然需要将数据集通过series_to_supervised()函数运行?
示例数据集
Time Win, VarIn_1, VarIn_2, VarIn_3, Out_1, Out_2
1, 5, 3, 7, 2, 3
2, 6, 2, 4, 3, 1
3, 4, 4, 6, 1, 4
…, …, …, …, …, …,
祝好,
Carl
可能不需要。
亲爱的 Jason,
非常感谢您的辛勤付出。
我正在尝试使用h2o软件包在R中进行超前一天预测。下面是glm模型。
glm_model <- glm(RealPtot ~ ., data= c(input3, target), family=gaussian)
然后我计算每天的MAPE,方法是
mape_calc <- function(sub_df) {
pred <- predict.glm(glm_model, sub_df)
actual <- sub_df$Real_data
mape <- 100 * mean(abs((actual – pred)/actual))
new_df <- data.frame(date = sub_df$date[[1]], mape = mape)
return(new_df)
}
# ONE-ROW DATAFRAMES 的列表
df_list <- by(test_data, test_data$date, mape_calc)
# 最终 DATAFRAME
final_df <- do.call(rbind, df_list)
我正在尝试在h2o环境中使用h2o实现上述代码,但在数据转换方面遇到了一些困难。任何想法都将不胜感激。预先感谢。
抱歉,我对h2o没有经验,也许可以联系他们的支持部门?
Jason,您的文章很棒。我不介意代码重复,这确实解决了新手可能遇到的问题。响应部分也很有帮助。谢谢!
谢谢。
我想知道你是如何处理日期的。我尝试使用您的方法对时间序列进行预测。但是,我的日期作为索引。
删除包含日期的列。您可以在代码中直接执行此操作,也可以在数据文件中直接执行(例如,通过Excel)。
你好 Jason,
好帖子,我有一个关于此情况下的训练/测试集分割的问题
例如,我现在将80%的行作为训练数据,其余作为测试数据。
这是否会被视为数据泄露,因为训练集中的最后两个样本包含测试集的目标值(t、t+1的值)?
不。
嗨,Jason,
感谢您的回复,但为什么呢?
也许我没有说清楚,但我在Medium上的一篇文章中找到了我想说的内容
https://medium.com/apteo/avoid-time-loops-with-cross-validation-aa595318543e
请看他们的第二个可视化图,他们称之为“前瞻间隔”,它排除了训练集中最后一个预测步骤的真实数据(ground truth data)来自测试集。
您对此有什么看法?这是否是常见的做法?
我见过许多许多论文使用交叉验证来报告时间序列结果,而这些结果几乎总是无效的。
您可以使用交叉验证,但要非常小心。如果结果真的重要,请使用前向验证。您不会搞砸的。
这就像写代码,您可以使用“goto”,但不要这样做。
他们也反对传统的交叉验证,他们实际上使用了前向验证(我认为他们对“前向交叉验证”一词的使用有点误导)。
所以是的,我绝对在使用前向验证!
我将用一个简化的例子来说明我的问题
如果我们有这个时间序列
[1, 3, 4, 5, 6, 1]
我将数据分成训练集
[1, 3, 4, 5]
…和测试集
[ 6, 1]
我将在将其转换为监督问题之前执行此操作。
所以,如果我现在进行到监督问题的转换,我的训练集将变成这样
t | t+1
1 | 3
3 | 4
4 | 5
5 | NaN
对于第四行,我没有t+1的值,因为它不属于训练集。如果我在这里使用测试集中的值6,我就会包含测试集的信息。
所以在这里,我只会训练到第三行,因为那是最后一个完整条目。
对于测试,我将使用这个训练好的模型来预测值6之后的t+1。
这就产生了一个缺口,因为在这次迭代中我将不会得到第四行的预测(“前瞻间隔”?)。
如果我在分割之前将序列转换为监督问题,这个问题(它是一个问题吗?)就不那么明显了,但在这种情况下,我会删除训练集的最后一行,因为它包含我测试集中的第一个值作为目标。
那么,我可以先转换再分割,还是需要先分割再转换,就像在例子中一样?
根本问题是,在后续时间步的预测性能上,是否“看到”或“没有看到”后续时间步的值会产生影响?
听起来你被绕晕了。
请记住这一点:您希望以您打算使用模型的方式来测试模型。
如果数据在需要预测之前对模型是可用的,模型应该/必须利用这些数据来做出最好的预测。这是前向验证的前提。
训练/测试数据方面的担忧仅在单个预测及其评估点才有意义。在先前的预测中“看到”测试集数据并不是数据泄露,除非您不期望以这种方式使用模型。在这种情况下,请将前向验证的配置从一步更改为两步或其他。
这有帮助吗?
我被绕晕了,思考在进行预测时哪些数据可用会很有帮助。
我的问题是我正在进行直接的3步预测,所以每次进一步预测之前都有三个“死”行,因为我需要3个未来值才能构成一个完整的训练样本(它们并非真的死,因为我在t时使用t+1、t+2和t+3作为条目)。
感谢您的耐心!
是的,它们不是死的/空的。
在进行预测时,它们将有实际的先前观测值。因此,请在这种假设下训练和评估您的模型。
我真心非常感谢您的信息。做得好!!!!我也希望您以后能发布更多文章。
我从这两篇文章中理解了概念
Convert-time-series-supervised-learning-problem-python 和 Time-series-forecasting-supervised-learning。
我现在想预测并根据经纬度或Geohash值设置布尔值(TRUE或False),对于这个,我该如何进行多变量预测?
我完全是这个领域的新手,请给我一些建议,我会照着做。
预先感谢。我正在我的Mac mini上使用Python3进行此操作。
听起来像是一个时间序列分类任务。
嗨,Jason,
如何在多变量时间序列中仅对变量1应用滞后?换句话说,我有5个变量,但只想滞后变量1?
一种方法是将一个变量的滞后观测值作为机器学习模型的特征。
另一种方法是采用多头模型,一个用于时间序列,一个用于静态变量。
嗨
我猜上面代码示例中的所有后续行
n_vars = 1 if type(data) is list else data.shape[1]
应该重写为
n_vars = 1 if type(data) is list else data.shape[0]
好的,我明白了,实际上它就是它本来的样子,所以是data.shape[0],但如果你传入一个numpy数组,那么秩应该是2而不是1。
所以这个不行(程序会崩溃)
values = array([x for x in range(10)])
但是这个可以
values = array([x for x in range(10)]).reshape([10, 1])
抱歉造成困扰。
不,shape[1]指的是二维数组中的列。
单步单变量预测问题:将t-1作为输入变量来预测当前时间步(t)。
如果我们不知道t-1,我们就无法预测当前时间步(t)。
例如1. 1,2,3,4,5,6,没有7,如何预测9?
随机缺失值
例如2.1,3,4,6,没有2和5,如何预测7?
谢谢
处理缺失值有很多方法,这也许会有帮助。
https://machinelearning.org.cn/handle-missing-timesteps-sequence-prediction-problems-python/
Jason,
在他的例子中,1,3,4,6。假设这是每日销量数据。例如,1/3日售出1件,1/2日商店关闭,1/3日售出3件,以此类推。我们是否应该将1/2日视为缺失值?还是忽略它?
1/2日,商店因公共假日关闭。
请指教
Jon
尝试忽略它,然后尝试插补缺失值,并比较由此产生的模型的技能。
你好,Jason。
我有一个关于多变量多步预测的问题。例如,另一个空气污染预测(不是您教程中展示的),总共有9个特征。我希望输出只是空气污染。
train_X 和 test_X 是:'var1(t-3)', 'var2(t-3)', 'var3(t-3)', 'var4(t-3)', 'var5(t-3)',
'var6(t-3)', 'var7(t-3)', 'var8(t-3)', 'var9(t-3)', 'var1(t-2)',
'var2(t-2)', 'var3(t-2)', 'var4(t-2)', 'var5(t-2)', 'var6(t-2)',
'var7(t-2)', 'var8(t-2)', 'var9(t-2)', 'var1(t-1)', 'var2(t-1)',
'var3(t-1)', 'var4(t-1)', 'var5(t-1)', 'var6(t-1)', 'var7(t-1)',
'var8(t-1)', 'var9(t-1)',
train_y 和 test_y 是:'var1(t)', 'var1(t+1)', 'var1(t+2)'(我删除了不需要的列)。
我使用minmax()进行归一化,如果输出是一步,我很容易反归一化。然而,问题是我有三个输出值。那么,您能给我一些建议吗?
关键是我使用了minmax(),我不知道如何在使用3个输出值时反归一化。您能给我一些建议吗?非常感谢!
也许可以使用该函数来找到最接近的匹配,然后修改列列表以满足您的要求。
你好!我最多是个新手,正在尝试创建一个预测模型。我不知道如何在我的数据集中处理“日期”变量。我应该直接删除它,然后添加一个行索引变量来建模吗?
丢弃日期并对数据进行建模,假设观测值之间间隔一致。
还有一件事,如何将包含t+1和t-1变量的新数据框导出到csv文件?
调用to_csv()。
你好 Jason,
您为机器学习所做的一切应该能让您获得诺贝尔和平奖。我经常参考您网站上的多篇文章,并逐渐扩展我的理解,一天比一天更知识渊博、更有信心。我学到了很多,但仍有很多需要学习。我的目标是在接下来的5个月内精通这一点,然后将机器学习应用到我脑海中的一百万个项目中。您以清晰简洁的方式实现了这一点。谢谢。
谢谢,我很高兴这些教程很有帮助!
嗨,Jason,
感谢这篇精彩的教程🙂我正在为一个学生评估系统的原型工作,该系统有过去5年的学期1和学期2的学生分数以及3个因变量。我需要预测从第二年到未来一年的学生分数。我需要您关于如何创建模型来利用过去可用的数据来预测当前分数的指导。
谢谢。
我关于开始单变量时间序列预测的最佳建议在这里。
https://machinelearning.org.cn/start-here/#timeseries
嗨,Jason,
我的数据是时间序列格式(t-1, t, t+1),其中日期(我数据中的时间分量)是按时间顺序排列的(一个接一个)。但是,在我的项目中,我需要将此数据框细分为12个子数据框(根据某些过滤标准——我按某些特定列值进行过滤),在完成过滤并得到这12个数据框后,我需要分别对每个数据框进行预测。
我的问题是:这12个数据框中每个数据框的时间分量不再是按时间顺序排列的(日期不是接连的。例如:第一行的日期是2015年10月10日,第二行的日期是2015年10月20日等等),这样可以吗?它会在以后的预测中造成问题吗?如果会,我该怎么办?
非常感谢您的帮助。预先感谢。
我不确定我是否理解,抱歉。
只要模型在拟合和进行预测时使用的输入-输出对是连续的,那应该就没问题。
你好Jason,如何更好地将数据集分割成训练集和测试集?
这取决于您的数据,特别是数据的数量和质量。也许可以尝试不同大小的分割并评估模型,看看哪个看起来稳定。
嗨,Jason,
假设我有一个分类问题。我有100个用户,他们的传感数据为60天。传感数据按天汇总。对于每个用户,我有2个特征。我正在尝试进行二元分类——我让他们在开始时选择一个数字,0或1,我试图根据他们60天的传感数据将每个用户分类到这两个类别之一。
所以我想到了可以将它转换为监督问题,正如您在以下方式中所建议的那样。
第60天特征1,第60天特征2,第59天特征1,第59天特征2……第1天特征1,第1天特征2,标签
我应该这样转换我的数据集吗?但这是否意味着我只有100个唯一的行可以用于训练?
到目前为止,我曾设想将问题结构化为这样,但我不知道我是否违反了监督学习的独立性假设。对于每个用户,我将他们每天的记录作为一行,并将他们在开始时选择的相同标签作为标签列。
例如:对于用户1
日期,特征1,特征2,标签
第1天,1,2,1
第2天,2,1,1
…………………
第60天,1,2,1
这样我将有100×60条记录用于训练。
我的问题是:我提出的第一种数据格式是正确的,而第二种格式是不正确的吗?如果是这样,那么我将只有100条记录用于训练(每个用户一条),这意味着我不能为此使用深度学习模型。在这种情况下,您能推荐哪种传统机器学习方法给我参考吗?任何帮助都将不胜感激。
非常感谢!
后者看起来更合理或更传统,但没有规则。您可以控制“样本”代表什么——例如,如何构建问题。
我强烈建议您探索问题的多种不同框架,以找出最合理或最适合您特定数据集的方法。也许可以单独为用户建模,或者不单独建模。也许可以将日期分组,或者不分组。等等。
也许这个框架会帮助集思广益。
https://machinelearning.org.cn/how-to-define-your-machine-learning-problem/
还有,也许这个。
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
你好 Jason,非常感谢这篇文章!
我有两个问题
1) 在“n_vars = 1 if type(data) is list else data.shape[1]”中,n_var不应该是列表数据集合的长度,例如“n_vars = len(transitions[0]-1) if type(transitions) is list else transitions.shape[1]”
2) 在 for i in range(0, n_out)
cols.append(df.shift(-i)) ==> 不应该是“df.shift(-i+1))”吗?
谢谢!
您为什么建议这些更改,它们具体修复了什么问题?
嗨 Jason
您的帖子很棒。它们为我理解时间序列预测节省了大量时间。非常感谢。
我已经使用您的代码测试了所有类型的时间序列预测(多步、多变量等),效果很好。但我有一个问题,就是如何从模型中获得实际预测值。
例如,在污染数据中,并尝试在精彩的帖子中进行操作
https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/
我正在寻找预测三个时间步长(t、t+1 和 t+2)的不仅仅一个,而是两个特征(观测值类型或标记为 var1(t)、var2(t)、var1(t+1)、var2(t+1)、var1(t+2)、var2(t+2))。我安排好了一切(维度和其他东西以适应我想要的结构),例如,我使用了
reframed = series_to_supervised(scaled, 3, 3)
并且我删除了与我想要预测的这两个特征无关的列(我为所有三个时间步长都这样做了)。
但是,在模型拟合之后(这也看起来很好),当我尝试命令时
yhat = model.predict(test_X)
我发现 yhat 的列数总是 1,这很奇怪,因为它应该为 6(var1(t)、var2(t)、var1(t+1)、var2(t+1)、var1(t+2)、var2(t+2) 的预测值)。
我在这里错过了什么吗?
调用 predict() 的一个样本的输入形状必须与训练模型时的输入形状相匹配。
这意味着,时间步长和特征的数量相同。
也许这会有帮助。
https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/
感谢您的回复,Jason。
它与预期形状匹配,实际上是拟合模型时用于验证的 same test_X。
重构后的数据看起来像这样
var1(t-3) var2(t-3) var3(t-3) var4(t-3) var5(t-3) var6(t-3) \
3 0.129779 0.352941 0.245902 0.527273 0.666667 0.002290
4 0.148893 0.367647 0.245902 0.527273 0.666667 0.003811
5 0.159960 0.426471 0.229508 0.545454 0.666667 0.005332
6 0.182093 0.485294 0.229508 0.563637 0.666667 0.008391
7 0.138833 0.485294 0.229508 0.563637 0.666667 0.009912
var7(t-3) var8(t-3) var1(t-2) var2(t-2) … var5(t-1) \
3 0.000000 0.0 0.148893 0.367647 … 0.666667
4 0.000000 0.0 0.159960 0.426471 … 0.666667
5 0.000000 0.0 0.182093 0.485294 … 0.666667
6 0.037037 0.0 0.138833 0.485294 … 0.666667
7 0.074074 0.0 0.109658 0.485294 … 0.666667
var6(t-1) var7(t-1) var8(t-1) var1(t) var2(t) var1(t+1) var2(t+1) \
3 0.005332 0.000000 0.0 0.182093 0.485294 0.138833 0.485294
4 0.008391 0.037037 0.0 0.138833 0.485294 0.109658 0.485294
5 0.009912 0.074074 0.0 0.109658 0.485294 0.105634 0.485294
6 0.011433 0.111111 0.0 0.105634 0.485294 0.124748 0.485294
7 0.014492 0.148148 0.0 0.124748 0.485294 0.120724 0.470588
var1(t+2) var2(t+2)
3 0.109658 0.485294
4 0.105634 0.485294
5 0.124748 0.485294
6 0.120724 0.470588
7 0.132797 0.485294
[5 行 x 30 列]
所以,在拟合模型之前,训练和测试数据的形状是这样的
print(train_X.shape, train_y.shape, test_X.shape, test_y.shape)
(8760, 1, 24) (8760,) (35035, 1, 24) (35035,)
并且在拟合模型后,我调用 test_X,其形状为 (35035, 1, 24) 进行预测,但它仍然给我 yhat,形状为 (35035, 1)。
是什么问题?
我刚意识到第二个维度(8760, 1, 24)和(35035, 1, 24)应该设置为 3。但这样做并重新拟合模型并没有改变 yhat 的维度。
不,正是如此。输入形状和输出形状不相关。
是因为密集层吗?因为也许最后的 dense(1) 层会返回维度 1?
然而,如果我将密集层中的这个 1 更改为例如 3,我会遇到维度不匹配的错误。我现在很困惑,并且进行了大量搜索但都没有成功
正确。
如果将模型更改为预测每个样本 3 个值,则必须将训练数据更改为 y 中每个样本包含 3 个值。
这表明每个输入样本有一个输出值,这正是你的模型设计方式。
也许我没理解你的意图?
我明白了,Jason。这是因为密集层,我不得不将其设置为 dense(6),并且在训练和测试数据的形状方面也进行了一些修改。
再次感谢
很高兴听到这个消息。
你好,
如何将图像序列引入预测问题?
谢谢
也许使用 CNN-LSTM 类型模型?
更多信息在这里
https://machinelearning.org.cn/cnn-long-short-term-memory-networks/
你好,我的问题是如何对时间序列进行分类。
我有一系列用户事件,这些事件发生在不同的时间间隔,我想根据用户产生的事件对其进行分类。如何将数据传递给 LSTM?
如何将数据传递给 LSTM?
我有一个很好的时间序列分类示例,请参阅关于“人类活动识别”的教程。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
嗨,Jason,
对于一个建模问题,我有许多时间序列(在这种情况下,每个患者一个),但测量不是以固定的时间间隔进行的。事实上,有很多并发的时间序列,都有不同的、变化的采样时间。数据有时非常稀疏(数天没有测量),有时非常密集(一小时内许多测量),所以我不想通过插值来丢失信息。
我想在一部分患者上训练一个模型,并用它来预测其他患者。您建议如何格式化数据?
我建议测试一系列不同的问题建模方法。
例如,尝试标准化区间,尝试零填充,尝试持久填充,尝试忽略区间,尝试将历史限制在固定窗口,尝试仅对固定窗口进行建模,等等。看看什么可以学习/有用。
我正在尝试绘制最终结果的折线图,但我得到的是条形图。
CODE
# 绘制历史记录
plt.plot(inv_yhat, label=’forecast’)
plt.plot(inv_y,label=’actual’)
plt.legend()
plt.show()
也许确认数据是浮点数数组?
对于你的函数“series_to_supervised”,我喜欢 dropna 的功能,但我可以想象用户可能不希望删除数据集中恰好是 NaNs 的中间行。相反,他们可能只想删除开头和结尾的一些行。
是的,最好控制数据准备过程并针对你的数据集进行专门化。
有什么简单的方法可以将这个转换为 Keras LSTM 所需的输入?我认为我们会使用多索引。
这可能有帮助
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
谢谢 Jason,我明白它应该是什么样子,但从你的 series_to_supervised 函数到这些三维张量的过程确实非常棘手,需要比我更多的 pandas 多索引、数据透视表知识 🙂
一旦有了二维矩阵,就可以直接用 reshape() 调用对其进行重塑。
我有一个解决方案,它有点丑陋,但它有效!
很高兴听到这个消息。
嗨,Jason,
感谢您精彩的教程。
我有一个关于你的函数“series_to_supervised”的疑问……在我的例子中,我有一个速度数据的时序,还有一个“datetime”信息的额外列,交通测量就是在这个时间进行的。
我想在你的函数中保留“datetime”作为输入特征,但又不为它添加滞后变量。有什么办法可以解决吗?
此致
你可能需要编写一些自定义代码,这需要一些设计/试错/和单元测试。
你好 Jason,
感谢您的帖子。我有一个关于分类任务的问题。假设我们采用这种 series_to_supervised 方法。但在那种情况下,我们的目标是预测时间“t”的原始值,对吧?如果目标是二元的,比如?谢谢。
我还想补充一点,如果采用这种方法,那么我们的原始目标函数包含 0/1 类,其样本数将比转换后的数据框多(由于 dropNAN 命令)。
听起来你在描述时间序列分类。
我这里有一个例子,可能会有所帮助,作为起点。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
好吧,虽然我同意你的看法,这只是一个分类问题(请看我的第一个帖子),但如果需要提前预测一个类别(0/1),这就会变成一个预测问题,对吧?
我之前浏览了链接的 URL,如果我没记错的话,你有几个时间序列分类的例子,但没有“让我们尝试预测未来 1 天的 Class 0”之类的例子。
是的,无论是为当前时间步长还是未来时间步长进行分类,这只是一个建模问题——例如,差异很小。
你到底遇到了什么问题?
我的问题如下。我们有一个与每个时间步长关联的目标集。例如
X y
0.2 0
0.5 1
0.7 1
0.8 0
我们进行一次移位,然后得到
X (t-1) X(t) y
NAN (或 0) 0.2 0
0.2 0.5 1
0.5 0.7 1
0.7 0.8 0
对吗?
那么,我的问题是:如果我使用 X(t-1) 作为输入,我的目标样本将大于 X(t-1)。那么在这种情况下,我该如何将我的滞后时间步长(X(t-1)、X(t-2)等)与我的类别关联/连接起来?
每一行连接输入和输出。
所以,我猜正确的方法是也对我的目标类别应用 series_to_supervised,并使用 y (t) 作为目标变量,而 y (t-1)、y (t-2)、…、y(t-k) 将作为我的输入,以及 X(t-1)、X(t-2)、…、X(t-k)。
我的方法听起来正确吗?谢谢。
也许可以尝试一下,看看它是否可行。
嗨 Emin,我正在处理一个类似的问题。我有一个每日时间序列,对于每一天,我都有一个标签(0,1),我想使用 LSTM 来预测第二天的标签。你是否解决了如何转换输入变量的问题?如果你解决了,能否就这个问题提供一些见解?
提前感谢!
顺便说一下,它会更大,因为在某些情况下(至少在我的情况下),添加 0 是不正确的,因为 0 代表与领域相关的其他内容。所以,如果我们有 NAN 并删除它们,我们的输入将是 (3,) 的大小,而我们的目标将是 (4,) 的大小。
是的,当我们移位时,我们会丢失观测值。
Jason,我还有一个问题。在将问题建模为滞后时,我们的时间序列必须是降序排列的,对吧?那么,上午 11:00(第 1 行),上午 0:00(第 2 行)。在这种情况下,当我们向下移位 1 时,我们基本上是在尝试预测原始值在时间 t 的值。
用例子演示
中午 12:00 0.5
上午 11:00 1.2
上午 10:00 0.3
应用移位后,lag_step=1 =>
中午 12:00 NaN
上午 11:00 0.5
上午 10:00 1.2
上午 9:00 0.3
通过这样做,我们基本上将所有值移到过去,并尝试预测,以最小化在原始时间 (t) 的实际观测值与同一原始时间 (t) 的模型值之间的误差。
不幸的是,到目前为止我找到的所有示例都以升序建模时间
http://www.spiderfinancial.com/support/documentation/numxl/reference-manual/transform/lag
如果你能澄清一下,那就太好了。
谢谢你。
是的,数据必须在时间序列中按时间顺序排列。
通常是升序,从最早到最新的时间。
那么,在这种情况下,如果我们以 (t-1) 作为我们的输入,我们难道不会面临数据泄露的问题吗?我们正在将数据推迟一个时间步,这实际上意味着我们将数据推迟到未来的时间。
不。这取决于你如何定义问题——你测试什么以及如何测试。
Jason,
如果我们使用这种方法,我们是否仍然需要担心去除趋势和季节性?
这取决于使用的模型。
通常,在转换之前去除趋势和季节性可以使问题更容易建模。
你好,
我尝试了这段简单的代码来做你书中的例子。我今天才刚开始读它。
x = []
y=[]
d = np.arange(12)
for i in range(len(d))
if i+3 <=11
x.append(d[i:i+3])
y.append(d[i+3])
print(x)
print(y)
a
结果
x = [array([0, 1, 2]), array([1, 2, 3]), array([2, 3, 4]), array([3, 4, 5]), array([4, 5, 6]), array([5, 6, 7]), array([6, 7, 8]), array([7, 8, 9]), array([ 8, 9, 10])]
y= [3, 4, 5, 6, 7, 8, 9, 10, 11]
干得好!
谢谢 Jason。我真的很喜欢这个教程。
不客气,我很高兴它有所帮助。
嗨,Jason,
感谢这篇有趣的论文。
我正在处理单变量预测,但有多个观测值。这里没有这种情况,也不知道如何将其转换为 TimeSeriesGenerator。
假设我有一个 100 个观测值的序列,并且我想训练一个 RNN 来预测 50 个观测值之后的下一个观测值。这很容易用 TimeSeriesGenerator 完成。
但是现在,如果我有 1000 个这样的 100 个观测值的序列呢?连接它们是没有用的,因为观测值 101 与观测值 99 没有关系。我仍然可以在这种情况下使用 TimeSeriesGenerator 吗?
谢谢!
也许这个教程会有帮助
https://machinelearning.org.cn/how-to-use-the-timeseriesgenerator-for-time-series-forecasting-in-keras/
你好 Jason。你的教程很棒。
1-你有没有关于使用 LSTM 进行时间序列预测的书?(我知道你有一本关于经典方法时间序列预测的书。
2- 你知道如何预测多元时间序列的多个值吗(你有没有教程或者能告诉我应该在 keras lstm 中更改什么设置?以下是详细描述。
假设我的多元时间序列在转换为监督学习问题后是(前 4 个数字是输入,后 4 个是输出)。
1 2 3 4 5 6 7 8
5 6 7 8 9 10 11 12
9 10 11 12 13 14 15 16
我想学习所有 4 个输出值。你知道这是否可以用你的方法实现,以及我需要更改什么才能使其成为具有多个输出的多元变量,并且我的目标或输出是 4 维的。如果您能帮助,我将非常感激。
是的,请参阅:深度学习用于时间序列预测。
https://machinelearning.org.cn/deep-learning-for-time-series-forecasting/
是的,我有许多多元和多步时间序列预测教程,从这里开始。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
非常感谢,我正在尝试购买你的深度学习时间序列书籍。我的问题在上面没有正确输入。我的意思是我的输入是
输入 输出
1 2 3 4 5 6 7 8
5 6 7 8 9 10 11 12
我应该在 lstm 中更改什么?密集层应该是 dense(4),因为我想学习四个值,而其他所有东西都保持不变。时间步长是 1,批量大小可以是任意的。
如果你的模型要预测每个样本 4 个值,那么密集输出层必须有 4 个节点。
有关样本/时间步长/特征的更多帮助,请参阅此链接。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
你好 Jason。有一个问题,我在你的网站上找不到任何教程。
假设我有多个非常相似的时间序列,为同一事件生成。比如你经常使用的 Shampoo 数据集。假设我没有一个数据集,而是有 100 个单独的数据集(由 1993-2000 年的时间序列组成)我该如何使用所有这些数据进行训练?我知道如何为单个数据集训练 lstm,但然后如何为所有数据集进行训练。我不能连接时间序列或根据值对它们进行排序,因为它们可能是多元的。
如果您能帮助我解决这个问题,我将不胜感激。
好问题,我在这里有一些建议。
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
如何使用 AR 模型系数为机器学习算法(如 SVM)生成特征输入?
我现在已经可以找到 AR 系数了。
通过这段代码
model = AR(train)
model_fit = model.fit()
print(‘Lag: %s’ % model_fit.k_ar)
print(‘Coefficients: %s’ % model_fit.params)
但我不知道如何使用系数来提取 SVM 的特征输入。
谢谢..
抱歉,我对你描述的方法不太熟悉。
如何使用 AR 模型系数为机器学习(如 SVM)生成特征输入?
我现在可以找到这段代码的 AR 系数。
model = AR(train)
model_fit = model.fit()
print(‘Lag: %s’ % model_fit.k_ar)
print(‘Coefficients: %s’ % model_fit.params)
如何为 SVM 创建带有 AR 模型系数的特征输入?.. 谢谢
抱歉,我没有这方面的教程,无法给出好的即时建议。
你好 Jason。优秀的入门文章。我只有两个问题。假设我有三个变量:时间、电流和电压,电压是我要预测的目标变量。那么,如果我按照提到的技术转换我的数据集并训练模型,然后我得到新的数据(验证集),只输入时间电流,并且需要预测验证集中给定时间段的输出电压,我该如何转换才能让我的模型能够预测电压?
另外,我该如何处理我的数据集中的面板数据?
根据一个样本设计模型,例如您想提供什么数据作为输入,以及您需要什么作为输出。
然后准备数据进行匹配、拟合、建模和评估。
嗨 Jason,感谢您提供的所有教程。到目前为止,它们非常有帮助。我现在正在处理一个带有时间序列的分类问题,我想知道您是否能给我一些建议。
我有一个每日时间序列,每天都有一个标签(0,1),我想将问题重构为二元分类——预测第二天的标签——但我遇到了输入变量和目标变量格式的麻烦。
您认为 series_to_supervised() 函数可以应用在这里吗?如果可以,我该如何操作?
我正在考虑以下一个非常简单的实验来检查这是否有效。如果变量值下降,则将天数标记为(0),如果变量值上升,则标记为(1)(这当然可以通过简单的 if 语句完成,但仅为此示例考虑)。
我的数据看起来会是这样的
----------
日期 var1 标签
----------
1 10 NaN
2 20 1
3 9 0
4 8 0
如果我应用 series_to_supervised(data,1,1),数据集将看起来像
------------------------------
日期 var1(t-1) var1(t) 标签(t)
------------------------------
1 10 20 1
2 20 9 0
3 9 8 0
然后定义我的输入/输出对
X = supervised.drop(‘label(t)’)
y = supervised[‘label(t)’]
这种方法正确吗?在我看来,标签对于任何 ANN 来说应该都非常容易学习,但我不知道这种输入/输出格式是否正确。
我很感激您在这方面的任何建议。再次感谢您提供的精彩书籍和教程。
这也许是,只有你自己才确切知道——那是你的数据。
嗨,Jason,
感谢教程
我有一个金融时间序列,我已将该序列转换为监督学习问题。我想预测 t+1 的值,使用过去 60 天的数据。我的问题是关于在 xgboost 和 SVR 之后我应该使用哪种预测方法?我所做的对吗?
我建议测试一系列方法,以发现最适合您的特定数据集的方法。
嗨,Jason,
一如既往的精彩文章,非常感谢。我只想问一下,将时间序列问题转换为监督学习问题的方法与将其视为时间序列问题相比如何?我认为使用 LSTM 等高级技术,我们应该不再需要将时间序列问题转换为监督学习问题。
所有模型最终都会进行这种转换。
LSTM 需要这种转换。请看这篇博文
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
精彩的文章,对我帮助很大。
我做了一些小的修改(我有一个类似但非常简单的函数)。
我想使用时间 t-n1, t-n2, …, t-nx 的数据来预测(例如)时间 t+n7 的值,并想避免删除中间的 t+n1, t+n2, …, t+n6 的新步骤。所以我添加了一个 window 参数来实现这个目的。
这并没有带来很大的改进,但对我有所帮助。
对于未来的版本,最好能够处理输入数据中的实际列名,以便进行自动后处理(例如,如果原始列名是“date”,输出将是“date t-1”)。
稍后我会尝试一下。
感谢分享!
好建议。
嗨,Jason,
我一直在浏览您所有的 LSTM 示例,并且一直在使用您的“series_to_supervised 函数进行预处理”。但是,我一直无法理解,当需要重塑数据以获得 n_in 和 n_out 值大于 1 时,我应该怎么做。
例如,我使用了 50 个时间步长(n_in = 50)的函数来预测未来的另外 50 个值(n_out = 50)。我有超过 300,000 个独立的样本,每个样本有 19 个观测值,所以该函数的输出‘agg’可以理解地很大。
关于重塑。我的直觉是为重塑我的训练 X 数据输入元组 (train_X.shape[0],50,train_X.shape[1])。这会引发错误。我哪里做错了?“series_to_supervised function”是解决这个问题的正确方法吗?我相信是,但我不知道如何解决这个问题。
我特别想知道如何为预测 50 个单独的观测值,甚至是 50 个所有观测值的序列(假设我的术语是正确的)来构建这个问题。作为参考,我查看了您几乎所有的 LSTM 帖子,但也许我忽略了什么。无论如何,您的工作到目前为止非常有帮助——感谢您为您的网站付出的所有辛勤工作!
好问题,我相信这会帮助理解和实践。
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
嗨,Jason,
我们应该创建多少滞后变量?我们只需要使用目标变量创建滞后吗?
也许可以尝试几个不同的值,看看哪个最适合您的模型和数据集。
嗨,Jason,
非常感谢 Jason 的意见。我还有一些问题。
1) 在使用监督机器学习进行时间序列分析之前,我们应该使数据平稳吗?
2) 在数据集中引入滞后(t-1)或(t-2)是否会使数据集平稳?
3) 机器学习模型无法直接“理解”时间数据,因此我们必须显式创建基于时间的特征。这里我们使用 substr 函数从日期字段创建了新的时间特征:星期几、日历日期、月份和年份。这些新特征有助于识别周期性销售模式。这是真的吗?
4) 我们可以创建各种统计特征。这里我们将使用 unit_sales 列创建三个新特征:lag_1(1天滞后)、avg_3(3天滚动平均值)和 avg_7(7天滚动平均值)。我们也可以创建这些类型的特征吗?
是的,尝试在转换之前使序列平稳,并比较结果以确保它能为模型增加技能。
添加滞后变量并不能使其平稳,您必须使用差分、季节性调整以及可能进行幂变换。
新特征可能有用,尝试一下看看是否适合您的数据集。
嗨,Jason,
我忘了在上面的帖子中发布更多问题。
1) 滞后是否总是只为 Y 变量(即因变量)创建?
2) 除了引入滞后数据外,我们是否还需要为 Y 变量添加差分列以使数据平稳?
谢谢,
Karan Sehgal
不,但目标变量的滞后观测值通常非常有益。
添加变量并不能使序列平稳。
你好 Jason,
感谢您的意见。
1.) 所以,我需要同时创建滞后变量和差分变量,因为差分将帮助我创建平稳数据集,而滞后变量对模型非常有益,然后我们需要在算法中同时考虑这两个变量吗?
2) 上面您还提到了季节性调整和可能的幂变换。我们如何获得季节性调整幂变换?我们需要为季节性调整和变换后的数据创建单独的列,还是可以在一列中创建两者?
谢谢。
先差分,再滞后。滞后变量将是差分后的。
这里有一些例子
https://machinelearning.org.cn/machine-learning-data-transforms-for-time-series-forecasting/
嗨,Jason,
我试图预测未来一天(1天 = 144 个值输出),基于过去一周的数据。(144*7= 1008 个时间步长)
在每个时间步长中,我有 10 个变量,例如温度等……
这意味着我有一个非常大的输入向量(144*7*10 = 10,080)
这是否数据量太大了?(10,080 个输入值 ———-> 144 个输出)
不。模型可以处理很多数据。
这与您在 LSTM 教程中所做的不同。
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
这里的输出不应该可以用在 LSTM 模型中吗?
我有点困惑,您能解释一下区别吗?
它可以被重塑并用作 LSTM 的输入,请看这个
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
我们可以将此方法用于天气预报吗?
是的,但物理模型在天气预报方面比机器学习模型表现更好。
滑动窗口和滚动窗口是相同的吗?
滑动窗口和扩展窗口是相同的吗?
请分享一些信息,这将有更多帮助。
谢谢
不完全是。它们是近亲,但不是相同的。
滑动窗口是准备时间序列数据以用于监督学习问题的一种方法。
滚动窗口和扩展窗口是数据准备方法。
好的,谢谢,我明白了,但我有一个疑问。
我们能将滑动窗口完全用作 ARIMA 或 RNN 等预测模型吗?
还是滑动窗口方法只是用于准备时间序列数据以用于监督学习?
滑动窗口是一种数据准备技术。
Jason 非常感谢,我从您的文章中学到了很多。
能否提供您关于端到端 ARIMA 和 RNN 进行时间序列预测的电子书链接?
您可以在这里购买 ARIMA 书籍。
https://machinelearning.org.cn/introduction-to-time-series-forecasting-with-python/
您可以在这里购买时间序列 RNN 书籍。
https://machinelearning.org.cn/deep-learning-for-time-series-forecasting/
嗨,如果我们使用这种将时间序列转换为监督学习问题的方法,我们仍然需要将时间戳作为特征使用吗?或者我们可以简单地删除该列?
因为我们只会建立一个窗口,所以我们不需要时间戳,对吗?如果我错了,是否有正确的准备此特征的方法?
另一个我想问的问题是:如果数据的时间间隔不相同(样本出现在完全随机的时间间隔,但顺序是连续的),这有问题吗?
谢谢,我真的很喜欢您的教程。
不,可以删除。
好问题,我有一些想法
https://machinelearning.org.cn/faq/single-faq/how-do-i-handle-discontiguous-time-series-data
您的博客真是太棒了,Jason!
非常感谢。
谢谢!
嗨,Jason,
这是一篇很棒且信息丰富的帖子。我正在处理我的第一个时间序列预测问题,并有一些问题想问您。所以,一旦调用了 series_to_supervised() 函数并将数据正确转换后,我就可以使用这个新的数据框与传统的机器学习算法(例如 RandomForestRegressor)一起使用吗?还是我需要设置 ARIMA 模型或其他时间序列特定预测模型?然后,我们如何过渡到预测多个变量或提前多个时间步?如果这些是愚蠢的问题,请原谅,我在这里是新手。
谢谢,
Matt
谢谢!
是的,您可以使用机器学习方法。statsmodels 中的 ARIMA 会自动在内部执行这种类型的转换。
对于多元时间序列,您可以使用支持它的线性模型,例如 VARIMA,或者使用深度学习模型。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
很棒的博客 Jason。学到了很多,代码也如您所宣传的那样工作!!!
四个问题:以及一个建议。
1) 如果我有每日预测数据,我的目标是预测未来 6 周,我以为这是方法
a) 将原始数据按周重新采样并汇总销售额 – 因此我的样本量变成 1/7
b) 转换为监督数据,如本文所述
c) 然后用我的数据对它进行建模——训练/测试并保存模型
问题是:我如何使用这个模型来预测未来 6 周,因为整个模型都依赖于之前的事件。学习效果会好吗?
2) 如果我有其他可能的影响因素,如销售促销、折扣、营销活动等,这个模型如何理解?这个 ARIMA 模型只接受一个差异序列。您能否提供关于如何将附加特征纳入模型的指导?
3) 如果有异常项目,例如远远偏离模式的值 -> 我可以修剪数据并删除它们吗?
4) 我们是否需要对数据进行缩放?
我希望您经常使用数据框而不是系列,因为越来越多的用户使用该数据结构,代码可以按原样重用 – 这只是一个建议。
Srinivas
谢谢!
或许可以试试看?
感谢您的回复 – 我认为您的回答与 1 和 3 相关。我认为在仔细考虑后,我不需要做第 4 项,因为差分已经完成了转换。所以这回答了第 4 项。
但是,关于第 2 项,我如何为 ARIMA 添加更多特征?
Srinivas
您可以使用 VARIMA 来处理更多并行输入系列,或使用外生输入变量。
也许从这里的例子开始
https://machinelearning.org.cn/time-series-forecasting-methods-in-python-cheat-sheet/
嗨,Jason,
据我所理解,如果我想基于前 5 个变量的观测值来预测接下来的 24 小时(这是一个多变量、多步的情况),我会使用“” series_to_supervised(dataframe, 1, 24) “”然后删除不需要的列,我是否弄错了?
否则,如果我想使用上个月的值,我应该将“”” n_in=720 “””而不是“”” n_out=1 “”” 或使用其他东西?
谢谢你
您似乎是在根据一个时间步预测 24 个时间步。这很激进。您在进行预测时可能想为模型提供更多上下文 – 例如,提供更多历史/输入。
没错,它不会准确。为此,我想包含更多以前的值,但不知道如何使用相同的函数?
将“n_in”参数更改为一个更大的数字,以便有更多的滞后观测作为输入。
首先,感谢您撰写如此详细的文章。
我的问题是
我有 3 个自变量和 1 个因变量(呼叫量每小时数据)。
我为因变量创建了 24 个滞后,并训练了模型。
但是现在我必须预测未来一周(每天 24 行 * 7 天 = 168)。
我的问题是,我无法理解如何为预测期创建滞后,因为我的模型是训练到,例如,今天。现在我必须预测到 2020 年 6 月 10 日。
现在如何为因变量创建滞后,因为我没有呼叫量的未来数据,而这正是我需要预测的。
在预测数据中,我已经为 3 个自变量创建了未来数据,因为它们都来自日期,例如星期几等……但是如何创建滞后???
我已经在这里卡了 4 天了……请帮忙。
很遗憾听到您遇到了麻烦。
本教程展示了如何拆分每周数据,并可能提供一些见解
https://machinelearning.org.cn/how-to-load-and-explore-household-electricity-usage-data/
还有这里
https://machinelearning.org.cn/how-to-develop-lstm-models-for-multi-step-time-series-forecasting-of-household-power-consumption/
嗨 Jason,我非常喜欢您的文章!内容充实且流畅。
sequence_to_supervised() 是否等同于为 LSTM 准备数据时进行的“窗口化”?
谢谢。
是的,我在这里进行了更详细的介绍
https://machinelearning.org.cn/time-series-forecasting-supervised-learning/
还有这里
https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/
我们进行预测时会发生什么?模型是否也期望序列数据,因为它是经过训练的数据?
新示例以相同形式提供,例如,过去观测值用于预测未来观测值。
嗨,Jason先生,
我的问题是关于“多步或序列预测”部分。
假设我们必须预测接下来的“m”个时间步,并具有一定的滞后,例如序列中的“n”,我的数据集将是这样的
v1(t-n)….v1(t-3),v1(t-2),v1(t-1) V1(t), V1(t+1), v1(t+2), v1(t+3), v1(t+4), v1(t+5)…v1(t+m) 。
现在,请告诉我哪个案例与我的问题相关
情况-1
我将为每个时间段拥有“m”个单独的模型吗?即
v1(t+1) = f(v1(t), v1(t-1), v1(t-2), ….. v1(t-n))
v1(t+2) = f(v1(t), v1(t-1), v1(t-2), ….. v1(t-n))
v1(t+3) = f(v1(t), v1(t-1), v1(t-2), ….. v1(t-n))
.....
v1(t+m) = f(v1(t), v1(t-1), v1(t-2), ….. v1(t-n))
情况-2
我是否应该将我之前的预测值作为序列输入来预测我的下一个值?
v1(t+1) = f(v1(t), v1(t-1), v1(t-2), ….. v1(t-n))
v1(t+2) = f(v1(t+1)hat,v1(t), v1(t-1), v1(t-2), ….. v1(t-n-1))
v1(t+3) = f(v1(t+2)hat,v1(t+1)hat,v1(t), v1(t-1), v1(t-2), ….. v1(t-n-2))
....
v1(t+m) = f(v1(t+m-1)hat,v1(t+m-2)hat,v1(t+m-3)hat,….v1(t+m-n)hat)
我对于选择哪种方法感到困惑
* 在情况-1中,模型的数量将非常多,如果“m”很大,我认为模型维护部分可能会有问题……!!
* 在情况-2中,我将只有一个模型,但随着我深入时间线,我的预测将更多地依赖于之前的预测值,这将使我的输入更加脆弱……
提前致谢,感谢您发表这篇精彩的文章。
您可以两者都做,选择权在您,或者哪个能产生最佳性能/最佳满足项目需求。
感谢 Jason 的文章,阅读愉快。我有一个问题:这与通常的、按行滑动窗口有什么不同?采用这种方式有什么好处,还是我可以同样轻松地让 M 个时间步作为我的 X,1-N 个时间步作为我的 Y,两者每行只有一个时间步?
不客气。
抱歉,我不明白您将此方法与什么进行比较。也许您可以详细说明。
这是一种滑动窗口方法,通常在将时间序列转换为监督学习问题时使用。
据我所知,本文中的滑动窗口方法是窗口在列之间移动
其中 X(t+1) 是目标输出,对于原始数据集中存在的任何特征都是如此。
另一方面,如果窗口像这样在行之间移动呢?
这样,如果您有一个大小为 3 的窗口,您将有 N-3 个滑动窗口,由 (X(t), X(t+1), X(t+2)) 组成,用于预测 X(t+3),一直到 (X(t+N-3), X(t+N-2), X(t+N-1)) 用于预测 X(t+N)?
这两种策略之间有什么区别吗?我问这个的原因是,我在训练 LSTM 时使用了第一种方法(跨列滑动窗口),在使用 pandas 的 shift() 进行大窗口时一直遇到内存不足的错误,但当在行之间滑动而不使用 shift() 时,这是一个相对微不足道的问题,因为不需要进行预处理。
谢谢,
忽略第二个示例中 X 旁边的 || 和 T,我试图说明一个带有向下箭头的 T。
是的,您可以使用上述滑动窗口来处理一个或多个变量。
也许可以看看这里的示例
https://machinelearning.org.cn/how-to-develop-lstm-models-for-time-series-forecasting/
啊,好的。我猜这两种方法是等效的?
嗨,Brownlee 先生
我有 276 个文件(从 1993-2015 年),维度为 (213*276)。每个文件属于一个月。我想预测去年(最后 12 个月)。
我该如何分割数据?时间步长是多少?
我的意思是,我应该将其重塑为一列并将所有年份连接成一长列吗?因为数据就像像素值(像热图),这让我感到困惑。
也许吧。尝试一下,看看它是否适合您的数据集。
也许一次将所有数据加载到内存中,或全部加载到一个文件中,然后对除最后一年之外的所有数据拟合模型,然后逐月在最后一年数据上使用前向验证。
嗨,Jason,
感谢您网站上的精彩材料。
“series_to_supervised”函数很棒,而且使用起来非常直接。但是,我看到当我们使用 shift 和 transform 数据时,数据类型从整数变为浮点数。在函数中调整列的数据类型不是更好吗?
再次感谢。
不客气!
我们应该处理浮点数——几乎所有机器学习算法都期望浮点数,除了可能是树模型。
嗨 Jason,感谢您这篇精彩的文章。我找这样的东西已经很久了。
在我的例子中,我正在尝试构建一个带有外生输入的 AR 模型,因此我需要使用所有训练数据(X 和 y)来训练网络,然后仅基于 X 进行预测。我的数据是非线性的,并且我想提前进行多步预测。
阅读其他网站,我了解到我需要参考 X 和 y_hat 向量的最后 N 个值(而不是整个滞后序列),这与您在这里教授的略有不同。如果您能提供任何关于如何实现这一目标的提示,我将非常感激。
先谢谢您了。
这里有一些例子
https://machinelearning.org.cn/how-to-develop-multilayer-perceptron-models-for-time-series-forecasting/
我想知道我们为什么首先需要做所有这些。为什么我们不能将 Date 列视为任何旧特征 X1,然后预测 y?
例如:将特征 X1、X2、X3(‘Date’、‘Temp’、‘Region’)插入,并训练一个随机森林来预测 y(‘Rainfall’)有什么问题?如果近期数据更重要,模型难道不应该能够找出这一点吗?
很好的问题!
您如果愿意可以这样做。尝试一下并进行比较。
我们这样做是因为最近的滞后观测值通常对未来的观测值具有高度预测性。这种表示称为自回归模型/表示。
嗨,Jason,
我的训练数据有 143 个实例,测试数据有 30 个实例,还包括温度和其他附加特征以及我的目标。
所以如果我创建滞后值,它应该超过第 30 个滞后,对吗?因为对于所有这 30 个实例,我们都不会有滞后 2,因为我们需要预测所有这 30 个实例。
在这种情况下,最佳解决方案是什么?我该如何添加滞后分量来获得结果?
通常,最好使用 ACF/PACF 图来选择合适的滞后,或者通过网格搜索不同的值来发现什么能带来最佳性能。
很棒的教程!这个开源工具有助于标注时间序列数据。
https://github.com/FeatureLabs/compose
感谢分享。
嗨,Jason,
有没有办法将此函数 series_to_supervised 与 PySpark Dataframe 一起使用,或者我可以处理它吗?
非常感谢!
此致,
没有,抱歉。
嗨,Jason,
我有一个与您将时间序列划分为 x(输入)和 y(输出)相关的问题。
我注意到大多数人将序列移动一步,而不管他们想预测多少步。(选项 1)
选项 1
– – – – – – –
—-X————Y
1 2 3 4 5 –> 6 7 8
2 3 4 5 6 –> 7 8 9
3 4 5 6 7 –> 8 9 10
这难道不会让模型预测相同的值吗?(7 8 和 9)
然后使选项 2 更可行,因为模型每次都必须预测新值?
选项 2
– – – – – – –
—-X————Y
1 2 3 4 5 –>. 6 7 8
9 10 11 12 13 –> 14 15 16
17 18 19 20 21 –> 22 23 24
感谢您为 ML 社区做出的贡献!
您正在训练一个函数来映射输入示例到输出示例。我们必须从序列中创建这些示例。
您可以根据需要设计这些映射示例。也许单步预测不适合您的特定数据集。没关系,可以更改它。
嗨 Jason,感谢您的教程。我注意到评论中很多人使用 LSTM 进行时间序列预测。您知道是否也可以使用其他模型,例如逻辑回归来解决这个问题吗?例如,如果我们想预测接下来一小时的家用电器的能源合规性(低或高),基于过去 2 到 3 小时的能耗?谢谢。
是的,一旦数据准备好,您就可以使用任何您喜欢的算法。
你好 Jason,
我有一些短系列,包含 5 个数据值,范围在 0 到 2 之间,例如 [1,2,1,0,0],它们代表给定足球队的最后五场比赛结果,1 代表胜利,2 代表平局,0 代表失败,我想预测下一个值是 1 的概率,一旦我预测了下一个值,第一个值(此处为 1)就会被丢弃以形成一个新的系列。
我对下一个值应该是什么有一个很好的直觉,但想创建一个模型。
请记住我是一个初学者。所以我只是猜测我应该使用时间序列。
我想为每个值加权,因为我知道每个值都取决于许多参数,例如对手的排名、球队上一场比赛的射门次数等等。
我试着理解,但这很难。感谢您所做的一切!
也许可以尝试几个模型,看看哪个适合您的数据集。
更高级的方法是使用评分系统
https://machinelearning.org.cn/faq/single-faq/what-methods-can-be-used-for-modeling-sports
“同样,取决于问题的具体细节,可以将列划分为 X 和 Y 组件,例如,如果 var1 的当前观测值也作为输入提供,而只预测 var2。”
在我们想预测 var2(t) 并且 var1(t) 也可用时。
var1(t-2),var2(t-2),var1(t-1) ,var2(t-1),var1(t),var2(t)
LSTM 网络需要 3D 输入。我们应该为 train_X 提供什么形状?
我必须提供形状 [X,1,5] 吗?
如果我们有一个偶数 train_X(当我们没有 var1(t) 时),我们必须这样塑形,
[X,2,2]
但现在它不是偶数,我无法这样塑形,因为 train_X 有 5 个特征。
唯一的解决方案是提供形状 [X,1,5] 吗?
*X 是数据集的长度
好问题,请看这个
https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input
哇,您的网页帮了我大忙,谢谢!
我在理解一些我认为是基本的东西时遇到了困难。
这围绕着滚动窗口的问题。在其他教程中,您展示了如何为时间序列预测实现 LSTM 模型,通常在通过先前时间步预测下一个时间步的示例中。在上面的示例中,您讨论了滚动窗口以及基于旧值数量进行预测的可能性。由于最佳窗口很大程度上取决于数据点,我仍然想知道 LSTM 是否可以使用窗口大小为 1 就能运行良好?网络如何了解不同的移动模式?还是我遗漏了什么?
也许您可以帮助我理解或指向您的资源。
非常感谢!
谢谢!
可以,但会给模型带来压力,使其在内部状态变量中捕获所需知识,并且您不会跨样本重置状态。
嗨,感谢您的教程,我想进行与电力消耗相关的时间序列预测,并且可能想将此概念应用到我的项目和我的论文中。您是否有此方法的参考?这样我就可以引用您论文中的方法(也许如果您有的话)。
提前感谢!
是的,您可以在这本书中找到许多关于电力消耗的教程
https://machinelearning.org.cn/deep-learning-for-time-series-forecasting/
关于 input_shape。
当我想要使用 20 个输入步长和 50 个输出步长时,我在 series_to_supervised() 方法中指定它,并相应地重塑我的数据/列。但是模型不接受任何其他步长为 1 的 input_shape。我想知道这怎么可能,如果您想预测未来 50 个序列,这是否意味着模型需要知道这一点?
此致。
是的,有许多方法可以进行多步预测,也许可以从这里开始
https://machinelearning.org.cn/multi-step-time-series-forecasting/
谢谢,我已经阅读过了,但这与 LSTM 有什么关系?我创建了一个时间序列 LSTM 模型,遵循 https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/,并且 MSE 指标都显示值小于 1。我没有未来步骤的 y,所以我认为我无法预测上述 4 种策略的 y,因为这要求将预测数据一遍又一遍地运行在模型上。
为了说清楚,我的 y 是一个整数值,x 由从日期中提取的 4 列数据组成,包括 y 值。我的时间步长不一致,这就是为什么我选择从日期中减去最小值/小时/星期几以连接到 y 值。我可以将 y 排除在 x 之外,但我认为那样的话它就不再是 LSTM 模型了?在这种情况下,预测值只会显示一周的平均值。
我感谢任何输入。
更清楚地说,我正在尝试预测未来某时将有多少人到场。我尝试过二元分类和 LSTM,但就是无法输出任何真正的“未来”值。
您可以将 LSTM 用作直接模型、递归模型等。这就是它相关的方式。
您的训练数据中会有用于未来的 y(目标值),或者您将能够构建它们。如果不是这种情况,那么您就无法训练任何模型,因为需要数据来训练模型。
非常详尽的阐述
谢谢!
嗨,您对数据使用了 -1 滞后,然后分割了训练和测试集,对吧?所以可以说您在训练数据中拥有一些关于测试数据的行为用于监督学习。您无法预测未知未来,对吗?…例如,如果我的时间序列数据直到今天,我们就无法预测未来。我说的对吗?
如果我们使用过去的观测值来预测未来的观测值,那么这就是监督学习。
嗨,我目前正在处理数据流上的异常检测,但请告诉我如何使用基于滑动窗口的方法来检测多元时间序列数据中的异常值。我该如何实现多变量数据中的相关系数?谢谢
这可能会给你一些想法
https://machinelearning.org.cn/faq/single-faq/how-do-i-model-anomaly-detection
嗨,感谢您的良好解释。
在我的工作中,LSTM 的输入是视频中的图像序列,输出是一张图像。
事实上,我想对图像进行分割以检测它们。
我不知道输入应该是多大的,例如对于 10 张尺寸为 240*320 的图像?
是否应该定义一个大小为10*76800的矩阵作为LSTM的输入,并在矩阵特征的每一行中写入每个图像?
提前感谢。
此致
也许这会有帮助。
https://machinelearning.org.cn/cnn-long-short-term-memory-networks/
嗨 Jason
非常感谢您精彩的解释。但我有一个问题
如何处理分类变量,其中需要为每个类别进行预测?
例如,有“week_date”、“products”和“sales”这三列,需要为每个产品预测每周的销量。您认为独热编码在这种情况下会有帮助吗?还是有其他方法可以将数据转换为监督学习?
不客气!
我怀疑您应该指定日期而不是预测它。您也可以为每个产品开发一个模型,这样就不需要指定它了。或者产品将作为输入提供。
嗨,Jason,
非常感谢这个教程,非常有帮助。
我目前正在处理鱼类养殖数据。我的目标是测试是否可以使用一个模型来预测养殖场水箱中氨的浓度,使用诸如以下信息作为输入:
每一行包含以下列:
– 站点名称(有3个主要站点有农场数据),连续5天
– 日期
– 水温
– 溶解氧
– 水的pH值
– 其他易于测量的水参数
– 然后,在5天之后,
– 日期(第5天之后的那一天)
– 氨含量 mg/l
并预测第6天的水箱中氨的浓度。
我尝试实现您的系统,但只为一天(第一天)构建了一个模型。我删除了每个鱼塘的其他所有天数。
在这种情况下,最佳解决方案是什么?您能给我指条路吗?我该如何为每一行使用所有5天的连续数据?我做不到。
诚挚的问候
这听起来是一个很棒的项目。
您可以使用上面的代码直接准备您的数据。
也许您可以单独为每个站点建模,或者将所有站点一起建模,这可能会有帮助
https://machinelearning.org.cn/faq/single-faq/how-to-develop-forecast-models-for-multiple-sites
我建议尝试不同的问题框架,以发现最有效的方法,例如,也许您只需要滞后的氨作为输入,也许您只需要当天的观察值或之前的许多天,等等。
非常感谢您的建议。如果我在一个站点上构建模型,它们在其他站点上的预测效果可能会很差。所以我需要使用所有站点的数据。问题是我无法将我的数据应用到您的教程中。
我该如何使用它们?例如,我有10000条数据,有 temp_day_1、temp_day_2、...、temp_day_5 列。对于所有特征,我有5天的连续数据列。在这种情况下,是否所有这些都应该是 (t-1),包括5天的 ammonia_day_1-2-3-4-5,然后我的输出(第6天的氨)将是 (t)?
对于一天来说很容易。我会将 temp_1、ammonia_1、num_fish_1…作为输入,并预测氨作为输出。但是对于所有数据,我无法实现您上面的一项建议。
非常感谢
结构应该是一样的。将第 t 天的 N 个特征作为输入来预测第 t+1 天的 1 个特定特征;或者使用第 t 天到第 t+4 天的 1 个特定特征来预测第 t+5 天的相同特征。
这个函数是否像 Keras 中的 GenerateTimeSeries 函数一样工作,还是有区别?
Keras 中有 GenerateTimeSeries 函数吗?
Jason,做得好。
我做了一个小小的修改,添加了列名,使监督数据集更易读。请检查一下您是否觉得方便。
多谢Alaa。这很有用。我已经格式化了您的代码,以便其他人可以更容易地访问它。
嗨,Jason,
我有一个问题。
普通的滑动窗口与重叠率为50%的重叠滑动窗口有什么区别?当应用于多元时间序列数据集时,重叠率50%是否意味着数据比普通滑动窗口少??
你说得对,因为通常滑动窗口意味着我们将窗口移动一个时间步长。而这里的重叠窗口是为了每次移动窗口的一半大小。
你好 Adrian,
感谢您提供这个精彩的教程!我有一个关于上采样和滞后的问题。我有一个每5分钟采样一次的时间序列。我意识到我不需要那么高的分辨率来进行预测。我能先对我的数据进行上采样(例如每小时),然后进行滞后吗?像这样
df_us = df.resample(‘1h’).mean()
X = df_us[columns = cols].shift(1)[1:]
y = df_us.iloc[1:,-1] # output is the last column
X_train, y_train, X_test, y_test = train_tes_split(X,y, test_size=0.3, random_state=10)
然后将训练和测试数据传递给模型进行训练和评估。在这里,df是给定的数据框,cols是数据框中列名的列表。在每个时间t,我的目标是使用前一个时间点(时间=t-1)的数据来预测时间t的输出。由于nan值,我删除了移位后的第一行数据。当将时间序列预测问题映射到监督学习问题时,重新采样然后滞后数据(就像我在这里所做的)是否会导致数据泄露用于预测?
上采样然后滞后是没问题的。您发布的几行代码在我看来是没问题的。我看不出数据泄露。
嗨,Jason,
祝贺您的文章,我认为它非常有帮助。
我是否可以问您为什么在您的代码中将MinMaxScaler()应用于整个数据集(在将其拆分为训练集和测试集之前)?
我学到的是,最佳实践是首先将数据集拆分为训练集和测试集,然后对训练集使用.fit_transform(),对测试集使用.transform()。这是为了避免用不应在此时可用的数据(即测试集)来偏置训练集的标准化。
感谢您的澄清。
嗨,Jason,
感谢教程。但是 series_to_supervised() 函数有问题。第一行
n_vars = 1 if type(data) is list else data.shape[1]
在数据是 np.array 时不起作用。
谢谢,
Zhongxian
感谢 Zhongxian 的反馈!我的团队将审查并对代码列表进行任何必要的更正。
嗨 James,
感谢您的博文。我发现它们非常有用。
目前我正在处理一种时间序列问题,我需要预测学校食堂的就餐人数。所以我有两个问题:
1. 第一个问题是我希望将问题作为监督学习问题来解决。但是除了就餐人数(这是目标值)之外,我还有当天的预订人数(提前预订)和日历(日、月、季)。我想知道是否可以从就餐人数(通过使用就餐人数的先前时间步长作为输入变量,并将下一个时间步长作为输出变量)创建另一个输入变量?
2. 我的第二个问题是,我想知道是否可以进行网格搜索,并进行适合时间序列的切分(如果存在解决方案)?
感谢您的回答,
Thierno
您好 Thierno…请将您的帖子限制在一个问题上,以便我更好地帮助您。
嗨 James,
感谢您的回复。事实上,我想知道是否可以进行网格搜索,并进行适合时间序列数据的切分。
谢谢,
Thierno
您好 Jason!非常感谢您的教程。它在很大程度上帮助了我。但现在我为我目前正在进行的一个项目感到有些挣扎。我在 Kaggle 上找到了这个数据集
https://www.kaggle.com/cdminix/us-drought-meteorological-data.
我想使用这个数据集来制作一个使用 Keras 和 LSTM 的预测模型。
我的计划是暂时只使用气象数据来训练模型。稍后我也会尝试使用土壤数据。但我需要先让我的模型正常工作。目前我主要在数据处理方面遇到困难。数据集已经清理干净了,但我不知道如何处理我的数据。
让我先向您解释一下数据:
- 有20列关于当天的气象数据及其位置。
- 每周都会有一个干旱评分。该评分范围从0(无干旱)到5(严重干旱)。所以我们有6个标签。
- 但并非每天都有干旱评分 -> 所以每周都会分配一个评分。
现在我在数据处理方面遇到了一些困难。我首先尝试使用“create data_set”函数,但我发现它会创建一个只有一列的数据集。这对我来说是合理的,因为这个函数不适合多元时间序列。(https://machinelearning.org.cn/time-series-prediction-lstm-recurrent-neural-networks-python-keras/)。
我现在也阅读了这篇文章,但我想知道我是否可以使用您定义的函数。如果不行,我该怎么办?我一直在怀疑我是否可以使用您的函数,因为我只有7行输入对应一个标签,而其他6行输入没有标签。
我很想听听您的意见,因为我已经被这个问题困扰了好几天了!
此致,
Mika
您好 Mika…请将您的查询限制在一个具体的问题上,以便我能更好地帮助您。
嗨,Jason,
感谢您提供这个精彩的教程。在多步预测中,为什么您要移位输入特征而保留输出特征?将输出(t+1)移位并保留输入数据是否正确?
嗨
我的时间序列数据集,例如汽车销售,并且我有这个函数
def to_supervised(train,n_input,n_out)
#falten data
data=train
X,y=list(),list()
in_start=0
for _ in range(len(data))
in_end=in_start+ n_input
out_end=in_end + n_out
if out_end<=len(data)
x_input=data[ in_start:in_end,0]
x_input=x_input.reshape((len(x_input)))
X.append(x_input)
y.append(data[in_end:out_end,0])
in_start+=1
return array(X), array(y)
to make data supervised
数据集就像已发布的日期
1960-01 65
我的问题是这个函数会发生什么?
您好 Masoud…以下资源将为您提供一种逐行逐步执行代码的方法,以确认每行正在发生什么。
https://www.hertzler.com/wp-content/uploads/Manual/7_Appendices/Python/Editor/DebugPythonScriptt.htm
你好 Jason,
非常感谢这些教程。
我遇到了一个问题,试图复制一个接受n个时间步长输入数据并使用相同LSTM模型的LSTM模型的预测精度(近似)。但是数据已经被转换成了监督学习结构,就像您在本教程中所做的那样。
我刚接触这个领域,但我认为同一个LSTM模型在这种转换后的数据上无法表现得那么好。
是否存在任何特定的模型类型/结构/架构可以复制LSTM学习序列时间步数据的方式,但使用监督数据来代替;本质上是将新创建的数据列像LSTM处理时间步长一样来处理?
感谢您的时间。
您好 Lahan…您可能想研究一下用于时间序列预测的 CNN,并将其结果与 LSTM 模型进行比较。
https://machinelearning.org.cn/how-to-develop-convolutional-neural-networks-for-multi-step-time-series-forecasting/
嗨,Jason,
我从2019年开始关注您的工作,它帮助我从本科毕业。现在,我正在攻读商务分析硕士学位。非常感谢您。
我有一个关于时间序列预测的问题。我看到过别人的代码,有时他们不仅使用滞后值,还使用滚动平均值(例如7步或28步)。问题是:
1. 您是否对这种方法(仅滞后值或也包含滚动平均值)有任何学术参考资料?
2. 在执行机器学习之前,我们是否也需要检查数据的平稳性?基本上,我们是否需要像 ARIMA 那样进行检查?
非常感谢。
您好 Omar…以下资源可能会有所帮助
https://machinelearning.org.cn/introduction-to-time-series-forecasting-with-python/
詹姆斯,谢谢您的回复。关于第二个问题,我们在将值转换为新列(滞后值和滚动平均值)之前是否需要检查平稳性?
您好 Jason,一如既往的精彩文章,
我正在处理温度时间序列数据,我的导师希望我使用 SVM(回归),这种方法是否适用于 SVM 等经典模型,还是我需要转向神经网络?
您好 Ash!非常欢迎!建议将经典模型与深度学习模型进行比较。不能保证经典模型或神经网络在所有情况下都效果最佳。
你好,
如果我的“t+1”目标列末尾有多个NaN,如下所示,该怎么办?
t t+1
0 1.0
1 2.0
2 3.0
3 4.0
4 5.0
5 6.0
6 7.0
7 NaN
8 NaN
9 NaN
您将如何处理?您会删除这些NaN,还是会进行一些外插或预测来填充时间 t=7,8,9 的缺失值?谢谢。
您好 Tom…此处介绍了多种方法
https://www.geeksforgeeks.org/how-to-deal-with-missing-values-in-a-timeseries-in-python/
您好,您是否有可以使用的文章或教程来使用 LSTM 进行动态和静态变量的预测。在我的数据集中,我有一个依赖于时间的功能,即交易量,我还有 Channel 和 Class 等功能,它们是分类的,但它们一起代表一个类别,还有其他变量,如 Quarter 和星期几,它们也依赖于时间,但其变异性不大。我想预测特定时间特定频道和类别组合的交易量。但我不知道如何处理(在数据集中定位)每种类型的变量。例如,Channel 和 Class 应该被视为特征还是索引?请帮帮我。
您好 Amparo…多元 LSTM 模型可能是一个不错的选择
https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/
此外,我们关于 LSTM 模型最全面的资源可以在这里找到:
https://machinelearning.org.cn/lstms-with-python/
嗨,Jason,
首先,感谢您创建这个博客。您在帮助社区方面做得很好!
我有一个包含每日需求列和另外6个虚拟列的数据集,这些虚拟列代表星期几,因为我需要我的算法能够区分周末。
Reg Demand Monday Saturday Sunday ……Thursday
1 0 1 0 0 0
2 11 0 0 0 1
3 8 0 0 0 0
4 4 0 0 0 0
5 3 0 0 0 0
我想使用 RF、xgboost 和其他算法来预测下周每天的需求。如果您能解释或给我一个关于我以下问题的示例,那将更有帮助:
1- 我只需要进行1天的移位,还是需要将7传递给n_out参数?
2- 我该如何处理虚拟变量?
3- 我是否需要对我的数据进行任何额外的转换?
提前感谢🙂
您好 Jason,首先感谢您的博客,它对我们非常有帮助。我有一个关于准备数据的问题。
我的数据集如下:
Reg Demand Monday Saturday Sunday Thursday Tuesday Wednesday
1 0 1 0 0 0 0 0
2 11 0 0 0 0 1 0
3 8 0 0 0 0 0 1
其中星期几是虚拟变量。
我想使用随机森林、XGboox 和其他算法来逐日预测下周的需求。那么我的问题是:
– 我是否必须将值7传递给函数作为n_out参数?
– 我是否需要对数据进行更多转换?例如,缩放数据?
提前感谢🙂
您好 dvd23…我实际上会推荐一种深度学习模型
https://machinelearning.org.cn/start-here/#deep_learning_time_series
感谢 James 的分享和快速回复,
我也会应用一些深度学习模型,所以您的信息会有用。但是,如果必须强制使用随机森林,我是否需要创建一些移位列作为您想要预测的那些天?
例如,如果我想预测5天,那么列将是 t-1, t-2, t-3, t-4, t-5?
非常非常感谢您的耐心。
您好,感谢分享。这篇文章让我着迷。
我只是一个新人,但我有一个担忧。
– 这种方式与准备 LSTM 模型数据的方式(如 input_shape=(timesteps, features),例如 input_shape=(67, 5) – 67 个时间步长和 5 个特征)相比有何优势?因为如果使用 series_to_supervised,我们将有 input_shape=(1,features),而这个 features = (n_in + n_out + 1) * features – 1。
非常感谢。
您太客气了!您的建议可能确实很合适。我们鼓励您继续您的想法,并告知我们您的发现!
你好 James Carmichael
我想开发一个机器学习模型来预测维护。
我拥有与(故障日期、故障时间、恢复日期、恢复时间等)相关的故障数据。
可以使用哪些模型将(日期和时间数据)转换为可供机器学习算法用于预测模型的格式?
换句话说
如何将这些数据转换为 ML 模型可读的格式?
你好 Ahmad…以下内容可能对您有帮助
https://machinelearning.org.cn/start-here/#dataprep
你好,James,
我有一个问题。如果最后一个特征是目标变量的值,那么 series_to_supervised 函数是否可以用于多变量数据集?
你好 Jessica…简而言之,是的。请继续,并告知我们您的发现。
不完全是。让我猜猜您的目标是从 t 预测到 t + n
我认为您需要修复 trainX 和 testX,使它们“结束”于 Var(t)。
另一方面,trainy 和 testy 必须严格是 Var(t+n)。
抱歉,我误读了您的评论,是的,将最后一个特征设置为目标特征可能没问题。如果它是多变量的,您想预测一组变量,您可能需要尝试其他方法,比如目标向量之类的。
请记住,我之前写的内容如果您想为多步预测设置框架,也可能会很有用。
抱歉,我误读了您的评论,是的,将最后一个特征设置为目标特征可能没问题。如果它是多变量的,您想预测一组变量,您可能需要尝试其他方法,比如目标向量之类的。
请记住,我之前写的内容如果您想为多步预测设置框架,也可能会很有用。
感谢 Brendan 的反馈和建议!
嗨 James,
感谢您的本教程!
我有一个问题。
假设我将时间序列预测问题转换为监督学习问题,并使用直到 t-1 的一组特征和因变量(或输出)的值来对时间 t 及之后的时间进行多步预测。
模型将使用测试集中的哪些数据来进行预测?是为了预测下一个输出而使用真实输出的最新值还是测试集中的预测输出?如果前者属实,那么预测器是否需要持续测量/知道真实输出才能进行进一步预测?如果后者属实,那么预测误差会不会在后续预测中累积?
你好 Kartik…以下资源将极大地帮助您理解使用深度学习方法进行时间序列预测。
https://machinelearning.org.cn/start-here/#deep_learning_time_series
为什么不直接使用 shift 来获取滞后/超前变量?例如 data[[variable1_lag1, variable2_lag2]] = data[[variable1,variable2]].shift(1),lag 2、3 和超前也一样。为什么还要写一个函数来逐列进行拼接?这似乎完全不必要。
你好 Micah…感谢您的反馈!
亲爱的 Jason,
非常感谢您带领我们完成这个复杂的问题!我非常喜欢,所以一直在思考并阅读这里的讨论!🙂
我有一个关于单变量和多变量情况下输入变量如何重新构建的概念性问题。例如,在单步单变量预测演示中,为什么在时间 = t-1 的输入变量的第一行值为“0.0”,因为对于观测数据,我们没有事件之前的信息?在我看来,pandas 的 shift 函数用 NaN 值替换它是有道理的。如果您能提供一些想法和解释,我将非常感激。谢谢!
致以最诚挚的问候,
Yahuei
你好 Yahuei…关于在时间序列预测中输入变量如何重新构建的问题,特别是为什么在一步单变量预测演示的第一行可能是“0.0”而不是 NaN,这对于理解时间序列建模中的数据准备非常重要。
### 理解时间序列预测中的输入重构
#### 单变量时间序列预测
在单变量时间序列预测设置中,我们根据过去的值来预测单个时间序列的未来值。该过程涉及创建滞后特征,这些特征本质上是对时间序列值进行移位。
以下是一个简单的例子来说明这一点
1. **原始时间序列数据:**
时间:t-3 t-2 t-1 t
数据:0.2 0.5 0.7 1.0
2. **创建滞后特征:**
– Lag 1(t-1 时刻的值)
时间:t-2 t-1 t
Lag 1:0.2 0.5 0.7
Target:0.5 0.7 1.0
#### 处理缺失值
当我们移位时间序列以创建滞后特征时,最初的几个条目不可避免地会是 NaN,因为没有可用的先前值。例如:
– 如果我们将数据移位一步(以创建 `t-1`)
Original: 0.2 0.5 0.7 1.0
Lag 1: NaN 0.2 0.5 0.7
– `NaN` 值表示在 `t-3` 之前的时段没有可用数据。
### 为什么用 0.0 替换 NaN?
将 `NaN` 替换为 0.0(或任何其他值)是一种插补形式,它是为了处理缺失值,以便数据可以用于机器学习模型。以下是一些处理此问题的原因和方法:
1. **避免模型输入中的 NaN:**
– 机器学习模型无法直接处理 `NaN` 值。插补这些值可以使模型能够处理整个数据集而不会出错。
2. **零插补:**
– 将 `NaN` 值设置为 0.0 是一种简单的插补方法。这种方法假设系统的初始状态(例如,在时间 `t-0`)可以从零开始。这是一个务实的决定,尤其是在没有充分理由偏好其他插补方法时。
3. **前向填充:**
– 另一种常用方法是前向填充,即将 `NaN` 值替换为最近的非 `NaN` 值。
Lag 1 with Forward Fill: NaN 0.2 0.5 0.7
↓ ↓
0.2 0.2 0.5 0.7
4. **其他插补方法:**
– 可以使用均值或中位数插补来将 `NaN` 值替换为序列的均值或中位数。
– 插值可以根据周围数据点估算缺失值。
### 代码示例
以下是使用 Pandas 的 Python 示例,演示了如何创建滞后特征和处理 `NaN` 值:
python
import pandas as pd
import numpy as np
# 示例时间序列数据
data = pd.Series([0.2, 0.5, 0.7, 1.0])
# 创建滞后特征
data_lagged = data.shift(1)
# 打印原始数据和滞后数据
print("Original Data:\n", data)
print("Lagged Data (with NaN):\n", data_lagged)
# 处理 NaN:零插补
data_lagged_zero = data_lagged.fillna(0)
print("Lagged Data (Zero Imputation):\n", data_lagged_zero)
# 处理 NaN:前向填充
data_lagged_ffill = data_lagged.ffill()
print("Lagged Data (Forward Fill):\n", data_lagged_ffill)
### 总结
– **NaN 处理:**在创建滞后特征时,初始的 NaN 值是自然发生的,因为没有先前的数据。为了使数据适用于机器学习模型,需要处理这些 NaN 值。
– **零插补:**用 0.0 替换 NaN 是一种简单且有时实用的方法,尽管根据数据的具体情况,它可能并不总是最佳方法。
– **替代方法:**前向填充、均值/中位数插补和插值是处理 NaN 值的替代方法。
理解如何在时间序列数据中处理 NaN 值对于构建有效的预测模型至关重要。插补方法的选择会影响模型性能,因此应根据数据的具体特征和手头的任务来决定。
在 k 步 RF 预测的特征工程中,我们如何找到每周数据的最佳滞后?此外,在进行特征工程之前,我们应该进行哪些测试来确保数据适合 RF 时间序列?
你好 Vampy…### 1. **为 RF 预测每周数据找到最佳滞后**
对于时间序列预测中的随机森林(RF)模型,确定要包含为特征的最佳滞后数(过去观测值)至关重要。以下是为每周数据查找最佳滞后的一些方法:
#### **1.1. 自相关和偏自相关(ACF/PACF)**
– **自相关函数 (ACF)**:有助于识别过去的值如何影响当前值。
– **偏自相关函数 (PACF)**:通过去除中间滞后的影响来帮助识别显著的滞后。
– **如何使用 ACF/PACF 来确定滞后**
– 绘制 **ACF** 和 **PACF** 并检查显著的峰值(滞后)。
– 在每周数据中,1 周、2 周等的滞后可能很重要。
– 如果存在季节性成分(例如,每 4 周或 12 周重复一次的模式),也应将其包含在内。
python
import pandas as pd
import matplotlib.pyplot as plt
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
# 加载您的时间序列数据
df = pd.read_csv("your_data.csv", parse_dates=["date"], index_col="date")
# Plot ACF and PACF
plt.figure(figsize=(12,5))
plot_acf(df["target_variable"], lags=20)
plot_pacf(df["target_variable"], lags=20)
plt.show()
—
#### **1.2. 递归特征消除 (RFE)**
– 使用不同滞后变量集训练 RF 模型。
– 使用 **RFE** 对每个滞后的重要性进行排名。
– 仅保留最重要的滞后。
python
from sklearn.ensemble import RandomForestRegressor
from sklearn.feature_selection import RFECV
from sklearn.model_selection import TimeSeriesSplit
import numpy as np
# 创建滞后特征
def create_lags(data, max_lag=12)
df = data.copy()
for lag in range(1, max_lag+1)
df[f"lag_{lag}"] = df["target_variable"].shift(lag)
return df.dropna()
df_lags = create_lags(df, max_lag=12)
# 定义特征和目标
X = df_lags.drop(columns=["target_variable"])
y = df_lags["target_variable"]
# 使用时间序列分割进行验证
tscv = TimeSeriesSplit(n_splits=5)
rf = RandomForestRegressor(n_estimators=100, random_state=42)
# 递归特征消除与交叉验证
rfe = RFECV(rf, step=1, cv=tscv, scoring="neg_mean_squared_error")
rfe.fit(X, y)
# Selected features
selected_features = X.columns[rfe.support_]
print("Optimal lags:", selected_features)
—
#### **1.3. 滞后优化网格搜索**
– 使用 **GridSearchCV** 调整滞后数量。
– 测试不同的滞后值(例如,1-12 周)并选择表现最佳的。
python
from sklearn.model_selection import GridSearchCV
param_grid = {'max_features': [5, 10, 15], 'n_estimators': [50, 100, 200]}
grid_search = GridSearchCV(rf, param_grid, cv=tscv, scoring="neg_mean_squared_error")
grid_search.fit(X, y)
print("Best parameters:", grid_search.best_params_)
—
### 2. **在特征工程之前确保数据适合 RF 时间序列**
在将 RF 应用于时间序列数据之前,检查它是否合适很重要。RF 本身不直接建模时间依赖性,如 ARIMA 或 LSTM,因此应执行以下测试:
#### **2.1. 平稳性检验**
随机森林不需要平稳性,但高度非平稳的数据可能导致性能不佳。使用 **增强迪基-福勒 (ADF) 检验** 进行检查。
python
from statsmodels.tsa.stattools import adfuller
result = adfuller(df["target_variable"])
print("ADF Statistic:", result[0])
print("p-value:", result[1])
if result[1] < 0.05: print("The series is stationary.") else: print("The series is not stationary. Consider differencing.")
如果是非平稳的,请考虑差分
python
df["diff_target"] = df["target_variable"].diff().dropna()
---
#### **2.2. 特征重要性检查**
在构建完整模型之前,测试滞后是否具有预测能力。
python
rf.fit(X, y)
importances = rf.feature_importances_
sorted_idx = np.argsort(importances)[::-1]
for i in sorted_idx:
print(f"Feature: {X.columns[i]}, Importance: {importances[i]:.4f}")
如果所有特征重要性都很低,RF 可能不是最佳选择。
---
#### **2.3. 时间序列交叉验证**
在部署之前,使用 **TimeSeriesSplit** 来验证 RF 性能。
python
from sklearn.model_selection import cross_val_score
scores = cross_val_score(rf, X, y, cv=tscv, scoring="neg_mean_squared_error")
print("Cross-validation scores:", -scores)
print("Mean RMSE:", np.sqrt(-scores.mean()))
如果 RMSE 很高,请考虑特征工程或尝试不同的模型。
---
### **结论**
– **查找最佳滞后**:使用 **ACF/PACF**、**RFE** 或 **Grid Search**。
– **RF 建模前的预检查**
1. **平稳性检验 (ADF)**
2. **特征重要性检查**
3. **使用 TimeSeriesSplit 进行交叉验证**
通过遵循这些步骤,您可以确保您的 RF 模型拥有有意义的特征并在时间序列预测中表现良好。🚀