Python 中使用 LSTM 进行多步时间序列预测

长短期记忆网络(LSTM)是一种循环神经网络,可以学习和预测长序列。

LSTM 的一个优点是除了学习长序列外,它们还可以学习进行一次性的多步预测,这对于时间序列预测可能很有用。

LSTM 的一个难点在于配置它们可能很棘手,并且需要大量准备才能使数据以正确的格式进行学习。

在本教程中,您将了解如何在 Python 中使用 Keras 为多步时间序列预测开发 LSTM。

完成本教程后,您将了解:

  • 如何为多步时间序列预测准备数据。
  • 如何为多步时间序列预测开发 LSTM 模型。
  • 如何评估多步时间序列预测。

开始您的项目,阅读我的新书《深度学习时间序列预测》,其中包含分步教程和所有示例的Python源代码文件。

让我们开始吧。

  • 2019 年 4 月更新:更新了数据集链接。
Multi-step Time Series Forecasting with Long Short-Term Memory Networks in Python

Python 中使用长短期记忆网络进行多步时间序列预测
照片作者:Tom Babich,保留部分权利。

教程概述

本教程分为 4 个部分;它们是

  1. 洗发水销售数据集
  2. 数据准备和模型评估
  3. 持续模型
  4. 多步 LSTM

环境

本教程假定您已安装 Python SciPy 环境。您可以使用 Python 2 或 3。

本教程假定您已安装 Keras v2.0 或更高版本,并使用 TensorFlow 或 Theano 后端。

本教程还假定您已安装 scikit-learn、Pandas、NumPy 和 Matplotlib。

如果您需要帮助设置 Python 环境,请参阅此帖子

接下来,让我们看看一个标准的时间序列预测问题,我们可以将其作为本次实验的背景。

时间序列深度学习需要帮助吗?

立即参加我为期7天的免费电子邮件速成课程(附示例代码)。

点击注册,同时获得该课程的免费PDF电子书版本。

洗发水销售数据集

此数据集描述了 3 年期间洗发水月销量。

单位是销售计数,共有 36 个观测值。原始数据集归功于 Makridakis、Wheelwright 和 Hyndman (1998)。

以下示例加载并创建加载数据集的图表。

运行该示例将数据集作为 Pandas Series 加载并打印前 5 行。

然后创建该系列的线图,显示出明显的上升趋势。

Line Plot of Shampoo Sales Dataset

洗发水销售数据集的折线图

接下来,我们将看一下实验中使用的模型配置和测试工具。

数据准备和模型评估

本节介绍本教程中使用的和数据准备和模型评估

数据分割

我们将把洗发水销售数据集分为两部分:训练集和测试集。

前两年的数据将用于训练数据集,剩下的一年数据将用于测试集。

模型将使用训练数据集进行开发,并对测试数据集进行预测。

供参考,最近 12 个月的观测值如下

多步预测

我们将构造一个多步预测。

对于数据集中最后 12 个月的某个月,我们将需要进行 3 个月的预测。

即给定历史观测值(t-1,t-2,… t-n),预测 t、t+1 和 t+2。

具体来说,从第二年的 12 月开始,我们必须预测 1 月、2 月和 3 月。从 1 月开始,我们必须预测 2 月、3 月和 4 月。一直到第三年的 9 月进行 10 月、11 月和 12 月的预测。

总共需要 10 次 3 个月的预测,如下所示

模型评估

将使用滚动预测方案,也称为向前验证模型。

测试数据集的每个时间步都将逐一进行。模型将用于预测时间步,然后将从测试集中获取下一个月的实际预期值,并使其可用于模型进行下一个时间步的预测。

这模拟了现实世界场景,其中每个月都会有新的洗发水销售观察值,并用于预测下个月。

这将通过训练和测试数据集的结构进行模拟。

将收集测试数据集上的所有预测,并计算误差分数以总结模型在每个预测时间步的技能。将使用均方根误差 (RMSE),因为它会惩罚较大的误差,并且得出的分数与预测数据的单位相同,即月度洗发水销量。

持续模型

时间序列预测的一个良好基准是持续模型。

这是一个将最后一个观测值向前持续的预测模型。由于其简单性,它通常被称为朴素预测。

您可以在以下帖子中了解更多关于时间序列预测的持续模型的信息

2. 准备数据

第一步是将数据从序列转换为监督学习问题。

即从数字列表到输入和输出模式列表。我们可以使用一个预先准备好的名为 series_to_supervised() 的函数来实现这一点。

有关此函数的更多信息,请参阅帖子

该函数列示如下。

通过传入加载的序列值,并将 n_in 值设置为 1,n_out 值设置为 3,可以调用该函数;例如

接下来,我们可以将监督学习数据集分割为训练集和测试集。

我们知道,在这种形式下,最后 10 行包含第二年的数据。这些行构成测试集,其余数据构成训练数据集。

我们可以将所有这些内容放入一个新函数中,该函数接收加载的序列和一些参数,并返回一个已准备好进行建模的训练集和测试集。

我们可以用洗发水数据集来测试这个。完整的示例将在下面列出。

运行示例首先打印整个测试数据集,即最后 10 行。还会打印训练和测试数据集的形状和大小。

我们可以看到测试数据集第一行的单个输入值(第一列)与第二年 12 月洗发水销量中的观测值相匹配。

我们还可以看到,每行包含 4 列,用于每个观测值中的 1 个输入值和 3 个输出值。

进行预测

下一步是进行持续预测。

我们可以轻松地将持续预测实现到一个名为 persistence() 的函数中,该函数接收最后一个观测值和要持续的预测步数。此函数返回一个包含预测的数组。

然后,我们可以从第二年的 12 月到第三年的 9 月,为测试数据集中的每个时间步调用此函数。

下面是一个执行此操作的函数 make_forecasts(),它将训练集、测试集和数据集配置作为参数,并返回一个预测列表。

我们可以这样调用该函数

评估预测

最后一步是评估预测。

我们可以通过计算多步预测的每个时间步的 RMSE 来做到这一点,在这种情况下,我们将得到 3 个 RMSE 分数。下面的 evaluate_forecasts() 函数计算并打印每个预测时间步的 RMSE。

我们可以像这样调用它

将预测与原始数据集中的上下文进行绘制也有助于了解 RMSE 分数与问题的关系。

我们可以首先绘制整个洗发水数据集,然后将每个预测绘制为红线。下面的 plot_forecasts() 函数将创建并显示此图。

我们可以像这样调用该函数。请注意,测试集中的观测值数量为 12 个月(12 个),而不是像上面使用的 10 个监督学习输入/输出模式。

通过将持续预测与原始数据集中的实际持续值连接起来,我们可以使图表更好。

这将需要将最后一个观测值添加到预测的前面。下面是 plot_forecasts() 函数的更新版本,包含了这项改进。

完整示例

我们可以将所有这些部分组合在一起。

多步持续预测的完整代码示例列在下面。

运行该示例首先会为每个预测的时间步长打印 RMSE。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。考虑运行几次示例并比较平均结果。

这为我们提供了每个时间步长的性能基准,这是我们期望 LSTM 能够超越的。

还创建了原始时间序列与多步持续预测的图。线条连接到每个预测的适当输入值。

这种背景显示了持续预测的朴素程度。

Line Plot of Shampoo Sales Dataset with Multi-Step Persistence Forecasts

带有步骤持续预测的洗发水销售数据集的折线图

多步 LSTM 网络

在本节中,我们将以持续性示例为起点,并查看将 LSTM 拟合到训练数据并为测试数据集进行多步预测所需的更改。

2. 准备数据

在我们可以使用数据训练 LSTM 之前,必须先进行准备。

具体来说,需要进行另外两个更改:

  1. 平稳性。数据显示出增加的趋势,必须通过差分去除。
  2. 缩放。数据的大小必须减小到 -1 和 1 之间的值,这是 LSTM 单元的激活函数。

我们可以引入一个名为 difference() 的函数来使数据平稳。这将把值序列转换为差值序列,后者是更容易处理的表示。

我们可以使用 sklearn 库中的 MinMaxScaler 来缩放数据。

将这些放在一起,我们可以更新 prepare_data() 函数,使其首先对数据进行差分和重新缩放,然后像之前对持续性示例一样,执行转换为监督学习问题和训练测试集。

该函数现在除了训练集和测试集之外,还返回一个 scaler。

我们可以这样调用该函数

拟合 LSTM 网络

接下来,我们需要将 LSTM 网络模型拟合到训练数据。

这首先要求将训练数据集从 2D 数组 [样本, 特征] 转换为 3D 数组 [样本, 时间步, 特征]。我们将时间步固定为 1,因此此更改很简单。

接下来,我们需要设计一个 LSTM 网络。我们将使用一个简单的结构,其中包含 1 个具有 1 个 LSTM 单元的隐藏层,然后是一个具有线性激活和 3 个输出值的输出层。该网络将使用均方误差损失函数和高效的 ADAM 优化算法。

LSTM 是有状态的;这意味着我们必须在每个训练周期结束时手动重置网络的状。网络将训练 1500 个周期。

训练和预测必须使用相同的批量大小,并且我们需要在测试数据集的每个时间步长进行预测。这意味着必须使用批量大小为 1。批量大小为 1 也称为在线学习,因为网络权重将在每次训练模式后(而不是 mini batch 或 batch 更新)更新。

我们可以将所有这些组合到一个名为 fit_lstm() 的函数中。该函数接受一些关键参数,这些参数可用于以后调整网络,并且该函数返回一个已拟合的 LSTM 模型,可用于预测。

可以如下调用该函数:

网络的配置尚未调整;您可以尝试不同的参数。

请在下面的评论中报告您的发现。我很想看看您能得到什么。

进行 LSTM 预测

下一步是使用已拟合的 LSTM 网络进行预测。

可以通过调用 model.predict() 来使用已拟合的 LSTM 网络进行单个预测。同样,数据必须格式化为 3D 数组,格式为 [样本, 时间步, 特征]。

我们可以将此包装到一个名为 forecast_lstm() 的函数中。

我们可以从 make_forecasts() 函数调用此函数,并更新它以接受模型作为参数。更新版本如下所示。

更新后的 make_forecasts() 版本可以如下调用:

反转换

在进行预测后,我们需要反转换,将值恢复到原始尺度。

这是必需的,以便我们可以计算误差分数和与其他模型(如上面的持续预测)可比较的图。

我们可以直接使用提供 inverse_transform() 函数的 MinMaxScaler 对象来反转换预测的尺度。

通过将最后一个观测值(前几个月的洗发水销量)添加到第一个预测值,然后将该值向下传播到预测中,我们可以通过添加最后一个观测值来反转换差分。

这有点棘手;我们可以将此行为包装到一个名为 inverse_difference() 的函数中,该函数将最后一个观测值(在预测之前)和预测作为参数,并返回反转换后的预测。

将这些放在一起,我们可以创建一个 inverse_transform() 函数,该函数遍历每个预测,首先反转换尺度,然后反转换差分,将预测恢复到其原始尺度。

我们可以使用预测来调用此函数:

我们还可以反转换输出部分的测试数据集,以便我们可以正确计算 RMSE 分数,如下所示:

我们还可以简化 RMSE 分数的计算,使测试数据只包含输出值,如下所示:

完整示例

我们可以将所有这些部分结合起来,将 LSTM 网络拟合到多步时间序列预测问题。

完整的代码列表如下。

运行该示例首先会为每个预测的时间步长打印 RMSE。

注意:由于算法或评估程序的随机性,或者数值精度的差异,您的结果可能会有所不同。考虑运行几次示例并比较平均结果。

我们可以看到,在每个预测的时间步长上,分数都比持续性预测要好,在某些情况下甚至好得多。

这表明配置好的 LSTM 在此问题上确实具有预测能力。

有趣的是,正如预期的那样,均方根误差(RMSE)并没有随着预测范围的长度而逐渐变差。这一点在 t+2 比 t+1 更容易预测的事实中得到了体现。这可能是因为与系列中观察到的向上波动相比,向下波动更容易预测(这一点可以通过对结果进行更深入的分析来证实)。

还创建了包含系列(蓝色)和预测(红色)的折线图。

该图显示,尽管模型的预测能力有所提高,但一些预测效果并不好,仍有很大的改进空间。

Line Plot of Shampoo Sales Dataset with Multi-Step LSTM Forecasts

洗发水销售数据集的折线图与多步 LSTM 预测

扩展

如果您想深入研究本教程,可以考虑以下一些扩展。

  • 更新 LSTM。将示例修改为在获得新数据后重新拟合或更新 LSTM。训练 10 个 epoch 应该足以用新的观测值重新训练。
  • 调整 LSTM。对教程中使用的一些 LSTM 参数进行网格搜索,例如 epoch 数、神经元数和层数,看看是否能进一步提升性能。
  • Seq2Seq。使用 LSTM 的编码器-解码器范例来预测每个序列,看看这是否能带来任何好处。
  • 预测范围。尝试预测不同的时间范围,并观察网络在不同超前时间下的行为变化。

你尝试过这些扩展吗?
请在评论区分享您的结果;我很乐意倾听。

总结

在本教程中,您了解了如何为多步时间序列预测开发 LSTM 网络。

具体来说,你学到了:

  • 如何为多步时间序列预测开发持久性模型。
  • 如何为多步时间序列预测开发 LSTM 网络。
  • 如何评估和绘制多步时间序列预测的结果。

关于使用 LSTM 进行多步时间序列预测,您有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

立即开发时间序列深度学习模型!

Deep Learning for Time Series Forecasting

在几分钟内开发您自己的预测模型

...只需几行python代码

在我的新电子书中探索如何实现
用于时间序列预测的深度学习

它提供关于以下主题的自学教程
CNNLSTM多元预测多步预测等等...

最终将深度学习应用于您的时间序列预测项目

跳过学术理论。只看结果。

查看内容

544 条对Python 中使用 LSTM 进行多步时间序列预测的回复

  1. Masum 2017年5月10日 凌晨 6:48 #

    谢谢

    你最棒了

    没等多久。几天前在不同的博客上就有要求了

    • Jason Brownlee 2017年5月10日 凌晨 8:53 #

      希望您觉得这篇文章有帮助!

      • Masum 2017年5月10日 凌晨 9:59 #

        我相信是的。这里的东西越来越深入了。

        我们很快就会有用于多步预测的递归 LSTM 模型了吗?

        会热切期待那篇博客。

        谢谢

        • Jason Brownlee 2017年5月11日 凌晨 8:22 #

          也许可以。

          • Masum 2017年5月11日 凌晨 8:43 #

            先生,

            希望很快就能看到。

        • Xingying 2017年10月27日 凌晨 10:06 #

          你好 Masum,
          我正在网站(https://machinelearning.org.cn/multi-step-time-series-forecasting-long-short-term-memory-networks-python/)上学习 LSTM,并在留言板上找到了你。你对多步预测有什么想法吗?我运行了教程中的代码,但使用历史数据总是得到过度拟合的结果。

          谢谢,期待您的回复。

        • Lau Bourne 2022年8月11日 凌晨 11:53 #

          当您使用递归 LSTM 模型进行预测时,能否获得相对精确的结果?
          我发现很难获得令人满意的结果,也许我不太擅长这样训练模型。

    • Harjot Singh 2019年3月11日 下午 7:17 #

      您好,我完全是 RNN 和神经网络的新手。我有一个项目,需要用到 9 年的月度销售数据。我想应用 LSTM 来预测未来 6-7 个月。
      我使用了 ARIMA 并获得了不错的准确度。但我想尝试 LSTM,因为我读了很多支持它的文章。

      这是一个单一变量(包含 9 年月度销售历史数据)的稳定时间序列数据。

      您能建议我从哪里开始学习吗?或者我应该直接将此博客用于我的数据吗?

      您最早的回复将不胜感激。
      感谢您所有的博客。它们真的很有帮助。

    • Steve 2019年5月23日 下午 4:11 #

      我不确定为什么您会用相同的参数多次调用以下内容?
      model.fit(X, y, epochs=1, batch_size=n_batch, verbose=0, shuffle=False)
      model.reset_states()
      X 和 y 是否真的需要按 i 索引到不同的 epoch?

      • Jason Brownlee 2019年5月24日 凌晨 7:47 #

        这是训练神经网络的标准过程,例如,多次 epoch 显示相同的数据集,在本例中我们是手动执行而不是由框架自动执行。

  2. jvr 2017年5月17日 凌晨 1:27 #

    非常感谢这篇帖子。我从九月开始就一直在尝试这个,但没有取得好的结果。但我遇到了麻烦:我无法编译。也许您或有人能告诉我为什么会这样:运行代码时出现以下错误

    TensorFlow 库没有针对 SSE 指令进行编译,但这些指令在您的机器上可用,并且可以加快 CPU 计算。

    TensorFlow 库没有针对 SSE2 指令进行编译,但这些指令在您的机器上可用,并且可以加快 CPU 计算。

    TensorFlow 库没有针对 SSE3 指令进行编译,但这些指令在您的机器上可用,并且可以加快 CPU 计算。
    .
    TensorFlow 库没有针对 SSE4.1 指令进行编译,但这些指令在您的机器上可用,并且可以加快 CPU 计算。

    TensorFlow 库没有针对 SSE4.2 指令进行编译,但这些指令在您的机器上可用,并且可以加快 CPU 计算。

    TensorFlow 库没有针对 AVX 指令进行编译,但这些指令在您的机器上可用,并且可以加快 CPU 计算。

    显然这与 Tensorflow 有关(我阅读过有关此问题的信息,我认为是因为它不是从源代码安装的,但我不知道如何解决)。

    先谢谢您了。

  3. Shamsul 2017年5月17日 下午 9:17 #

    先生,

    我们可以说这里使用了多种输出策略(避免了 1. 直接、2. 递归、3. 直接递归混合策略)吗?

    我说的对吗?

  4. jinhua zhang 2017年5月18日 凌晨 11:26 #

    您好,Jason,
    您的文章非常有帮助!我有一个问题,如果数据序列是三维数据,第二行是输入数据,第三行是预测数据(都包含训练和测试数据),它们可以运行“差分”和“转换”吗?
    非常感谢!

    • Jason Brownlee 2017年5月19日 凌晨 8:11 #

      很好的问题。

      您可能只想让预测变量保持平稳。考虑进行三项测试

      – 按原样建模
      – 输出变量平稳的建模
      – 所有变量平稳的建模(如果其他变量不平稳)

    • jvr 2017年5月21日 下午 10:21 #

      我通过询问一些人发现了如何做到这一点。序列对象实际上是一个 Pandas Series。它是一个信息向量,带有一个命名的索引。然而,您的数据集除了时间序列索引之外,还包含两个信息字段,这使得它成为一个 DataFrame。这就是为什么教程代码在您的数据上会出错。

      要将您的整个数据集传递给 MinMaxScaler,只需对两个列运行 difference(),然后将转换后的向量传递给缩放器。MinMaxScaler 接受一个 n 维 DataFrame 对象。

      ncol = 2
      diff_df = pd.concat([difference(df[i], 1) for i in range(1, ncol+1)], axis=1)
      scaler = MinMaxScaler(feature_range=(0, 1))
      scaled_values = scaler.fit_transform(diff_df)

      所以,通过这个,我们可以使用任意数量的变量。但现在我有一个大疑问。

      当将数据集转换为监督学习问题时,我们在列中有一个分布,如https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/ 所示

      我的意思是,对于您这样的 2 变量数据集,我们可以设置,例如,这些值

      n_lags=1
      n_seq=2

      因此,我们将拥有一个如下的监督数据集

      var1(t-1) var2(t-1) var1(t) var2 (t) var1(t+1) var2 (t+1)

      所以,如果我们想训练 ANN 来预测 var2(这是我们想要预测的目标),并以 var1 作为输入,并且以前的 var2 值也作为输入,我们必须将它们分开,这就是我的疑问开始的地方。

      在代码部分

      def fit_lstm(train, n_lag, n_seq, n_batch, nb_epoch, n_neurons)
      # reshape training into [samples, timesteps, features]
      X, y = train[:, 0:n_lag], train[:, n_lag:]
      X = X.reshape(X.shape[0], 1, X.shape[1])

      我认为如果我们想定义 X,我们应该使用

      X=train[:,0:n_lag*n_vars]

      这意味着我们从上一个示例中选择 X

      var1(t-1) var2(t-1)

      (滞后数*变量数),所以:X=train[:,0:1*2]=train[:,0:2]

      但是……

      Y=train[:,n_lag*n_vars:] 是 ¿目标的向量?

      问题是,通过这种方式,我们将以下内容选为目标

      var1(t) var2(t) var1(t+1) var2(t+1)

      所以我们包含了 var1(我们不打算预测它,只是用它作为输入)。

      我想知道是否有解决方案可以解决这个问题,以便使用变量 1,2…n-1 作为输入,但不对其进行预测。

      希望这很清楚 :/

  5. jvr 2017年5月19日 凌晨 3:16 #

    感谢之前的澄清。我有一个关于“拟合网络”部分的疑问。我在尝试绘制训练图(验证 vs 训练)以查看网络是否过拟合时遇到了一些麻烦,但由于“model.reset_states()”语句,我只能从 history 语句中保存最后一个 loss 和 val_loss。有什么方法可以解决这个问题吗?

    提前感谢 🙂

    • jvr 2017年5月19日 凌晨 3:45 #

      我回复我自己,如果有人也感兴趣的话。

      只需创建 2 个列表(或 1 个,但我这样看更清楚),并在函数中返回它们。然后,在外部,只需绘制它们。抱歉提问,也许答案很明显,但我刚开始接触 Python,不是程序员。

      # 拟合网络
      loss=list()
      val_loss=list()
      for i in range(nb_epoch)
      history=model.fit(X, y, epochs=1, batch_size=n_batch,shuffle=True, validation_split=val_split)
      eqm=history.history[‘loss’]
      eqm_val=history.history[‘val_loss’]
      loss.append(eqm)
      val_loss.append(eqm_val)
      model.reset_states()

      return model,loss,val_loss

      # 拟合模型
      model,loss,val_loss=fit_lstm(train, n_lag, n_seq, n_batch, n_epochs, n_neurons)

      pyplot.figure()
      pyplot.plot(loss)
      pyplot.plot(val_loss)
      pyplot.title(‘cross validation’)
      pyplot.ylabel(‘MSE’)
      pyplot.xlabel(‘epoch’)
      pyplot.legend([‘training’, ‘test’], loc=’upper left’)
      pyplot.show()

      • Jason Brownlee 2017年5月19日 凌晨 8:23 #

        很高兴看到您取得了进展 jvr,做得好。

      • Andrew 2019年2月5日 凌晨 10:50 #

        你好 jrv,

        我知道现在很晚了,但我想知道您是否还有实现多变量解决方案的完整代码?

        如果其他人有解决方案,可以将多变量和多滞后输入预测为单个列,我将非常乐意交流!

        提前感谢

    • Jason Brownlee 2017年5月19日 凌晨 8:22 #

      调用 model.fit() 时会返回历史记录。

      我们一次只拟合一个 epoch,因此您可以在 epoch 循环中检索并累积每个 epoch 的性能,然后在循环结束时处理数据(保存/绘图/返回)。

      这有帮助吗?

      • jvr 2017年5月19日 下午 9:17 #

        这有帮助,谢谢。

        现在我正在尝试寻找一种方法来加快训练过程并降低 RMSE,但这非常困难(目的是使结果优于 Matlab 神经网络工具箱中实现的 NARx 模型,但结果和计算时间很难克服)。

        • Jason Brownlee 2017年5月20日 凌晨 5:37 #

          LSTM 通常需要比您想象的更长的训练时间,并且可以大大受益于正则化。

  6. DJ 2017年6月2日 凌晨 1:42 #

    你好,

    感谢精彩的教程,我想知道您能否帮助我澄清您为什么

    model.reset_states()

    (第 83 行)
    在拟合模型时,我发现在没有这一行的情况下也能获得类似的结果。

    谢谢!

    • Jason Brownlee 2017年6月2日 下午 1:02 #

      它会清除 LSTM 的内部状态。

      • anurag 2017年8月30日 下午 3:41 #

        我尝试过使用和不使用 model.reset_states(),使用了一些其他的数据集。
        我正在进行 6-10 步的多步预测,在不使用 model.reset_states() 的情况下我能获得更好的结果。

        是我做错了什么,还是这完全取决于数据集?

        提前感谢。

        • Jason Brownlee 2017年8月30日 下午 4:20 #

          这完全取决于数据集和模型。

          • anurag 2017年8月31日 下午 6:42 #

            非常感谢。:)

  7. DJ 2017年6月2日 下午 4:11 #

    感谢您快速回复 Jason :-)。我看到其他地方通过使用 model.fit 中的 callbacks 参数来重置状态。


    class ResetStatesCallback(Callback):
    def __init__(self):
    self.counter = 0

    def on_batch_begin(self, batch, logs={}):
    if self.counter % max_len == 0:
    self.model.reset_states()
    self.counter += 1

    然后回调的使用方法如下


    model.fit(X, y, epochs=1, batch_size=1, verbose=2,
    shuffle=False, callbacks=[ResetStatesCallback()])

    ResetStatesCallback 代码片段来自
    http://philipperemy.github.io/keras-stateful-lstm/

    请告诉我您的想法。

    谢谢!

    • Jason Brownlee 2017年6月3日 凌晨 7:21 #

      是的,有很多方法可以实现重置。使用最适合您应用程序的方法。

  8. QQ 2017年6月2日 下午 5:00 #

    你好 Jason,很棒的文章,我有一些问题

    1. 在您的 fit_lstm 函数中,您重置了每个 epoch 的状态,为什么?
    2. 为什么您自己迭代每个 epoch,而不是使用 model.fit(X, y, epochs)?

    谢谢 Jason

    # 训练一个 LSTM 网络
    def fit_lstm(train, n_lag, n_seq, n_batch, nb_epoch, n_neurons)
    # reshape training into [samples, timesteps, features]
    X, y = train[:, 0:n_lag], train[:, n_lag:]
    X = X.reshape(X.shape[0], 1, X.shape[1])
    # 设计网络
    model = Sequential()
    model.add(LSTM(n_neurons, batch_input_shape=(n_batch, X.shape[1], X.shape[2]), stateful=True))
    model.add(Dense(y.shape[1]))
    model.compile(loss='mean_squared_error', optimizer='adam')
    # 拟合网络
    for i in range(nb_epoch)
    model.fit(X, y, epochs=1, batch_size=n_batch, verbose=0, shuffle=False)
    model.reset_states()
    return model

    • Jason Brownlee 2017年6月3日 凌晨 7:23 #

      epoch 结束是序列的结束,内部状态不应在下一个 epoch 的序列开始时延续。

      我手动运行 epoch 以实现对重置发生时间的精细控制(默认情况下,它们在每个 batch 结束时发生)。

  9. J 2017年6月7日 凌晨 12:48 #

    我想澄清 LSTM 示例中的第 99 行

    —– plot_forecasts(series, forecasts, n_test+2)

    Is the n_test + 2 == n_test + n_lag – n_seq?

    谢谢,
    J

    • jvr 2017年6月15日 下午 11:49 #

      我也想知道为什么使用 n_test + 2

      • M 2017年8月8日 凌晨 3:07 #

        我认为应该是 n_test + 2 == n_test+n_seq-1(与 n_seq 无关)。如果有人能澄清这一点,那就太好了。

        • Mrtn 2017年10月4日 下午 8:36 #

          M,你说得对。否则 RMS 会被错误计算,并且绘图会不对齐。

    • Daniel 2022年7月8日 凌晨 2:22 #

      我也非常想知道为什么使用 n_test + 2

  10. Kao 2017年6月10日 下午 5:46 #

    你好 jason,
    当我将您的代码应用于 22 年的每日时间序列时,我发现 LSTM 预测结果与持久性预测结果相似,即红线只是一个水平线。我确定我没有搞砸这两种方法,我想知道是什么原因?

    我的关键配置如下
    n_lag = 1
    n_seq = 3
    n_test = 365*3

    我的序列长度是 8035。

    • Jason Brownlee 2017年6月11日 凌晨 8:21 #

      您需要调整模型以适应您的问题。

      • Kao 2017年6月25日 下午 6:55 #

        感谢您的教程,我这些天一直在调整 epoch 数和神经元数等参数。然而,我注意到您提到了网格搜索方法来获取合适的参数,您能否解释一下如何将其应用于 LSTM?我对我从其他教程中看到的模型类感到困惑,这似乎不熟悉。

  11. MM 2017年6月13日凌晨6:44 #

    Jason,

    感谢您的这些教程。这是网络上最好的教程。一个问题:预测最后两个值的最佳方法是什么?

    谢谢你

    • Jason Brownlee 2017年6月13日凌晨8:31 #

      谢谢 MM。

      没有人能告诉你应用机器学习中做任何事情的“最佳”方法,你必须通过在你特定的问题上进行反复试验来发现它。

      • MM 2017年6月13日凌晨9:29 #

        Jason,

        明白了。请允许我重新表述一下这个问题。在实际应用中,人们会关注预测最后一个数据点,即在洗发水数据集,“3-12”。您会建议如何做到这一点?

        • Jason Brownlee 2017年6月14日凌晨8:41 #

          将您的模型拟合到所有数据,然后调用 predict(),传入您的模型所需的任何滞后输入。

      • MM 2017年6月13日凌晨10:24 #

        Jason,

        plot_forecasts() 中启动偏移点的行应该是

        off_s = len(series) – n_test + i + 1

        而不是

        off_s = len(series) – n_test + i – 1

  12. Michael 2017年6月21日凌晨4:03 #

    嗨,Jason,

    感谢您出色的教程!

    我看了您的几篇关于 LSTM 的文章,学到了很多,但脑海中有一个问题:我能否在模型中引入一些干扰因素?例如,对于洗发水销售问题,可能有一些假日销售数据,或者事件发生后的销售数据。如果我想对这些事件之后的销售进行预测,我该怎么做?

    更重要的是,我注意到您会使用解析器来解析日期/时间,但您并没有真正将时间特征引入模型。例如,我想预测下周一或明年一月的销售情况,我该如何输入时间特征?

    谢谢!

    • Jason Brownlee 2017年6月21日凌晨8:18 #

      是的,请参阅这篇关于添加附加功能的帖子。
      https://machinelearning.org.cn/basic-feature-engineering-time-series-data-python/

      • Michael 2017年6月22日晚上5:53 #

        感谢您的澄清。

        我还有两个更具体的问题
        1) 在 inverse_transform 中,为什么索引是 len(series) – n_test + i – 1?

        2) 在 fit_lstm 中,您说“将训练重塑为 [samples, timesteps, features]”,但我认为第 74 行的代码与您的格式略有不同

        73 X, y = train[:, 0:n_lag], train[:, n_lag:]
        74 X = X.reshape(X.shape[0], 1, X.shape[1])

        在第 74 行,我认为它应该是 X = X.reshape(X.shape[0], X.shape[1], 1)

        • Jason Brownlee 2017年6月23日凌晨6:52 #

          您好 Michael,

          是的,偏移量在原始时间序列中找到预测之前的一个步长。我在整个教程中都使用了这个模式。

          在下一行我说:“我们将时间步长固定为 1,所以这个改变很简单。”

          • Mark 2020年3月6日凌晨12:50 #

            嗨,Jason,

            首先,感谢您提供的所有精彩教程。

            我正在详细地逐步分析这个例子,并且遇到了和 Michael 在 (2) 中提出的相同问题。恐怕我还不完全理解“我们将时间步长固定为 1”的说法。

            我们需要 X 的维度为 [samples, timesteps, features]

            因此,第 74 行不应该写成

            X = X.reshape(X.shape[0], X.shape[1], 1) (如 Michael 所建议的)

            我期望 X.shape[1] 与 n_lag 相同(即 timesteps),在这个例子中只有 1 个特征。

            如果像您的例子中那样,timesteps = n_lag = n_features = 1,这不会有区别,但是,我尝试了 n_lag = 2。

            对于 1 个特征和 n_lag = 2,我期望 X.shape 是 [n_samples, 2, 1],而代码给我的却是 [n_samples, 1, 2]。

            提前感谢,Mark。

          • Jason Brownlee 2020年3月6日凌晨5:38 #

            据我回忆,特征数量和时间步长都是 1。它们是等效的。

            另外,这或许会有帮助
            https://machinelearning.org.cn/faq/single-faq/what-is-the-difference-between-samples-timesteps-and-features-for-lstm-input

  13. Michael 2017年6月22日晚上6:01 #

    嗨,Jason,

    我想知道如何用最少数量的模型来做短期和长期预测?

    例如,我有一个 12 步输入和 12 步输出的模型 A,以及一个 12 步输入和 1 步输出的模型 B,模型 A 对第一个时间步的预测会比模型 B 好吗?

    更重要的是,如果我们有一个 1 步输入和 1 步输出的模型,它对长期预测更容易出错。
    如果我们有一个多步输入和 1 步输出的模型,它仍然更容易出错于长期预测。那么如何看待长期和短期预测?

    • Jason Brownlee 2017年6月23日凌晨6:53 #

      我建议针对不同的用例开发和评估每个模型。我发现 LSTM 在实践中相当不受假设和经验法则的影响。

  14. jzx 2017年6月25日下午1:17 #

    您好,感谢您的教程
    如果我的预测模型是三个时间序列 a、b、c,我想用 a、b、c 来预测未来的 a,我该如何构建我的 LSTM 模型?
    非常感谢!

    • Jason Brownlee 2017年6月26日凌晨6:05 #

      a、b 和 c 中的每一个都将是输入特征。请记住,输入数据的形状或维度是 [samples, timesteps, features]。

  15. Kedar 2017年6月26日晚上6:03 #

    数据平稳化对 LSTM 真的有帮助吗?如果有,其直觉是什么?我的意思是,我能理解为什么这对 ARIMA 类方法来说是这样,但为什么对 LSTM 呢?

    • Jason Brownlee 2017年6月27日凌晨8:27 #

      是的,根据我的经验,主要是因为它是一个更简单的预测问题。

      我建议尝试几种不同的序列“视图”,看看哪种最容易建模/能获得最佳的模型技能。

  16. Michael 2017年6月28日晚上5:47 #

    嗨,Jason,

    我想用以下输入大小的模型进行训练:[6000, 4, 2]([samples, timestamps, features])

    例如,我想预测未来两年的洗发水销量。如果我有经济指数等其他特征,我能否将销售数据和指数数据以上述格式连接起来?那么我的输入将是一个 3D 向量。我应该如何修改模型来训练?

    我总是遇到这样的错误:ValueError: Error when checking target: expected dense_1 to have 2 dimensions, but got array with shape (6000, 2, 2)。

    错误来自这一行:model.fit(X, y, epochs=1, batch_size=n_batch, verbose=0, shuffle=False)。您能提供一些建议吗?谢谢!

    • Jason Brownlee 2017年6月29日凌晨6:32 #

      重新调整数据以使其成为 [6000, 4, 2]。

      将网络的输入形状更新为 (4,2)。

      调整您想要预测的输出序列的长度。

  17. shamsul 2017年7月11日早上11:31 #

    先生,

    要用 LSTM 进行一次预测,如果我们这样写

    oneforecast = forecast_lstm(model, X, n_batch)

    它显示:未定义的 X

    X 的值应该是什么?我们知道模型和 n_batch 的值?

    你能帮忙吗?

    • Jason Brownlee 2017年7月12日凌晨9:38 #

      X 将是进行预测所需的输入序列,例如滞后观测值。

  18. masum 2017年7月12日凌晨8:06 #

    先生,

    如果我想让模型从训练数据(这里是 23 个样本)学习,并且只想预测 3 个时间步(1 月、2 月、3 月),该怎么办?我想在这种情况下避免使用持久化模型,并且只要求 3 步直接策略。希望您理解了。

    任何帮助都将不胜感激。

    训练(过去数据)= 预测(1月、2月、3月)

    • Jason Brownlee 2017年7月12日凌晨9:54 #

      也许我误解了,但这正是教程中提出的模型。它预测 3 个时间步。

      • masum 2017年7月12日早上11:00 #

        # 评估持续模型
        def make_forecasts(model, n_batch, train, test, n_lag, n_seq)
        forecasts = list()
        for i in range(len(test))
        X, y = test[i, 0:n_lag], test[i, n_lag:]
        # 进行预测
        forecast = forecast_lstm(model, X, n_batch)
        # 存储预测结果
        forecasts.append(forecast)
        return forecasts

        在这里,如果我想对 3 个步骤(1 月、2 月、3 月)进行一次预测,我需要更改什么。我不需要这个月的其余部分(4 月、5 月、6 月、7 月、8 月……12 月)。一次预测或 3 步预测。

        希望您明白了。

        • Jason Brownlee 2017年7月13日凌晨9:47 #

          传入进行这 3 个月预测所需的输入即可。

          • masum 2017年7月13日凌晨10:16 #

            先生,

            能否请您再简化一点?

            我没明白。

  19. Devakar Kumar Verma 2017年7月24日凌晨4:23 #

    在加载 CSV 文件数据时,我遇到了日期解析错误。
    错误是
    ValueError: time data '1901-Jan' does not match format '%Y-%m'

    有人能帮我解决这个问题吗?

    • Jason Brownlee 2017年7月24日凌晨6:56 #

      很抱歉听到这个消息。请确认您已精确复制代码,并且数据文件中没有额外的页脚信息。

    • p 2017年7月30日晚上8:05 #

      你好
      我遇到了这个问题
      我已从文本中的链接下载了数据集
      我认为这个错误发生是因为我们 CSV 文件中的数据格式不正确!
      谁能给我数据集,拜托??

      • Jason Brownlee 2017年7月31日凌晨8:15 #

        这是准备好的原始数据。

        • Dongchan 2017年10月9日凌晨9:26 #

          先生,

          我遇到了同样的问题。如何修复解析器以解决此错误?

          • manuel 2017年12月1日凌晨5:57 #

            您选择的数据 csv 是用“,”分隔的,如果是“;”则无法工作。

        • J. Berglund 2018年5月25日晚上10:37 #

          我遇到了同样的问题。对我来说,问题在于 CSV 文件中的第一列(“m-y”)默认设置为“1-Jan, 1-Feb, …. , 3-Dec”,并且无法与“‘%Y-%m’”匹配。

          但是,通过在 Excel 中手工制作日期列,在日期前加上一个“‘”,解决了这个问题。例如:‘1-01, ‘2-01 .. 等。

          希望这能帮助到未来的人。🙂

  20. Devakar Kumar Verma 2017年7月24日晚上2:34 #

    @Jason,
    数据文件没有页脚,我只是复制粘贴了代码,但 dateparser 抛出了错误。我不知道为什么它表现得如此奇怪。

    • Jason Brownlee 2017年7月25日凌晨9:27 #

      抱歉,我没有什么好主意。可能是 Python 环境问题?

  21. Josep 2017年7月31日晚上8:15 #

    嗨,Jason,
    再次精彩的解释。我有一个关于这段代码的疑问

    # 评估持续模型
    def make_forecasts(model, n_batch, train, test, n_lag, n_seq)
    forecasts = list()
    for i in range(len(test))
    X, y = test[i, 0:n_lag], test[i, n_lag:]
    # 进行预测
    forecast = forecast_lstm(model, X, n_batch)
    # 存储预测结果
    forecasts.append(forecast)
    return forecasts

    为什么您将“n_seq”参数传递给函数,而它在函数内部没有使用?

  22. Nara 2017年8月1日晚上10:12 #

    你好,
    我该如何预测一整月?(假设我有每日数据)。
    假设我有大约 5 年的数据,1.8k 个数据点用于训练。

    我想使用一年前的数据来预测下个月的全部情况?

    为了做到这一点,我应该改变这个模型的训练方式吗?
    我的理解是否正确,即这个模型试图仅通过当前值来预测下一个值?

    • Jason Brownlee 2017年8月2日凌晨7:50 #

      是的,将数据框定为预测一个月,然后训练模型。

      模型可以输入您想要的任何内容,例如,过去一个月或一年的序列。

  23. Kiran 2017年8月4日晚上2:09 #

    您好 Jason,感谢您写下如此详细的解释。
    我正在为一个时间序列预测问题使用 LSTM 层。
    一切都很好,除了当我尝试使用 inverse_transform 来撤销数据的缩放时。我收到了以下错误。

    ValueError: Input contains NaN, infinity or a value too large for dtype(‘float64’).

    不确定如何解决这个问题。您能帮我一下吗?

    • Jason Brownlee 2017年8月4日晚上3:45 #

      看起来您正在尝试对 NaN 值执行逆变换。

      也许尝试使用 print 语句来帮助追踪 NaN 值来自哪里。

      • Kiran 2017年8月5日中午12:01 #

        感谢您的回复。是的,我的预测中确实有一些 NaN 值。这是否表明模型训练不当?

        • Jason Brownlee 2017年8月6日凌晨7:36 #

          您的模型可能正在接收 NaN 作为输入,请检查一下。

          如果输入正常,模型也可能产生 NaN 预测,在这种情况下,它可能在训练过程中遇到了困难。有一些方法,如梯度裁剪,可以解决这个问题。
          https://keras.org.cn/optimizers/

          但首先要弄清楚是哪种情况。

          • Kiran 2017年8月14日晚上11:05 #

            谢谢!我的输入没有 NaN。我会看看梯度裁剪。

          • Jason Brownlee 2017年8月15日凌晨6:37 #

            Kiran,让我知道进展。

          • Ami Tabak 2018年1月22日晚上6:59 #

            嗨 Jason
            我遇到了数据文件格式问题和 Kiran 遇到的类似 NaN 问题。
            我下载的文件格式没有 19 的格式。
            例如:
            Month,Sales of shampoo over a three year period
            01-Jan,266

            所以我修改了 parser(),使其只返回 x 本身。

            然后在 Multi-Step LSTM Network 上,我得到了以下 NaN。

            ipdb> series
            月份
            01-Jan 266.0

            03-Nov 581.3
            03-Dec 646.9
            NaN NaN
            Sales of shampoo over a three year period NaN
            Name: Sales of shampoo over a three year period, dtype: float64

            我更改了调用以使用 skipfooter,例如:
            series = read_csv(‘shampoo-sales.csv’, header=0,skipfooter=2, parse_dates=[0], index_col=0, squeeze=True, date_parser=parser)

            网络运行了,但实现了略有不同的训练 RMSE。

            t+1 RMSE: 97.719515
            t+2 RMSE: 80.742075
            t+3 RMSE: 110.313295

          • Jason Brownlee 2018年1月23日凌晨7:51 #

            干得好!

            考虑到该方法的随机性,这些差异是相当小的。
            https://machinelearning.org.cn/randomness-in-machine-learning/

          • Yasmine Sayed 2018年5月15日凌晨8:06 #

            嗨,Jason,
            我遇到了类似的问题。我的 train_x 中的所有输入都不是 nan,但一旦我进行训练,并且打印 train_predict,它会给我一整串 nan 值。我也收到了这个错误。
            ValueError: 输入包含 NaN、无穷大或对于 dtype('float32') 来说太大的值。

            请帮忙……

            注意:我正在使用日期和值的数据集,格式如下(每日而不是每月),因为我想预测每日值:不确定这是否会影响代码中的任何内容。

            2013-12-02,3840457
            2013-12-03,3340470
            2013-12-04,3356629
            2013-12-05,3324450
            2013-12-06,3275983
            2013-12-07,2968327

            我有大约 1500 条记录。

          • Jason Brownlee 2018年5月15日凌晨8:09 #

            您必须在建模之前对数据进行缩放。

          • Yasmine Sayed 2018年5月15日凌晨9:17 #

            我在建模前已经规范化了数据。我做了和您在这段代码中为 LSTM 预测所做的一模一样。唯一的区别是我的数据是每日的,而不是每月的。
            这是我的 train_x 在构建模型之前的样子。
            train_x
            [[[0.939626 ]
            [0.9441713 ]
            [0.93511975]

            [0.5557002 ]
            [0.5948241 ]
            [0.5920827 ]]

            [[0.9441713 ]
            [0.93511975]
            [0.9214866 ]

            [0.5948241 ]
            [0.5920827 ]
            [0.5772988 ]]

          • Jason Brownlee 2018年5月15日晚上2:43 #

            有趣的是您会遇到 NaN。也许模型需要进一步的调整,进行实验看看能否更多地了解它为什么会发生。

          • Yasmine Sayed 2018年5月16日凌晨4:19 #

            嗯,或者,
            我只是使用了另一个示例中的相同模型和数据框准备(关于航空公司乘客),然后我调用了这里的 make_forecast 函数,并将 testX 集作为输入(所以我想它正在使用 testX 的最后一个值来预测未来……?),并且我还调用了我们在此示例中构建的模型。
            它进行了预测……但出于某种原因,预测值持续增加,即使这些数据非常有周期性,它会上下波动。——这很奇怪,因为当我们验证模型时,准确性非常令人印象深刻。但现在当我尝试预测未来几个时间步时,它的准确性差了很多,而且它只是在向上走……。
            我该如何解决这个问题?我的方法是错误的吗?

            非常感谢您的回复——这对您真的很有帮助。

          • Jason Brownlee 2018年5月16日凌晨6:08 #

            我建议针对问题调整模型。

          • Yasmine Sayed 2018年5月16日凌晨4:54 #

            另外,我的预测在大约 25-30 个时间步后会变得几乎恒定。

  24. Nara 2017年8月8日晚上9:34 #

    嗨,Jason,

    当我尝试分步预测时。也就是说,预测 1 个点,然后将其作为数据使用并预测下一个点,我的预测在仅 2 个时间步后就变得恒定,有时从一开始就是如此。

    https://datascience.stackexchange.com/questions/22047/time-series-forecasting-with-rnnstateful-lstm-produces-constant-values
    详细介绍了其中的内容。您能解释一下为什么会发生这种情况吗?哪种预测方法通常更好?逐步预测还是窗口式预测?

    另外,何时 ARIMA/线性模型可能比网络/RNN 表现更好?

    • Jason Brownlee 2017年8月9日凌晨6:30 #

      使用预测作为输入是不好的,因为错误会累积。只有在无法获取真实观测值时才这样做。

      如果您的模型具有线性关系,那么使用线性模型(如 ARIMA)进行建模会更好,模型将训练得更快且更简单。

      • Nara 2017年8月11日晚上10:09 #

        但是 ARIMA 模型不就是这样预测的吗?
        它们是逐点预测。根据我的结果,ARIMA(或 STL ARIMA 甚至 XGBOOST)在与 RNN 相比时表现相当不错。🙁

        但我没有考虑平稳性和异常值处理,我发现 RNN 在数据非平稳/有异常值时表现很差。

        这是预期的吗?我读过 RNN 应该能自动处理平稳性?

        另外,如果我们对数据进行一阶差分,即使数据不存在平稳性,结果也会很糟糕吗?

        在规范化方面,是否有可能在某些情况下 RNN 在没有规范化的情况下也能表现良好?
        何时通常推荐规范化?当标准差很大时?

        • Jason Brownlee 2017年8月12日凌晨6:49 #

          我发现 RNN 在自回归问题上表现不佳,它们在更多的数据预处理(例如,去除任何系统性东西)方面表现更好。请参阅此帖子。
          https://machinelearning.org.cn/suitability-long-short-term-memory-networks-time-series-forecasting/

          通常,如果您不需要,则不要进行差分,但请测试所有内容以确保。

          如果分布是高斯的,则进行标准化,否则进行归一化。RNN(如 LSTM)需要良好的数据缩放,MLP 则不太需要,尤其是在 ReLU 时代。

          • Nara 2017年8月13日凌晨1:34 #

            哦,那么使用 ARIMA 残差的混合模型进行 RNN 应该效果很好吧?🙂
            残差将没有任何季节性成分。(即使缩放也应该得到很好的处理)。
            或者在这里您也期望 MLP 表现更好吗?

          • Jason Brownlee 2017年8月13日凌晨9:55 #

            很难确定,我建议使用实验来收集数据以确切了解,而不是猜测。

  25. Nights 2017年8月13日 上午5:37 #

    我认为在进行多步预测的逆差分时存在问题(以处理非平稳数据)。
    此示例将先前预测的(并已进行逆差分)值添加到当前预测值。如果我们有30个点需要预测,这种方法是否是错误的,因为它会不断累加结果,从而导致输出持续增加?

    下面是我得到的结果。
    https://ibb.co/d1oyNF

    我是否应该只将最后一个已知的真实观测值添加到所有预测值中?我猜这可能也不奏效。

    • Jason Brownlee 2017年8月13日 上午9:58 #

      对于长超前时间,这可能是一个问题,因为误差会累积。

      如果真实观测值可用于逆差分,您将不需要进行如此长的超前时间预测,该问题也就无关紧要了。

      考虑对比有差分和无差分的模型技能,至少作为起点。

  26. Sandra 2017年8月14日 下午5:46 #

    你好,感谢你精彩的教程。

    关于序列到序列的时间序列预测问题,我有一个关于多步 LSTM 的问题。

    我创建了一个监督数据集,包含 (t-1), (t-2), (t-3)…, (t-look_back) 和 (t+1), (t+2), (t+3)…, (t+look_ahead),我们的目标是预测 look_ahead 个时间步。

    我们尝试了你完整的示例代码,将最后一个层设置为 Dense(look_ahead),但结果并不理想。这是使用有状态和无状态网络都进行的。

    然后我们尝试使用 Dense(1) 再 repeatvector(look_ahead),我们得到所有 look_ahead 时间步的(平均)相同值。这是使用无状态网络进行的。

    然后我创建了一个逐步预测,其中 look_ahead 始终为 1。那么 t+2 的预测是基于 (t+1)(t)(t-1)… 的历史。这给了我更好的结果,但只尝试了无状态网络。

    我的问题是
    – 使用非状态网络是否可以与 repeatvector 一起使用?或者网络必须是有状态的?您是否知道我的预测值为何都相同?
    – 您推荐哪种网络来处理这类问题?有状态还是无状态,序列到序列还是逐步预测?

    提前感谢!
    Sandra

    • Jason Brownlee 2017年8月15日 上午6:32 #

      Sandra,你的工作很棒,谢谢分享。

      RepeatVector 仅用于编码器-解码器架构,以确保输出序列中的每个时间步都能访问编码器中的整个固定宽度编码向量。它与有状态或无状态模型无关。

      我会开发一个简单的 MLP 基线,并带有向量输出,并挑战所有 LSTM 架构来超越它。我会查看简单 LSTM 和序列到序列模型的向量输出。我也会尝试递归模型(将输出作为输入重复一步预测)。

      听起来你正在尝试所有正确的事情。

      现在,说了这么多,LSTM 可能不擅长简单的自回归问题。我经常发现 MLP 在自回归方面的表现优于 LSTM。请参阅这篇帖子
      https://machinelearning.org.cn/suitability-long-short-term-memory-networks-time-series-forecasting/

      希望这有帮助,请告诉我进展如何。

  27. Oscar 2017年8月16日 上午1:28 #

    嗨,Jason,
    感谢您的教程。我正在学习机器学习,您的网站非常有帮助!

    我对 inverse_difference 函数有点困惑。特别是需要传递的 last_ob。

    假设我有以下数据

    原始数据 差分 缩放后的预测值
    raw_val1=.4
    raw_val2=.35 -.05 -.045 [0.80048585, 0.59788215, -0.13518856]
    raw_val3=.29 -.06 -.054 [0.65341175, 0.37566081, -0.14706305]
    raw_val4=.28 -.01 -.009 [[0.563694, -0.09381149, 0.03976132]

    当将 last_ob 传递给 inverse_difference 函数时,我需要将哪个观测值传递给函数,raw_val2 还是 raw_val1?

    我的猜测是我需要传递 raw_val2。这正确吗?

    另外,在您的示例中,在这一行

    forecasts = inverse_transform(series, forecasts, scaler, n_test+2)

    为什么是 n_test+2 呢?

    提前感谢!
    Oscar

  28. Jaskaran 2017年8月17日 上午10:57 #

    嗨,Jason,
    做得很好。

    我有一个问题。在为 lstm 重塑 X 时(样本数,时间步长,特征数),为什么您将问题建模为时间步长=1 和特征数=X.shape[1]?难道不应该是时间步长 = 滞后窗口大小
    并且输出的密集层应该具有视野窗口的大小。我认为这样会得到更好的结果。

    这是一个链接,可以更清楚地说明我的问题
    https://stackoverflow.com/questions/42585356/how-to-construct-input-data-to-lstm-for-time-series-multi-step-horizon-with-exte

    • Jason Brownlee 2017年8月17日 下午4:54 #

      我以没有时间步长和大量特征(同一时间点的多个观测值)的方式对问题进行建模。

      我发现,如果以多个时间步长和多个特征来构建问题,性能会更差。基本上,我们在这里将 LSTM 用作 MLP 型网络。

      LSTM 在自回归方面并不擅长,但这篇帖子是我有过最多人询问的。

      更多关于 LSTM 适用性的信息在这里
      https://machinelearning.org.cn/suitability-long-short-term-memory-networks-time-series-forecasting/

      • Jaskaran 2017年8月18日 上午5:59 #

        所以 Jason,

        如果我没理解错的话,RNN+LSTM 学习随时间(隐藏状态取决于过去的值)的全部意义在这里就消失了。

        本质上,这只是一个自回归神经网络。没有随时间的存储状态。

  29. hanoun 2017年8月18日 上午11:37 #

    嗨,我尝试使用这个例子来识别形状变化的角度,这个教程有用吗?我应该如何测试我训练的模型?
    此致,
    Hanen

  30. A 2017年8月19日 上午7:53 #

    嗨——我喜欢你的博客和这些教程!它们非常有帮助。

    我一直在学习这个教程和这个教程:https://machinelearning.org.cn/time-series-prediction-lstm-recurrent-neural-networks-python-keras/
    我已经将两个代码应用到我正在处理的一个简单数据集中(日期、ROI%)。两个代码都能很好地处理我的数据,但我遇到了一个让我完全困惑的问题

    使用此代码,我能够实际预测未来的 ROI%。而使用另一个代码,它在建模历史数据方面做得更好,但我无法弄清楚如何让它预测未来。两个代码都有我需要的元素,但我似乎无法弄清楚如何将它们结合起来。

    任何见解都将是极好的!谢谢!

  31. Ankit 2017年8月22日 上午11:34 #

    Jason,首先,我想感谢您所做的工作。它非常有帮助。

    我有一个问题,正在寻求您的专家意见。

    如何处理一个具有多个且可变粒度输入的单时间步长的时间序列数据集。例如,考虑下面的数据集

    日期 | 区域 | 产品类别 | 订单 | 收入 | 成本

    因此,在这种情况下,一天会有多个记录,按日期汇总,这也是我想要的粒度。

    应该如何处理这类数据,因为这些特征将贡献于收入和订单?

    • Jason Brownlee 2017年8月23日 上午6:53 #

      您可以标准化数据并将其输入一个模型,或者构建单独的模型并组合它们的预测。

      尝试几种方法,看看哪种最适合您的问题。

  32. Daniel 2017年8月24日 上午2:07 #

    我正在使用这个框架进行第一次 LSTM 网络尝试,用于监控网络响应时间。我目前正在处理的数据是通过模拟 API 调用随机生成的。我看到 LSTM 似乎总是预测会回到看起来像数据均值的地方。这是随机数据的一个特性吗?

    另外一个问题:由于 LSTM 的神经元内置了记忆组件,使用较大的 n_in/n_lag(大于 1)有什么优点/缺点?

    • Jason Brownlee 2017年8月24日 上午6:48 #

      问题可能对您的模型来说太难了,也许可以调整 LSTM 或尝试其他算法?

      LSTM 的一个关键优势是它们的滞后可以比其他方法长得多,例如数百个时间步。这意味着您正在模拟这样的东西

      yhat = f(t-1, …, t-500)

      并且模型可以根据需要重现它在 500 个时间步之前看到的东西。

      • Daniel 2017年8月26日 上午3:34 #

        谢谢。我现在正在使用一些玩具数据,只是为了确保我理解它是如何工作的。

        我能够很好地用 5 个神经元、100 个 epoch 的训练运行来模拟余弦波,处理 np.cos(range(100)) 并将其分成 80/20 的训练集。这是在进行缩放但没有进行差分的情况下。我输入 10 个输入,得到 30 个输出。

        调用 model.predict 会改变模型吗?我用相同的 10 个输入反复调用,每次都得到不同的结果。看起来预测的波形在不同的幅度之间循环。

        • Daniel 2017年8月26日 上午4:09 #

          啊,明白了。由于 stateful 为 True,我需要在预测之间显式调用 reset_states()。有道理,我想!Stateful 对于训练很有用,但由于我不会进行“在线学习”,并且我会在特征中馈送滞后,因此在预测时不应该依赖状态。

        • Jason Brownlee 2017年8月26日 上午6:48 #

          干得好!

          是的,通常缩放很重要,但如果您的余弦波值在 [0,1] 范围内,那么您就没问题了。

      • Daniel 2017年8月26日 上午6:03 #

        我有一个简单的问题。我试图设置一个不同的玩具问题,数据生成方式为 y=x,共 800 个点(保留接下来的 200 个作为验证集)。无论我训练多少层、多少神经元、多少个 epoch,结果似乎都是预测值在较低值时接近直线,但在较高值时迅速发散并接近某个固定值 y=400。

        您对此有何看法?

        • Jason Brownlee 2017年8月26日 上午6:51 #

          可能是误差累积。您给 LSTM 带来了麻烦。

  33. Daniel 2017年9月1日 上午2:47 #

    您能否就我遇到的这个问题提供一些意见?我真的很想确保我没有错误地实现。如果我需要调整网络参数,我可以进行练习。但是,我对我在这条正确的道路上的情况没有信心。 https://stackoverflow.com/questions/45982445/keras-lstm-time-series-multi-step-predictions-has-same-output-for-any-input

  34. lucius 2017年9月1日 下午6:14 #

    你好,代码有问题。在进行数据处理时,即计算差分和最小-最大缩放。您不应该使用所有数据。在更真实的情况下,您只能对训练数据进行此操作。因为您不了解测试数据。

    所以我修改了代码,将最后 12 个月作为测试集。然后只使用 24 个月的数据进行差分、最小-最大缩放、拟合模型并预测第 25、26、27 个月。

    然后我继续使用 25 个月的数据进行差分、最小-最大缩放、拟合模型并预测第 26、27、28 个月。

    最终结果比基线差!

    • Jason Brownlee 2017年9月2日 上午6:04 #

      没错,这是我为保持教程简短易懂而进行的简化。

  35. Eldar M. 2017年9月17日 上午1:47 #

    Jason,您好,我使用自定义损失函数(加权 MSE)取得了一些更好的结果

    def weighted_mse(yTrue,yPred)

    ones = K.ones_like(yTrue[0,:])
    idx = K.cumsum(ones)
    return K.mean((1/idx)*K.square(yTrue-yPred))

    功劳归于 Stack Overflow 上的 Daniel Möller,因为我无法自己弄清楚张量修改步骤,他在那里回答了我的问题

  36. Alex 2017年9月23日 上午1:53 #

    def make_forecasts(model, n_batch, train, test, n_lag, n_seq)
    forecasts = list()
    for i in range(len(test))
    X, y = test[i, 0:n_lag], test[i, n_lag:]
    # 进行预测
    forecast = forecast_lstm(model, X, n_batch)
    # 存储预测结果
    forecasts.append(forecast)
    return forecasts

    如果“train”数据集作为参数传递给这个函数,但它没有被使用,那么它的作用是什么?
    谢谢

    • Jason Brownlee 2017年9月23日 上午5:43 #

      是的,看起来它没有被使用。你可能可以删除它。

  37. Fei 2017年9月24日 上午1:51 #

    您好,这是一个非常有用的教程。我是 Python 和编程的初学者。我能否将模型的输入转换为 4 个或更多变量?并且将 n_batch 更改为非 1 的其他数字?

  38. Fei 2017年9月26日 上午4:33 #

    但是,当我更改 n_batch 大小时,模型就不工作了。另外,您手动指定了模型的 epoch,您能否告诉我如何做?

  39. Fabian 2017年9月29日 下午7:41 #

    嗨,Jason,
    非常感谢您关于 LSTM 的教程。
    您对如何为多元多步预测建模网络有什么建议吗?我读了您关于多元预测和多步预测的文章,但将两者结合起来似乎更棘手,因为密集层的输出维度会更高。

    用您这里的例子来说:如果我想在 T 时间步后预测洗发水和牙膏的销售量,我该如何实现预测维度为 2xT?密集层有替代方案吗?

    • Jason Brownlee 2017年9月30日 上午7:38 #

      我明白了。您可以在网络的输出层中有两个神经元,就这样。

  40. Camille 2017年9月30日 上午9:07 #

    感谢这个精彩的教程。您认为这项技术适用于多对多预测吗?

    一个玩具场景:想象一台机器有 5 个调谐旋钮 [x1, x2, x3, x4, x5],作为结果,我们可以读出 2 个值 [y, z],作为对任何旋钮变化的响应。

    我想知道我是否可以使用 LSTM 来预测 y 和 z,用一个模型而不是为 y 构建一个模型,为 z 构建另一个模型?我计划遵循这个教程,但我很想听听您对此的看法。

  41. Jean-Marc 2017年9月30日 下午12:08 #

    嗨 Jason,非常感谢您的教程。我刚开始学习 LSTM,您关于 LSTM 的系列非常有价值。
    关于多输出预测的一个问题:如何处理多输出时绘制真实数据与预测数据的对比。
    假设我有一个模型来预测接下来的 10 个时间步(t, t+1…,t+9)。
    使用时间 t 的观测值
    –> t=0,模型将给出 t=1,2,3,4,5,6,7,8,9,10 的预测
    同样,在
    –> t=1,将输出 t=2,3,4,5,6,7,8,9,10,11 的预测
    等等…
    从 t=0 和 t=1 的预测在时间步上有重叠。例如,如果我想知道 t=2 的值,我应该使用 t=1 的预测还是 t=0 的预测,或者预测的加权平均值?

    也许只使用 t=1 的预测就足够了,因为它已经包含了时间序列的历史(即它已经包含了 t=0 的观测值)。

    • Jason Brownlee 2017年10月1日 上午9:06 #

      我不确定我是否理解。也许您最好先从线性模型开始,然后迁移到 LSTM 以提高在已经奏效的框架/问题上的技能。
      https://machinelearning.org.cn/start-here/#timeseries

    • Kai Ding 2019年2月15日 上午2:09 #

      你好 Jean-Marc

      “例如,如果我想知道 t=2 的值,我应该使用 t=1 的预测还是 t=0 的预测,或者预测的加权平均值?”

      我也有同样的问题,您知道如何解决这个“重叠”问题吗?

      • Jason Brownlee 2019年2月15日 上午8:10 #

        我不确定我是否理解,您能详细说明您想通过一个例子来实现什么吗?例如,输入和输出?

  42. mr 2017年10月1日 下午9:53 #

    The
    return datetime.strptime('190'+x, '%Y-%m')

    它给我

    ValueError: time data ‘1901/1’ does not match format ‘%Y-%m’

    提前感谢

  43. wmbm 2017年10月4日 下午10:29 #

    所以您实际上不需要将数据分割成测试集和训练集,因为您在这段代码中不使用训练集。那么这就变成了一个无监督问题吗?

  44. Noah yao 2017年10月16日 下午2:33 #

    抱歉,我对 inverse_transform 函数感到困惑,为什么您在函数中使用 n_test+2 而不是 n_test?

  45. RRighart 2017年10月20日 下午9:12 #

    嗨,Jason,

    非常感谢您发表如此精彩的博文!

    您解释说将使用“滚动预测场景”,也称为前向模型验证。您说“测试数据集的每个时间步将逐一进行。将使用一个模型来预测该时间步,然后将从测试集中获取下一个月的实际预期值,并将其提供给模型以进行下一个时间步的预测”。

    在这种没有此类测试/验证数据的情况下,您会建议使用哪种方法/算法?换句话说,我有一系列时间序列数据,在某个点停止了,我需要预测接下来的点。

    提前感谢您的建议!

  46. Prakash Anand 2017年10月21日 晚上10:57 #

    嗨,Jason,

    感谢这个精彩的教程。我正在尝试解决一个问题,并希望得到您的意见,该问题大致如下。我拥有两年的每日销售数据,以及一些其他预测变量,如节假日、促销等。假设从2015年1月到2017年1月。我想预测2月份。我正在考虑数据准备,将过去60天的数据作为输入序列,并预测接下来的30个时间步。由于数据集非常小,您认为这会奏效吗?您有什么建议?

    • Jason Brownlee 2017年10月22日 上午5:21 #

      试试看。

      通常,除非您有大量数据或问题相对简单,否则提前预测30天是非常困难的。

      • Prakash Anand 2017年10月22日 上午6:24 #

        是的,这也是我的担忧。因为数据集非常小。

  47. Bryant 2017年10月24日 下午8:12 #

    Bryant 2017年10月24日晚上8:12 #
    我有两个问题:
    1.在此示例中,导出了三个RMSE。如果我想输出每个时间步的三个预测并将所有输出整合到一个数据框(易于观察)中,我该怎么办?
    2.如果我需要进行6个月、12个月的预测,该如何更改?
    抱歉,我的Python不是很好。
    非常感谢!

  48. Derrick 2017年10月25日 上午1:29 #

    嗨,Jason,

    我正在学习您的教程,但在“prepare_data”函数中的重塑时遇到了问题。

    我目前使用的数据形状如下
    (156960, 3)

    但是prepare_data函数中的重塑告诉我这个

    ValueError 回溯 (最近一次调用)
    in ()
    —-> 1 train, test = prepare_data(X, 15696, 2, 4)

    在prepare_data(series, n_test, n_lag, n_seq)
    3 # 提取原始值
    4 raw_values = series.values
    —-> 5 raw_values = raw_values.reshape(len(raw_values), 1)
    6 # 转换为监督学习问题 X, y
    7 supervised = series_to_supervised(raw_values, n_lag, n_seq)

    ValueError: cannot reshape array of size 470880 into shape (156960,1)

    这个数组大小470880是156960(我的数据长度)的三倍。

    您能给我一些建议如何解决这个问题吗?

  49. Kishore Kumar 2017年11月11日 晚上8:17 #

    嗨,Jason,

    我是机器学习的初学者。这些教程对我学习和提高帮助很大。非常感谢您发布您所有的探索。

    现在我有一个问题想问您,

    本例中有36个月的数据。现在我需要知道第37个月的预测。我该如何在模型中进行预测?

    在预测之前,我是否应该重塑新值,还是直接将新数据注入预测模型?

    例如。
    new_data = 145
    predicted_output = model.predict(new_data, verbose = 0)

    (或者)

    new_data = 145
    x = x.reshape(1,1,1)
    predicted_output = model.predict(x, verbose = 0)

    (或者)

    我们是否需要任何其他方法来做到这一点?

    注意:根据您的回答,我想预测4个月。

    提前感谢您的时间和帮助

    • Jason Brownlee 2017年11月12日 上午9:04 #

      这篇帖子提供了更多关于如何重塑输入数据的建议
      https://machinelearning.org.cn/reshape-input-data-long-short-term-memory-networks-keras/

      这篇帖子展示了如何为最终的LSTM模型进行预测
      https://machinelearning.org.cn/make-predictions-long-short-term-memory-models-keras/

      • Kishore Kumar 2017年11月12日 晚上8:24 #

        谢谢你的回复。

        当我保存模型并尝试预测已加载的模型时,我看到两个不同的预测结果。

        但是,在保存模型之前无限次运行模型时,预测结果是相同的。

        使用已保存和加载的模型,每次运行已加载的模型时,结果都是相同的预测输出。

        问题是,在保存模型之前提供的结果与已加载的模型不匹配/不相同。

        看起来在保存模型时,训练模型内部发生了某些变化。
        在保存模型之前,它提供98%的准确率。而在保存模型后,当尝试预测时,它给出90%的准确率。

        您能否帮助我弄清这个疑问。我已在此处提供代码片段及输出。此保存和加载模型的代码片段来自同一个Python程序,而不是多个Python脚本。

        注意:我正在尝试使用不同的数据集,该数据集包含小数价格,与本教程数据集类似。

        程序代码
        #########################################
        value = [ 0.0568]
        value = array(value)
        value = value.reshape(1, 1, len(value))
        predicted_example = model.predict(value, batch_size=1, verbose = 0)
        print (“predicted example %s” % predicted_example)

        model.save(‘saved_keras_model_1.h5’)

        model_storage_1 = load_model(‘saved_keras_model_1.h5’)

        predicted_example_1 = model_storage_1.predict(value, batch_size=1, verbose = 0)

        print (“predicted example_1 %s” % predicted_example_1)

        #######################################################

        收到的输出

        predicted example [[-0.0193442 0.01113211 -0.00196517 0.00191608 -0.00315076 0.0080449]]

        predicted example_1 [[-0.02511037 0.01445036 -0.00255096 0.00248715 -0.00408998 0.0104428]]

        • Jason Brownlee 2017年11月13日 上午10:15 #

          这很有趣。

          我没有什么好主意。如果这是任务关键的,我建议设计实验来进一步探究该效果的原因和限制。

          • Kishore Kumar 2017年11月13日 晚上9:32 #

            没关系。为什么这些预测值有正有负?它意味着什么?我们需要进一步将其转换为其他函数或进行任何操作吗?

  50. jiawenqi 2017年11月13日 晚上7:47 #

    model.add(LSTM(n_neurons, batch_input_shape=(n_batch, X.shape[1], X.shape[2]), stateful=True))
    当 X.shape[1] =1 时,step=1。LSTM 可能失去意义,因为它将变成一个回归模型。

  51. Abdur Rehman Nadeem 2017年12月1日 上午11:06 #

    嗨,Jason,

    您的博客非常好。我从中学到了很多,并且仍在学习。

    我正尝试将推文情感与一些数值特征(例如价格、成交量)一起应用于LSTM,但尚未成功。我阅读了一些博客和论文,但到处都是推文和数值特征分开输入,而我想将它们都作为特征向量输入。
    有什么好的建议吗?

    此致,

  52. ktr 2017年12月1日 晚上9:39 #

    谢谢你,Jason。
    我一直在学习您的教程,这些教程非常有用和
    清晰——即使对于非Python程序员来说,在这篇教程中,我有点迷失在
    “拟合LSTM网络。我担心“固定时间步为1”。

    当时间步长大小不恒定时该怎么办?一个具体的例子:我正在
    驾驶,每五分钟记录我的位置、加速度、方向和时间。
    由于各种原因,五分钟只是近似值。另外,有时我会丢失GPS,
    因此会错过一个或几个记录。

    显然,位置取决于时间。我应该重新采样所有记录,使时间段均匀吗?我应该插值来提供缺失的值吗?如果我晚上停止怎么办?我能否以某种方式将两天的数��拼接在一起?

    第二个问题:在这篇教程中,您在哪里为模型提供了惩罚反馈?我想使用一个不对称函数。(如果我想开车到悬崖边,走得太远比差一点点到达要糟糕得多。)

    谢谢

  53. Vino Jose 2017年12月5日 上午1:33 #

    感谢 Jason 提供精彩的博文。您能否提示一下如何为此多元输入进行多步预测?

  54. Vino Jose 2017年12月10日 晚上5:14 #

    我需要预测一个应用程序的性能。输入将是应用程序过去性能数据的时序列、托管应用程序的服务器的CPU使用率数据、内存使用率数据、网络带宽使用率等。我正在尝试使用LSTM构建一个解决方案,该解决方案将接收这些输入数据并预测该应用程序未来一周的性能。我遵循了您的博文“https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/”,并理解了如何处理多元数据。我现在卡在了预测未来多个时间步的部分,也就是应用程序未来一周的性能。尽管多步预测在单变量时间序列示例中对我来说是有效的,但在这里却不起作用。不确定我遗漏了什么。您能否就此提供一些指导?

    • Jason Brownlee 2017年12月11日 上午5:24 #

      具体问题是什么?您在哪里遇到了困难?

      • Vino Jose 2017年12月12日 晚上9:51 #

        预测结果中只有一个数据点,而我期望的是一周的数据点。

  55. G Flash 2017年12月12日 晚上7:57 #

    嗨,Jason,

    感谢您提供如此出色的博文!我有一个关于多步预测的普遍问题。据我理解,您对 t+3 的预测与 t+2 的预测是独立的,而 t+2 的预测又与 t+1 的预测是独立的。

    考虑将之前的预测反馈到网络中是否有意义?如果有,这样的模型叫什么?

  56. Yang 2017年12月27日 晚上6:15 #

    嗨,Jason,
    感谢精彩的教程!我对预测有几个问题。如果我处理的数据集大约有6000个观测值,那么进行从 t+1 到 t+500 的预测(如果 n_test=1)是否有意义?
    顺便说一句,在绘制预测时,最后一个数据点有一个小的偏移。这是从序列到监督转换的结果吗?也许我弄错了什么。

    谢谢

  57. Andreas 2018年1月16日 上午6:10 #

    你好,

    将我们要预测的时间步长(t+k)也作为模型的输入是否会更有益?因为目前我们考虑n_seq指定的范围内的所有数据点,将它们视为“离预测起点相同的时间步长”。

    致以最诚挚的问候和感谢,
    Andreas

  58. Martin 2018年1月29日 上午8:35 #

    嗨 Jason
    非常感谢您非常有用的教程。我将非常乐意获得有关此问题的帮助
    给定一个有20个输入变量和一个输出变量的时间序列。
    序列长度约为500个样本。对于20个变量中的5个,也有未来样本可用。(50个样本)。我想知道如何利用这5个变量的未来值来改进预测。
    非常感谢您的有用提示。
    此致

    • Jason Brownlee 2018年1月30日 上午9:44 #

      您所说的“未来样本”是什么意思?

      • Martin 2018年2月6日 上午4:46 #

        嗨 Jason

        对于20个输入变量中的5个(x1..x5),我已经有了未来50个时间步的值。(这些值是给定的)。所以不需要预测它们,但我想利用它们来改进(一个)输出变量y的预测。(也不需要预测其他15个输入值x6-x20)

        x1….x5, x6..x20, y
        t0 1, .. 2, 4, .. 7, 10
        t1 1, .. 3, 4, .. 5, 11
        ..
        t500 2, … 5, 5, … 8, 14
        t501 2, … 4, ?????? ?
        ..
        t550 2, … 3, ?????? ?

        提前感谢
        马丁

  59. Mohammad 2018年2月6日 上午5:59 #

    亲爱的 Jason,感谢您提供的精彩代码和解释,我有一个问题想问您。在这种情况下,一个人想要估计未来多步预测,对吗?例如提前10步。但是这10个步骤都是未知的。模型应该在不使用实际值的情况下找到它们。但在这里,我在测试集或训练集中看到的是,模型在考虑实际值而不是预测值的情况下估算数据点。
    让我们一起看一些数据
    [[ 342.3 339.7 440.4 315.9]
    [ 339.7 440.4 315.9 439.3]
    [ 440.4 315.9 439.3 401.3]]

    假设模型预测第一行 [ 342.3 339.7 440.4 315.9] 的预测值为439.4,但实际的正确值为439.3(我们不知道!)。所以在第二行,我们应该考虑 [ 339.7 440.4 315.9 439.4],而不是 [ 339.7 440.4 315.9 439.3]。

    请向我详细说明。

    • Jason Brownlee 2018年2月6日 上午9:23 #

      当然,具体问题是什么?

      • Mohammad 2018年2月6日 上午11:36 #

        问题是这样的,当您说这种方法能够进行多步预测时,您指的是以下哪一种?
        1) 这种方法不使用未来信息(无实际值),只使用自己的预测
        2) 这种方法预测下一步的一个点并计算误差,但忽略该预测,并使用该点的实际值(真实值)进行后续步骤的预测。

        我相信这里的模型是第二种,对吗?
        我想确保。

        我担心这里显示的好结果是因为模型看到了测试集中的结果。

        换句话说,模型预测一月份的洗发水价格为1000,但实际价格为1200。对于二月份的预测,模型使用的是1200(正确价格),而不是它预测的1000。

        一段时间后,差异会变得很大。

  60. Lak 2018年2月22日 上午4:45 #

    嗨,Jason,

    感谢您发布这个精彩的教程。您能否检查一下在完整代码的第172行和第174行中使用(n_test + 2)的计算是否正确?

    我认为应该是(n_test-n_lag+2)。这将是11而不是12。

    举个例子

    d: 差值,其中 d[i] = d[i+1] – d[i]
    f: 预测
    s: 原始序列

    训练数据是
    d0 : d1,d2,d3
    d1: d2,d3,d4
    .
    .
    d21: d22,d23,d24

    测试数据
    d22: d23,d24,d25
    .
    .
    d31:d32,d33,d34

    forecast[0] = f_d23,f_d24,f_d25

    f_d23 应该是 s24-s23 => s24 = f_d23 + s23

    所以 last_ob 的值是 s23,但您的代码给出 s22。

    这可以通过使用 (n_test – n_lag + 2) 来纠正。

    如果我有什么误解,请告诉我。

    感谢您的时间!

    Lak

    • Lak 2018年2月22日 上午7:38 #

      实际上,通用形式应该是 inverse_transform 的 (n_test+n_seq),plotting 的 (n_test+n_seq-n_lag)。

  61. Monty Shaw 2018年3月7日 下午12:29 #

    您能展示如何添加另一层LSTM吗?我试着只复制Model.Add(LSTM line),但会收到一个关于期望3维但只得到2维的错误

    另外,我正在参加您的7天课程(尽管比7天慢一些)

    谢谢

      • Sebastian Olbrich 2018年6月5日 上午8:19 #

        Jason,非常感谢您的辛勤工作!它在过去几个月里给了我很大的帮助。
        然而,我在我使用的其他LSTM模型中成功地添加了层。不过,我无法在上面的代码中添加层,因为LSTM的拟合被包装在一个单独的函数中。每次我向代码中添加LSTM层时,都会出现

        IndentationError: unindent does not match any outer indentation level

        错误。
        有什么想法吗?我可以重写代码并解决您的“def fit_lstm”,尽管这会让代码变得很难看。那么,如何在不这样做的情况下实现更多层呢?

        提前感谢……
        请继续,您正在做一件很棒的事情!

        Sebastian

  62. char 2018年3月10日 上午8:25 #

    这个例子只使用了一个时间步来预测接下来的3个时间步?要使用更多时间步进行预测,series_to_supervised的n_in参数是否应该大于1?另外,n_in和n_out参数是否对应于您在其他LSTM预测文章中的lag和seq参数?谢谢。

  63. MLT 2018年3月11日 晚上7:49 #

    嗨,Jason,

    我尝试调整您的代码中的参数以优化结果。首先,我检查是否有欠拟合或过拟合。

    我在您的程序中添加了以下代码。

    history = model.fit(X, y, epochs=1, batch_size=n_batch, verbose=1, shuffle=False, validation_data=(X_test, y_test))
    loss.append(history.history[‘loss’])
    val_loss.append(history.history[‘val_loss’])

    22/22 [==============================] – 0s 2ms/step – loss: 0.0988 – val_loss: 0.2584
    t+1 RMSE: 90.210739
    t+2 RMSE: 79.713680
    t+3 RMSE: 107.812684

    看起来验证损失远高于训练损失。我做了一个测试,使用线性激活函数将数据重缩放到(0, 1)。

    scaler = MinMaxScaler(feature_range=(0, 1))
    model.add(LSTM(n_neurons, activation=’linear’, batch_input_shape=(n_batch, X.shape[1], X.shape[2]), stateful=True))
    model.add(Dense(y.shape[1], activation=’linear’))

    我运行了两次。结果大相径庭。请允许我在此提出两个问题?
    1. 为什么结果与相同代码相比非常不稳定?
    运行 1 t+2 RMSE: 123.765729 几乎是运行 2 t+2 RMSE: 69.944902 的两倍。

    2. 指标显示了更好的改进(更改后的版本 loss: 0.0248 – val_loss: 0.0709 vs loss: 0.0988 – val_loss: 0.2584),但 RMSE 没有显示太大改进(更改后的版本 t+2 RMSE: 69.944902 vs t+2 RMSE: 79.713680)。

    运行 1
    22/22 [==============================] – 0s 2ms/step – loss: 0.0241 – val_loss: 0.0651
    t+1 RMSE: 158.873657
    t+2 RMSE: 123.765729
    t+3 RMSE: 186.785670

    运行 2
    22/22 [==============================] – 0s 2ms/step – loss: 0.0248 – val_loss: 0.0709
    t+1 RMSE: 93.477638
    t+2 RMSE: 69.944902
    t+3 RMSE: 113.995648

    提前感谢。

    • Jason Brownlee 2018年3月12日 上午6:29 #

      关于模型技能的高方差,也许模型对于问题来说指定不足。也许模型对问题拟合得很差。

  64. char 2018年3月13日 上午5:34 #

    差分反差会不会导致数据少一个?例如,对 [5,4,3,2,1] 进行差分会产生 [1,1,1,1],但反差只会产生 [4,3,2,1]。

    • Jason Brownlee 2018年3月13日 上午6:32 #

      是的,第一个观测值丢失了(我想)。

      • char 2018年3月14日 上午12:52 #

        如何只预测最后一个时间步?看起来你只预测到 t-2 时间步(从图中看)。谢谢!

        • char 2018年3月14日 上午3:35 #

          根据上面一些评论的阅读,似乎 n_test+2 应该是 n_test+n_seq-1(无论 n_seq 是多少)。这看起来像是预测从最后一步开始的。你能确认一下吗?

  65. MLT 2018年3月14日 下午9:01 #

    嗨,Jason,

    对于在线训练,如何用最新数据更新模型?谢谢。

    我可以输入最新一个月的 new_X 和 new_y 来拟合模型,并且永不重置模型的 states 吗?或者有更好的方法吗?谢谢。

    例如,模型是用一年前到五月的数据训练的。
    在七月,我有六月的销售数据。New_X 是五月的销售额,new_y 是六月的销售额。

    model.fit(new_X, new_y, epochs=1, batch_size=1, verbose=0, shuffle=False)

    July_sales = model.predict(new_y, 1) # new_y 是六月的销售额。

  66. Mark Stevenson 2018年3月17日 上午3:08 #

    嗨,Jason,

    非常感谢您的发布。我有一个快速的问题。我正在将此模型用于一些市场数据。当我使用 n_seq = 3 时,“实际”值与我的数据一致。当我将 n_seq 更改为 5 时,“实际”值的输出与我的数据集中任何内容都不对应,尽管它很相似。可能是什么原因造成的?

    再次感谢,

    Mark Stevenson

    • Jason Brownlee 2018年3月17日 上午8:44 #

      模型需要针对您的具体问题进行调整。

  67. Haylee Ham 2018年3月27日 上午5:07 #

    我也想将其应用于多元时间序列预测,并已阅读了您的多元文章(https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/)。

    我感兴趣的是预测天然气价格。因此,我感兴趣的输出只有一个变量,但我输入了大约 15 个变量。为了预测一个以上的时间周期,我是否需要训练 LSTM 来预测所有变量(输入和输出),而不仅仅是我的输出变量天然气价格?

    非常感谢。

    • Jason Brownlee 2018年3月27日 上午6:41 #

      不,您可以根据自己的意愿构建问题。

      在另一篇文章中,我们使用多个输入来预测一个输出,您可以将其扩展为预测单个输出特征的序列。

      • Haylee Ham 2018年3月27日 上午8:51 #

        谢谢回复!

        为了做到这一点,我会将问题设置为每行数据分别为天然气价格的 t、t+1、t+2 等,然后是所有输入变量的 t-1 吗?

        您是否有详细介绍此输出序列方法的帖子?

        • Jason Brownlee 2018年3月27日 下午4:16 #

          是的,这篇帖子(上面)展示了如何输出序列。

  68. Jenny 2018年4月3日 下午1:10 #

    嗨 Jason!感谢这篇精彩的文章!
    我想知道在使用 LSTM 之前是否需要去除季节性。

    • Jason Brownlee 2018年4月4日 上午6:04 #

      我推荐这样做。任何使问题更容易建模的事情都是好事。

  69. Marco 2018年4月6日 上午1:27 #

    嗨 Jason,在您的代码中,您使用了批量大小为 1,因为您只有少量数据。在我的情况下,我有更多的数据,所以我希望使用更大的批量大小。我只是想了解一件事,如果我使用的批量大小为 72,例如,我是否也必须更改 make forecast 函数,因为在您的示例中,我使用了一个 for 循环来一次进行一个示例的预测,而在我的情况下,我应该一次进行 72 个示例的预测?这是正确的吗?

    • Jason Brownlee 2018年4月6日 上午6:32 #

      批量是样本的集合。

      也许您指的是给定样本/序列的时间步长?

  70. Eric 2018年4月26日 上午3:48 #

    嗨,Jason,

    感谢所有精彩的内容——非常有帮助且全面。

    我正在尝试理解如何推广输入整形以适应变化的 1)特征数量和 2)滞后。

    在上面的例子中,您执行
    X = X.reshape(X.shape[0], 1, X.shape[1])

    其中 X.shape[0] 代表 X 中的行数(样本),1 是硬编码的,因为我们只查看前一个时间步进行预测,而 X.shape[1] 代表 X 中的列数(仅当我们查看 1 个前时间步时,它才代表特征数量)。

    如果我们考虑的滞后时间超过一个时间步,我们将不得不更改重塑的第二和第三个组件,对吗?例如,假设在上面的示例中我们考虑滞后 3。那么我们的监督 X 数据集将有 3 列。但这仍然是技术上一个原始特征(洗发水销量),只是分布在 3 个时间步上。所以我们需要的重塑应该是 X.reshape(X.shape[0],3,1),对吗?

    谢谢!

  71. Han Yi 2018年5月7日 上午12:52 #

    你好,布朗利博士!
    感谢您的分享。这非常有帮助。
    我最近在尝试使用多步 LSTM 进行预测时遇到一个问题。
    我的训练集中的时间序列大约有 3000 天。但是,我需要预测未来 600 天。此外,还需要考虑每天的另外 8 个有用特征。
    我使用了您介绍的递归多步预测(t-3, t-2, t-1 用于 t+1),但结果非常糟糕。
    您能否给我一些关于这个问题的建议?

  72. Mo 2018年5月11日 上午9:39 #

    你好!我认为您已经做出了我所见过(我见过一些)的最好、最易读、最可扩展的 LSTM RNN 示例!

    只有一个建议:我认为最好在代码中更改以下行

    plot_forecasts(mid_prices, forecasts, n_test+2)

    推广到

    plot_forecasts(mid_prices, forecasts, n_test + (n_seq – 1))

    因为它现在考虑了为任何数量的预测(n_seq)保留的观测数量。

    再次感谢!

  73. Andrea 2018年5月21日 上午2:57 #

    嗨,Jason,

    非常感谢您的教程。
    它们非常有用且具有教育意义。

    我有一个问题,这可能很愚蠢,但我不太明白 LSTM 如何实际评估预测。

    我可以看到您设置了 n_lag=1,并且该值用于在 make_forecasts 方法中分割测试集。

    您写道:
    >X, y = test[i, 0:n_lag], test[i, n_lag:]
    >forecast = forecast_lstm(model, X, n_batch)

    这是否意味着 LSTM 只能从一个单独的值开始预测未来三个月?

    提前感谢您的时间。

  74. Abhinandan Nabera 2018年5月21日 下午3:57 #

    你好 Jason,

    我的数据样本是这样的!

    样本 时间 w d ywn
    1 0 -0.10056 0.18784 -0.032737
    1 1 -0.039381 0.97014 -0.049748
    1 2 0.12412 -0.77848 0.029185
    1 3 0.019026 0.13856 0.013822
    1 4 -0.23032 0.84811 0.058235
    1 5 0.97489 0.24698 0.01231

    2 0 -0.59973 0.34736 -0.013221
    2 1 0.32069 0.11464 0.074709
    2 2 -0.12189 0.75243 -0.022599
    2 3 -0.63586 0.04404 0.056563
    2 4 -0.84312 0.17943 0.051038
    2 5 -0.28347 -0.34718 0.01531

    ……以此类推。像这样我有 500 个样本,w、d 是输入,ywn 是输出。我该如何训练和测试我的输出?请帮忙。太困惑了。顺便说一下,需要使用 Keras 和 tensorflow 的 RNN。

  75. MLT 2018年5月25日 下午7:27 #

    嗨,Jason,

    请问为什么数据缩放和反向缩放的形状不同?在缩放中,它使用 (len(diff_values), 1)。在反向缩放中,它变成 (1, len(forecast))。提前感谢。

    def prepare()
    diff_values = diff_values.reshape(len(diff_values), 1)
    # 将值重新缩放到 -1, 1
    scaler = MinMaxScaler(feature_range=(-1, 1))
    scaled_values = scaler.fit_transform(diff_values)

    def inverse_transform()
    inverted = list()
    for i in range(len(forecasts))
    # 从 forecast 创建数组
    forecast = array(forecasts[i])
    forecast = forecast.reshape(1, len(forecast))
    # 反向缩放
    inv_scale = scaler.inverse_transform(forecast)

  76. Siddharth 2018年5月25日 下午7:56 #

    嗨,Jason,

    感谢您的教程,它非常有帮助!我运行了上面的模型代码,有几个问题。(与此数据集有关)

    1) 每次运行后的 RMSE 变化很大。这正常吗?

    2) 我删除了 reset_states(),似乎每次运行都得到更低的 RMSE 分数。难道不应该是相反的吗?

    3) 我需要做哪些更改才能利用 LSTM 不需要固定的采样窗口来学习,并且可以随着时间的推移不断地纳入更大的窗口进行学习的事实?

  77. Jack 2018年5月29日 下午6:28 #

    嗨,Jason,
    感谢您的教程!我的问题是关于批量大小。为什么它固定为 1?是因为我们必须每次都进行预测吗?如果我只想在数据末尾进行多步预测,我必须更改批量大小吗?我的理解是批量大小是将样本放入网络中的数量,对吗?
    我正在尝试解决一个多元多步预测问题。我有 7 个变量,其中一个是目标。我对如何设置批量大小感到困惑。如果我想预测每个时间步,它仍然设置为 1 吗?

  78. Nimish Verma 2018年6月2日 上午1:40 #

    嗨,Jason,
    我正在尝试为价格变动时间序列构建一个 LSTM 网络,目前我正在尝试使用多步 LSTM,最近的 3 个输入,但我希望创建一个网络,其中第 i 个层的输入是直到 (i-1)th 层的所有序列。例如,如果序列是 10,9,5,2,6,7……。
    我现在正在训练我的模型,
    我会输入 10 到第一层,10,9 到第二层,10,9,5 到第三层,依此类推。

    创建这样的网络在逻辑上是否可行?

  79. Sarra 2018年6月4日 下午7:47 #

    这是一个不错的教程。是否有用于多元情况的代码?

  80. MLT 2018年6月14日 上午1:03 #

    嗨,Jason,

    我在 LSTM 模型中遇到了验证损失小于训练损失的情况。请问您是否有链接或文章讨论这个问题?提前感谢。

  81. Y.Ran 2018年6月16日 下午9:21 #

    嗨,Jason,
    感谢您精彩的教程。
    Shamsul 问道我们如何进行 MIMO(多个变量作为输入和多个变量作为输出)。您建议使用链接 https://machinelearning.org.cn/multi-step-time-series-forecasting-long-short-term-memory-networks-python/ 作为模板。据我所理解,您建议的教程展示了如何通过给定 t 来预测 t+1、t+2、t+3。它不适合我的 MIMO 用例。
    以您在 https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/ 中写的例子为例。例如,在时间 t,我有输入 PM2.5 浓度、露点和温度(多个输入变量)。我想在时间 t+1 预测 PM2.5 浓度、露点和温度(多个输出变量)。我们该如何做?

    • Jason Brownlee 2018年6月17日 上午5:40 #

      您可以将模型更改为 seq2seq,例如编码器-解码器模型或 RNN 自动编码器。

  82. Kapil K 2018年6月18日 下午9:57 #

    嗨 Jason – 首先,这是一篇很棒的文章。我尝试在不同的数据集上使用它。

    当 n_seq = 1 时,它似乎工作正常。但是,一旦我将其更改为 n_seq = 3 或更高的数字,我就会收到如下错误:

    ValueError: cannot reshape array of size 3 into shape (1,1)。

    我认为代码会处理这个问题,所以它在洗发水数据集上运行得很好。我尝试修改代码,特别是下面的部分,但没有效果。

    # reshape training into [samples, timesteps, features]
    X, y = train[:, 0:n_lag], train[:, n_lag:]
    X = X.reshape(X.shape[0], 1, X.shape[1])

    您能指导我一下吗?

    完整错误在此。
    /opt/conda/lib/python3.6/site-packages/sklearn/utils/validation.py:560: DataConversionWarning: Data with input dtype object was converted to float64 by MinMaxScaler。
    warnings.warn(msg, DataConversionWarning)
    —————————————————————————
    ValueError 回溯 (最近一次调用)
    in ()
    34 #forecasts = forecasts.reshape((len(forecasts), 1))
    35
    —> 36 forecasts = inverse_transform(series, forecasts, scaler, n_test+2)

    in inverse_transform(series, forecasts, scaler, n_test)
    115 # create array from forecast
    116 forecast = numpy.array(forecasts[i])
    –> 117 forecast = forecast.reshape(1, len(forecast))
    118 # invert scaling
    119 inv_scale = scaler.inverse_transform(forecast)

    ValueError: cannot reshape array of size 3 into shape (1,1)

  83. Alex 2018年6月19日 上午7:44 #

    你好 Jason-

    感谢又一篇精彩的文章。今年我学到了很多东西。我仍然在概念上难以理解多变量时间序列数据以及如何将其输入神经网络。

    这是我的数据的一个非常简化的例子(为方便理解而格式化),我正试图根据以下内容预测未来两小时不同房屋(成千上万)的用电负荷:当前天气观测值、前三个小时的平均负荷以及房屋信息。

    房屋/时间/温度/阳光 负荷(t-2) 负荷(t-1) 负荷(t) y_load(t+2)

    1 1 28 610 5 6 5 3
    1 2 28 599 6 5 4 3
    1 3 27 587 5 4 3 2
    1 4 26 576 4 3 3 1
    1 5 26 565 3 3 2 1

    2 1 23 587 7 7 6 5
    2 2 23 576 7 6 5 4
    2 3 22 565 6 5 5 3
    2 4 22 576 5 5 4 1
    2 5 22 565 5 4 3 1

    3 1 33 565 4 4 4 2
    3 2 34 503 4 4 3 1
    3 3 34 492 4 3 2 1
    3 4 35 481 3 2 1 1
    3 5 35 469 2 1 1 1

    ————–

    我甚至难以将此类复杂的多变量股票预测的例子与我联系起来,因为用这种类比,我试图使用多变量时间序列数据来预测一套股票(或此处指房屋),而不是仅仅预测一套股票。

    使用 train_test_split(),我想在 X_num 房屋的完整数据集上进行训练,然后在 y_num 房屋的完全未见过的数据上进行测试。

    我知道我想要 shuffle = False,以便时间是顺序的,但模型如何区分不同的房屋?使用 batch_size = 5(对应于房屋的 5 个时间间隔)会有用吗?这样做是否意味着一次将一个房屋的完整每日配置文件输入并作为时间序列进行训练。

    在处理了非时间序列相关数据的机器学习之后,我最困惑的是模型如何捕捉那个顺序时间元素,然后在我的例子中,它们如何学习对应于独特元素(房屋)的不同时间序列?

    非常感谢任何建议或解释。

    -Alex

  84. MLT 2018年6月27日 上午6:15 #

    嗨,Jason,

    我需要从特征 x1 和 x2 预测 y(t+1) .. y(t+n)。
    x1 是历史数据。
    x2 是外部来源提供的未来数据。

    f(x1(t) … x1(t-m), x2(t+1) … x2(t+n)) = y(t+1) .. y(t+n)

    您是否建议哪种算法适用于这种情况?我能否参考此 LSTM 多步实现?非常感谢。

    • Jason Brownlee 2018年6月27日 上午8:24 #

      尝试一套方法,找出最适合您特定数据集的方法。

  85. Mohammad Abuzar 2018年6月29日 上午5:09 #

    我有一个问题。
    在您的示例中,预测仅取决于一个前时间步和各种特征。

    如果我没记错的话,您试图根据许多过去的时间步来预测 1 个变量(1 个特征)。

    如果“[samples, timesteps, features]”是 LSTM 模型 3D 输入的含义。
    我想理解为什么时间步数是 1 且特征数大于 1?

    • Jason Brownlee 2018年6月29日 上午6:14 #

      这只是一个简单单变量问题的例子。您可以根据需要更改模型。

  86. Ray li 2018年7月2日 上午3:33 #

    嗨,Jason,

    感谢这篇文章。

    我有一个基于这篇文章的问题。假设我们有多个洗发水而不是只有一个,并且我们有每个洗发水的销售记录和每个洗发水的信息。
    我们应该使用什么模型来解决这个问题?

    谢谢,

    • Jason Brownlee 2018年7月2日 上午6:26 #

      尝试一套方法,看看哪种效果最好。

      • Ray li 2018年7月2日 下午8:21 #

        您能提供更多信息吗?您说的“一套”是什么意思?

        谢谢,

  87. zijin 2018年7月9日 上午7:32 #

    嗨 Jason
    非常感谢您非常有帮助的教程。我阅读了您所有的 LSTM 预测相关教程。我对预测中的 batch_size 感到困惑。我知道在训练模型时,batch_size 是模型将要处理的样本集合,用于更新权重。但是为什么在模型训练完成后,当我们进行预测时,我们仍然需要 batch_size,并且与训练模型时相同的 batch_size?您能否解释一下 batch_size 在模型训练后的预测中是如何发挥作用的?再次感谢。

    • Jason Brownlee 2018年7月10日 上午6:36 #

      通常,模型定义时会有一个固定的批量大小,这意味着它一次处理这么多记录。这是实现上的效率,而不是算法固有的。

      • zijin 2018年7月10日 上午11:20 #

        是的。在训练模型时,它期望一次处理一个批次大小的记录。假设我们有1-8个时间序列,如果时间步长是2,我们只向前预测一步,批次大小是3,那么我们将重新格式化数据为:
        X1 X2 Y
        1 2 3
        2 3 4
        3 4 5
        4 5 6
        5 6 7
        6 7 8
        模型将计算前3个Y(Y=3 4 5)估计值的损失,然后更新权重,接着计算最后3个Y(Y=6 7 8)估计值的损失来再次更新权重。这是一个epoch。经过一定数量的epoch后,模型就训练好了。然后权重和架构就固定了。现在我们知道X1=7, X2=8,我们可以使用模型进行一步预测,我们只需要知道X1, X2(这两个时间步长)、权重和模型架构。我们应该能够在没有批次的情况下进行预测。但是为什么在Keras中,我使用你的代码“forecast = model.predict(X, batch_size=n_batch)”时,必须将相同的batch_size传递给model.predict呢?我知道有些人会保存权重和模型架构,就像他构建另一个模型一样,然后他就可以使用不同的batch_size来解决这个问题。我只是不明白为什么batch_size在model.predict中很重要。你能解释一下,或者给我一些论文或教程吗?非常感谢你的时间和帮助。

  88. zijin chen 2018年7月10日下午9:59 #

    明白了,非常感谢你的回答。

  89. Eric Gou 2018年7月13日下午5:11 #

    嗨,Jason,
    感谢分享这些关于LSTM的文章。
    我在预测未来数据时遇到了一个问题。
    在进行预测时,我只将第一个实际值作为输入。然后使用输出进行下一次预测。预测值在几个步骤后变得几乎恒定。
    你对这种预测有什么看法吗?

    谢谢!

    此致,
    埃里克

    • Jason Brownlee 2018年7月14日上午6:13 #

      您可能需要根据具体问题进一步调整模型。

    • Hao Chen 2019年1月14日晚上11:45 #

      你好,Gou,我也有同样的问题。你现在解决了它吗?

  90. Trung Anh 2018年7月16日下午1:03 #

    嗨,Jason,

    我一直在关注你的教程。我正在做一个使用LSTM和softmax分类器的时间序列分类问题。
    我的数据形状如下:(3154, 30, 6) (3154, 30) (1352, 30, 6) (1352, 30)。
    我的模型包含一个LSTM层和一个dense(30)。
    但是当我运行模型时,我收到错误:“ValueError: Error when checking target: expected dense_2 to have shape (1,) but got array with shape (30,)”。
    这是因为我的模型吗?我该如何解决这个错误?
    非常感谢!

    • Jason Brownlee 2018年7月16日下午2:13 #

      也许输出形状需要是 [n, 30, 1]?

      • Sundeep Nayakanti 2018年7月17日上午5:39 #

        你好,Jason博士,

        感谢您精彩的博客文章。

        但是,我仍然不明白如何预测未来(例如,某个产品未来三个月的销量),其中我的输入变量是该产品的历史销量+收到的报价数量+价格点……+其他数值变量。说LSTM可以用来预测这类问题(考虑所有输入)是否公平?提前感谢。

  91. ezgi 2018年8月2日下午7:25 #

    你好,感谢教程,它让我对LSTM有了更清晰的认识。但我对序列数量和滞后数量感到困惑。目前,我有一个单变量时间序列数据集,包含547个每日销售数据。我想通过LSTM预测未来3个月(91天)。我已经将n_lags设置为3、5和7。据我所知,这是预测时我们回顾的数据量。但是,我无法理解序列数量是什么,以及我应该如何设置它。如果您能回答我的问题,我将非常感激。谢谢!

  92. xiaowanzi 2018年8月6日晚上10:20 #

    Jason先生
    非常感谢您的文章,它给了我很大的帮助,但是我的数据具有周期性和复杂的序列,它是sinx和cosx的组合。我想预测一个周期或更多周期,我拥有100,000个数据,每个周期500个数据,我该如何预测相同类型的数据?

    • Jason Brownlee 2018年8月7日上午6:27 #

      也许可以先从SARIMA和ETS等经典方法开始,然后尝试一些ML方法,然后尝试MLP、CNN,最后是LSTM。

  93. Darkwind 2018年8月23日晚上11:24 #

    嗨,Jason,

    感谢这篇好文章。

    我可以在以下函数中问一下

    # 使用 LSTM 进行一次预测,
    def forecast_lstm(model, X, n_batch)
    # 重塑输入模式为[样本,时间步长,特征]
    X = X.reshape(1, 1, len(X))
    # 进行预测
    forecast = model.predict(X, batch_size=n_batch)
    # 转换为数组
    return [x for x in forecast[0, :]]

    为什么是 X = X.reshape(1, 1, len(X)) 而不是 X = X.reshape(X.shape(0), 1, X.shape(1))?

    虽然文章中的结果没有改变,但我无法理解其中的逻辑。

    提前感谢您的时间

  94. Loong 2018年8月30日凌晨12:25 #

    Jason 博士您好,

    非常感谢您的精彩教程。

    我不确定为什么我的预测结果是错误的。

    https://ibb.co/nc1jV9

    我应该在哪里得到?

    https://3qeqpr26caki16dnhd19sv6by6v-wpengine.netdna-ssl.com/wp-content/uploads/2017/03/Line-Plot-of-Shampoo-Sales-Dataset-with-Multi-Step-LSTM-Forecasts.png

    源代码和数据集来源于此网站。

    我使用的是tensorflow 1.10.0和keras 2.2.2。

    谢谢

    • Jason Brownlee 2018年8月30日上午6:30 #

      您可能需要多次运行示例?

      • Loong 2018年9月7日上午10:29 #

        Jason 博士您好,

        抱歉,是我的错。

        我复制了代码的错误部分。

        谢谢

  95. summer 2018年8月30日下午12:44 #

    嗨,Jason,

    非常感谢这篇好文章。

    我可以在以下函数中问一下
    # 评估每个预测时间步的 RMSE
    def evaluate_forecasts(test, forecasts, n_lag, n_seq)
    for i in range(n_seq)
    actual = test[:,(n_lag+i)]
    predicted = [forecast[i] for forecast in forecasts]
    rmse = sqrt(mean_squared_error(actual, predicted))
    print(‘t+%d RMSE: %f’ % ((i+1), rmse))

    该函数为测试数据输出t+1, t+2, t+3……的RMSE。
    [[ 342.3 339.7 440.4 315.9]
    [ 339.7 440.4 315.9 439.3]
    [ 440.4 315.9 439.3 401.3]
    [ 315.9 439.3 401.3 437.4]
    [ 439.3 401.3 437.4 575.5]
    [ 401.3 437.4 575.5 407.6]
    [ 437.4 575.5 407.6 682. ]
    [ 575.5 407.6 682. 475.3]
    [ 407.6 682. 475.3 581.3]
    [ 682. 475.3 581.3 646.9]]
    但是,我如何评估总测试值和预测值之间的RMSE呢?
    谢谢

    • Jason Brownlee 2018年8月30日下午4:52 #

      对整个测试集进行预测,然后计算预测值的RMSE。

  96. Mike C 2018年8月30日晚上10:42 #

    嗨,Jason,

    我也一直在尝试遵循本指南以及您在此链接的指南:https://machinelearning.org.cn/multivariate-time-series-forecasting-lstms-keras/,但遇到了一些问题。

    首先,我的最终目标是实现一个多变量多步预测时间序列LSTM。具体来说,我使用的是一个按日期索引/排序的数据集,类似于您的pollution.csv,它每行有9个其他字段,我希望在训练中使用。通过训练,我的目标是能够为模型提供目标日以及前2天(总共3个滞后日)的数据,然后让它对未来7天进行预测。如果数据集的大小/行数有影响的话,这个数据集有6375个条目。

    不幸的是,我无法弄清楚如何将上面链接的示例转换为多步模式,也无法在多变量环境中运行本文中的示例。您能否展示如何转换这两个示例中的一个?

    谢谢!另外,您在文章发布一年多后仍然坚持回复新问题,这真的很棒🙂

  97. segun 2018年9月9日上午6:39 #

    感谢这个信息丰富的教程。我有一个问题。如何更新LSTM?正如您的文章中所解释的那样。

    更新LSTM。将示例更改为在有新数据可用时重新拟合或更新LSTM。10个训练周期应该足以用新的观测值重新训练。

    基本上,我想让新的观测值输入模型以进行下一次预测,或者您的文章在任何地方都有提到吗?

  98. Al 2018年9月13日上午6:12 #

    嗨,Jason,

    感谢您发布所有这些内容。我使用您几个教程的汇编创建了一个模型,该模型根据数十年的每日最高温度、每日最低温度、一年中的月份和降水来预测未来3天的最高温度。对于我生成的模型,当我在t+1(第二天)进行预测时,该值最终非常紧密地模仿了前一天的值(图形基本上看起来像同一图形被复制,引入了1步的时间滞后)。我可以调整哪些参数来帮助处理这个问题?

    谢谢!

  99. Pranay 2018年9月17日晚上11:42 #

    嘿!我如何预测未来一周?因为上述过程似乎仅适用于测试数据。我的意思是“make_forecasts”函数考虑了测试数据,这从(X, y = test[i, 0:n_lag], test[i, n_lag:])可以看出。我只想问的是,没有测试数据。我只有训练数据。那么,我现在如何预测未来一周呢?

    • Jason Brownlee 2018年9月18日上午6:16 #

      调用model.predict()并将最后的n个观测值传递进去。

      • Pranay 2018年9月18日下午3:35 #

        但这会导致单步预测,而我关心的是多步预测。

        • Jason Brownlee 2018年9月19日上午6:14 #

          如果您的模型预测多个时间步长,那将是多步预测。

  100. Monte 2018年9月27日凌晨12:36 #

    嗨,Jason。我是一名新的学习者。但是,我仍然不知道如何进行多变量多步时间序列预测与LSTM?你能帮我吗?

  101. Mohammad Ali Bagheri 2018年10月18日上午11:33 #

    感谢您所有精彩的教程。但是,对于这个教程,我不明白为什么有些部分写得很难!
    例如,为什么您不使用
    numpy.diff(dataset, n= interval)?

    • Jason Brownlee 2018年10月18日下午2:33 #

      谢谢你的反馈。

      解决一个问题有很多方法,我尽量不假设读者知道太多。

  102. Francis Kim 2018年10月24日下午12:51 #

    嗨,Jason,

    谢谢您将我引向此页面。代码运行良好。

    将预测长度(例如从3个月改为12个月)是否像将n_seq值更改为12一样简单?

    • Jason Brownlee 2018年10月24日下午2:47 #

      可能是的,时间有点久了。也许试试看。

  103. Kartheek 2018年10月24日晚上11:56 #

    我们如何为未来值获得RMSE?RMSE是基于我们的预测值和实际值,但在这个例子中我们是为未来预测,我们不知道实际值。

    • Jason Brownlee 2018年10月25日上午7:56 #

      只有当您拥有地面真实值时,才能计算模型的误差。

      您可以通过在历史数据上评估模型来估算模型预期的性能。

  104. Jing Li 2018年10月25日下午3:57 #

    为什么我们需要对测试数据进行逆缩放?我认为第二行不是必需的。

    actual = [row[n_lag:] for row in test]
    actual = inverse_transform(series, actual, scaler, n_test+2)

    此致,
    Jing

    • Jason Brownlee 2018年10月26日上午5:31 #

      我们进行逆缩放是为了能够以数据集的原始单位来评估模型的误差。

  105. saravana 2018年10月31日晚上9:47 #

    嗨,Jason,

    谁能给我解释一下这一行?
    n_vars = 1 if type(data) is list else data.shape[1]

    谢谢!
    saravana

    • Jason Brownlee 2018年11月1日上午6:09 #

      如果输入是列表,它会将变量设置为1,否则对于numpy数组,它会将变量设置为第二个维度(列)的形状。

  106. Harry 2018年11月2日晚上9:36 #

    嗨,Jason,

    “模型将被用于对时间步长进行预测,然后从测试集中取下一月实际期望的值,并使其可用于模型对下一个时间步长的预测。”

    您能否指出方法中模型在包含前一个数据点后的下一个时间步长被更新(重新训练)的位置?

    我期望测试数据集中的每个数据点都可以用于重新训练。

    • Jason Brownlee 2018年11月3日上午7:05 #

      模型在进行前向验证的每一步都不会重新训练,通常计算成本太高。

      相反,数据会被添加到历史记录中,用于输入以进行下一次预测。例如,我们模拟了实际观测值在预测后被制作的事实,并使用该观测值而不是预测值来制作后续的预测。

  107. Junzhi Xue 2018年11月7日下午1:00 #

    非常感谢!
    我对一些方面感到困惑。time_steps是否等于batch_size?而且我看到过您的一些关于LSTM将time_step设置为1的博客,如果我将time_step更改为另一个数字,对样本会有什么影响?
    我只是不清楚time_steps和samples在[samples,time_steps,features]中的关系。谢谢你的帮助。

    • Jason Brownlee 2018年11月7日下午2:48 #

      不,时间步长与批次大小不同。

      一个批次是1个或多个样本,一个样本是1个或多个时间步长,一个时间步长是1个或多个特征。

      • Junzhi Xue 2018年11月9日凌晨12:16 #

        在我看来,时间步长决定了LSTM的记忆,那么将时间步长设置为1有意义吗?换句话说,我们如何选择更好的时间步长?
        谢谢你的帮助!

        • Jason Brownlee 2018年11月9日 上午5:24 #

          LSTM 具有在批次之间重置的记忆,或者根据您的选择手动重置。

          概念上,这种记忆与一个样本中的时间步长数量是分开的。

  108. Kiko 2018年11月18日 下午9:56 #

    嗨,Jason,

    感谢博客。
    我有一个关于您代码的问题。运行“prepare_data(series, n_test, n_lag, n_seq)”中的代码后,我遇到了以下问题
    TypeError Traceback (most recent call last)
    in
    8 n_test = 10
    9 # 准备数据
    —> 10 train, test = prepare_data(series, n_test, n_lag, n_seq)
    11 print(test)
    12 print(‘Train: %s, Test: %s’ % (train.shape, test.shape))

    TypeError: ‘NoneType’ object is not iterable。

    有一点要说明的是,我没有使用您提供的“parser”函数,因为它会引发另一个关于 %Y-%M 格式的错误。所以我只是删除了 parser 函数中的最后一个参数。
    ValueError: 时间数据“190Sales of shampoo over a three year period”与格式“%Y-%m”不匹配

    提前感谢您的帮助!

  109. Leon 2018年11月29日 上午4:19 #

    嗨,

    感谢您发布这个教程。

    对于“多个主体内部”设计,如何轻松地进行适应?例如,在每个月的时间测量点有 100 种不同的洗发水。

  110. Mudassar 2018年12月18日 下午9:41 #

    嗨,jason
    我有一个问题。在电力预测或使用时间序列数据进行估算方面,CNN 还是 LSTM 更好?

    • Jason Brownlee 2018年12月19日 上午6:33 #

      尝试两者,并找出最适合您特定数据集的方法。

      • Mudassar 2018年12月19日 下午12:43 #

        您会推荐任何关于这两种技术的电力预测的链接吗?

        • Jason Brownlee 2018年12月19日 下午2:29 #

          是的,我的博客上有很多示例,请尝试使用搜索框。

  111. mk 2019年1月3日 下午4:40 #

    层数,如何设置多层LSTM?您能否给我一些
    您的帖子?

  112. mk 2019年1月4日 下午1:13 #

    我有一个想法。代替 LSTM
    步骤 1:在每个层中随机将序列中的值替换为 0
    步骤 2:使用 resnet 保持信息完整
    请指出不合理之处。

  113. Hao Chen 2019年1月15日 上午12:13 #

    你好,Jason。
    最近,我一直在尝试使用 LSTM 进行递归预测,但结果非常糟糕。事实上,我预测的模型非常简单,就是一个指数函数。您有什么相关的建议和指导吗?

  114. Murali 2019年2月18日 上午7:50 #

    如何修改代码来预测未来?这里预测停止在“十二月”。如何预测未来三个月?

  115. Doosun Hong 2019年2月19日 下午7:31 #

    嗨,感谢您提供的精彩教程。

    我有一些关于多步 LSTM 与正常 LSTM 的问题,我遵循了:https://machinelearning.org.cn/time-series-prediction-lstm-recurrent-neural-networks-python-keras/

    我认为这两个模型的主要区别在于输出值的数量。在本教程中是 3,而上一教程是 1。

    1. 与正常 LSTM 相比,这个多步 LSTM 的主要目的(优点)是什么?例如,为了提高准确性,还是提前预测 t+2、t+1 值的好处?

    2. 在这个 3 步 LSTM 的例子中,训练模型时,三个输出值是否每次都会影响记忆的权重?

    3. 多步 LSTM 的 t+1 RMSE 通常比正常 LSTM 的 t+1 RMSE 更好吗?

    • Jason Brownlee 2019年2月20日 上午7:58 #

      如果其他变量对目标变量具有预测性,那么多元模型可能有用。

      性能差异确实取决于预测问题的具体情况和模型的选择。

      • Doosun Hong 2019年2月20日 下午3:41 #

        所以您的意思是,性能不仅取决于模型给出多少输出,还取决于数据的具体情况(预测问题)。

        1. 那么,这是否意味着我必须同时使用正常(1 步)LSTM 和 3 步 LSTM,然后比较这两个模型的评估结果并选择更好的一个?

        2. 此外,我对于验证和评估感到困惑。您计算的 RMSE 分数是验证方法,而不是评估。我理解得对吗?

        如果可能,请分别回答问题 1 和 2。谢谢!!

  116. Bross 2019年2月22日 上午1:15 #

    尊敬的教授
    在学习了其他文章后,我发现我们可以对以下代码进行一些小改动
    第 77 行:model.add(LSTM(n_neurons, batch_input_shape=(n_batch, X.shape[1], X.shape[2]), stateful=True))
    改为
    model.add(LSTM(n_neurons, batch_input_shape=(n_batch, X.shape[1], X.shape[2]), stateful=True, dropout=0.5, recurrent_dropout=0.5))
    根据文章,这两个 dropout 有助于避免过拟合。

    此外,我想知道为什么第 172、174 和 178 行有 ‘n_test+2’ 而不是 ‘n_test’?
    我非常感谢这个教程!

  117. Adi 2019年2月23日 上午8:29 #

    嗨,Jason,

    您所有的教程都非常有帮助!谢谢!我有一个问题,我有一个从 2016 年 1 月到 2018 年 12 月(36 个值)的月度数据。我将数据分割为 24(2016-2017):12(2018)个值。我遇到的问题是,在现实场景中,假设我在 2018 年 1 月 1 日收到 2017 年 12 月的需求数据,那么我将进行的预测实际上是针对 2018 年 2 月。在这种情况下,我需要对上述模型进行哪些更改?

    上述场景的唯一原因是“反应时间”。如果我在 2018 年 1 月 1 日发布 2018 年 1 月的预测,那么我们就没有时间进行准备。因此,当我有截至 2017 年 12 月的数据时,我将进行的第一次预测将是针对 2018 年 2 月的。

    谢谢!

    • Jason Brownlee 2019年2月24日 上午9:01 #

      好问题。

      如果模型稳健且问题简单,则可以在没有新观测值的情况下直接使用。

      一种方法可能是使用一月份的预测作为观测值来做出下一次预测。
      另一种方法可能是使用基于真实数据的关于一月份的估计值作为下一次预测的观测值。

  118. jack 2019年2月24日 下午5:55 #

    据我理解,您有 10 个示例,将它们分成 7 个和 3 个训练和测试集。然后尝试从前 7 个示例中预测最后 3 个示例。但在现实世界中,我们想预测明天和后天、大后天,而我们没有他们的示例。所以请提供一个对未来未知示例有效的代码(或文章),而不仅仅是针对先前已知的示例!

    致以最诚挚的问候。

  119. beta 2019年2月26日 上午2:17 #

    先生您好,感谢您的工作,我想使用 LSTM 来预测每日时间序列。我阅读了您的文章和代码,我明白了您在训练和测试数据上进行预测的原理,但我的
    问题是,我无法对未来 10 天进行预测,例如?
    请帮助我,先生,提前致谢
    Selmi

  120. Gunay 2019年3月3日 下午11:39 #

    嗨,Jason,

    这是一篇很棒的文章,有助于理解持久性和 LSTM 实现。我想将 ARIMA 的性能与这些方法进行比较。正如您在文章中所提到的,您将数据集转换为监督学习以进行多步预测。因此,您在这里使用了 1 个先前的时间步来预测接下来的 3 个时间步。例如,以下矩阵,第一列是单个输入,接下来的 3 列是预测。
    [[ 342.3 339.7 440.4 315.9]
    [ 339.7 440.4 315.9 439.3]
    [ 440.4 315.9 439.3 401.3]
    [ 315.9 439.3 401.3 437.4]
    [ 439.3 401.3 437.4 575.5]
    [ 401.3 437.4 575.5 407.6]
    [ 437.4 575.5 407.6 682. ]
    [ 575.5 407.6 682. 475.3]
    [ 407.6 682. 475.3 581.3]
    [ 682. 475.3 581.3 646.9]]

    要将 ARIMA 应用于此类问题,我是否应该以相同的方式进行监督学习?我的意思是,如果我们只考虑这个示例矩阵,我们有 10 次迭代。并且每次迭代,ARIMA 模型都应该将第一个值作为输入,并预测接下来的 3 个时间步?假设这是真的,我应该如何定义 p、d、q 值?并且拟合过程对我来说也不清楚。如果您能回答,我将非常感激。

    此致,
    古奈

    • Jason Brownlee 2019年3月4日 上午7:01 #

      您可以直接将 ARIMA 应用于被预测变量的单变量时间序列。

      • Gunay 2019年3月4日 上午8:43 #

        那样的话,结果与 Persistence 和 LSTM 如何比较?我的意思是,例如,对于 LSTM,将 342.3 这个数据点输入模型,预测接下来的 3 个时间步。然后,输入 339.7 并获得接下来的 3 个预测点。但对于 ARIMA,我感到困惑。我不明白我应该使用什么样的数据分割。您能详细解释一下您的回答吗?

        • Jason Brownlee 2019年3月4日 下午2:16 #

          您可以将 Persistence 的示例作为起点,然后拟合一个 ARIMA 而不是使用 Persistence。

          • Gunay 2019年3月4日 下午8:18 #

            谢谢,Jason

  121. Danial 2019年3月7日 下午7:07 #

    如果您在 CNN 中使用 Adam 优化器,那么是否必须使用 BP 算法来优化权重,或者它可以在没有 BP 的情况下工作?如果我使用 SGD,那么 BP 是必需的吗?

    • Jason Brownlee 2019年3月8日 上午7:45 #

      Adam 是一种随机梯度下降,与其他实现一样,它使用反向传播来更新模型权重。

      • Danial 2019年3月8日 上午11:51 #

        如果数据量很大,那么 SGD 还是 Adam 更好?Adam 使用默认的学习参数,还是我们可以更改它?

      • Danial 2019年3月8日 下午12:08 #

        您能分享一些链接吗?谢谢

  122. Danial 2019年3月7日 下午8:29 #

    还有一件事,LSTM 可以用于图像数据吗?或者它只能用于时间序列数据?您的回答解决了我的问题。有人告诉我 LSTM 不能作为输入来处理图像数据

    • Jason Brownlee 2019年3月8日 上午7:48 #

      是的,尽管通常使用 CNN 从图像中提取特征,然后再将特征传递给 LSTM,例如使用 CNN-LSTM 或 ConvLSTM。

  123. msu 2019年3月24日 下午7:47 #

    感谢这个教程,但它总是显示错误“No module named tensorflow”

  124. Juno 2019年3月25日 下午5:35 #

    嗨,J!感谢您的帖子。我是 LSTM 的新手,多次运行您帖子中的代码,我发现每次的预测结果都不同。您能告诉我原因吗?谢谢

  125. Adi 2019年4月1日 下午1:25 #

    嗨,Jason,

    感谢之前的回答!我还有另一个问题,可能与文章不完全相关,但还是想问一下

    我拥有 300,000 个不同的单变量时间序列,长度可变,用于生成预测,并且 LSTM 多步预测是我计划使用的策略之一。使训练更快(硬件方面/平台方面)的最佳方法可能是什么?目前我一直使用一个字典,并在一个循环中串行生成预测(我知道这是最糟糕的方法)。

    我已经考虑过使用 Spark 作为选项。还有其他更好的选择吗?

    谢谢,
    Adi

    • Jason Brownlee 2019年4月1日 下午1:38 #

      听起来是个很棒的项目。

      也许可以尝试使用自编码器在系列之间学习?
      也许先尝试线性模型?
      也许可以将时间序列跨越几台 AWS 机器进行分割?
      也许可以尝试一个大数据平台?

      告诉我进展如何。

      • Adi 2019年4月2日 上午1:56 #

        就线性模型而言,我将尝试自回归、移动平均和 MLP(MLP 被认为是线性模型吗?)

  126. Adi 2019年4月2日 上午1:42 #

    当然!谢谢!我会尝试所有方法🙂 ..

  127. Christos Tsoukalas 2019年4月2日 上午4:06 #

    嗨,Jason,

    感谢您这篇非常有趣的论文!我有一个关于“make_forecasts()”函数的问题。如果我设置“i=0”(将输入“X”固定为相同的值)并运行该行

    forecast = forecast_lstm(model, X, n_batch)

    多次,我每次都会得到不同的预测值,例如:

    [-0.48377362, 0.105986044, -0.3069649]
    [-0.5117972, 0.12195417, -0.32364962]

    尽管训练好的模型是相同的。是什么导致了预测中的这种随机性?

    谢谢你,
    Christos

    • Jason Brownlee 2019年4月2日 上午8:17 #

      LSTM 在时间步之间维护并使用内部状态。

      • Christos Tsoukalas 2019年4月2日 上午8:25 #

        谢谢你,Jason。

        我曾认为,将一个已经训练好的 LSTM 模型与相同的输入(在本例中是“X”)进行喂养,它应该会产生完全相同的预测。

        Christos

        • Jason Brownlee 2019年4月2日 下午2:17 #

          是的,如果模型没有改变,并且状态被重置,那么使用相同的预训练模型和相同的输入将产生相同的输出。

  128. msu 2019年4月9日 下午3:22 #

    我也可以对 ARIMA 做同样的事情,我的意思是关于时间步,我能否获得关于 t+1、t+2 和 2+3 的 ARIMA 结果?因为我需要比较 LSTM 和 ARIMA。如果您能帮助我,我需要比较这两种模型哪些方面
    谢谢你

  129. Matthew 2019年4月23日晚上11:51 #

    非常感谢你提供的所有教程,它们真的很有帮助。

    我在实现我的最后一个 LSTM 时遇到了困难。

    我有一个数据集,其中包含约 1000 个不同的维基百科页面,每个页面的过去两年的每日浏览量。

    我需要预测每个页面未来 30 天的页面浏览量。
    我已经训练了一个 Encoder/Decoder LSTM 模型,该模型可以预测未来 30 天,其 Keras 模型的输入形状为 (n_examples=1000, n_time_step=365*2, n_feature=1)。

    但是 LSTM 在非常长的时间步长上会遇到困难,也就是说,它不能很好地“记住”非常早的观测值,例如 t-500。

    因此,我想通过添加“外生特征”来改进模型,例如 t-365 的自相关性,或者页面的独热编码语言/星期几等。

    我不太清楚如何处理这些新特征,并且在线上找不到任何资源。
    你有什么想法吗?
    谢谢

  130. thiagu 2019年4月25日下午2:35 #

    你好 Jason,
    在上面的实验中,你展示了两个输出……一个是未使用 LSTM 模型尝试预测,另一个是使用 LSTM 模型预测数据……有什么区别?

    • Jason Brownlee 2019年4月25日下午2:48 #

      这篇文章展示了持久化模型与 LSTM 模型。

  131. Charlotte 2019年5月10日凌晨12:31 #

    嗨,Jason,
    首先,非常感谢你提供的所有教程,我通过你的文章学习机器学习,它们非常完美!

    我正在尝试在多步预测中实现 LSTM 模型,但我有多个个体(而不仅仅是你教程中的一个)。我无法处理多个个体的多步预测(特别是“系列到监督”和“准备数据”部分)。你是否有任何关于我如何处理这种情况的想法?

    我提前非常感谢你。

    Charlotte

    • Jason Brownlee 2019年5月10日早上8:19 #

      你到底遇到了什么问题?

      • Charlotte 2019年5月15日凌晨1:06 #

        如果我的消息不够清晰,请原谅。
        我的数据集包含 1000 个个体,我想为每个个体进行多步预测。
        然而,在运行“prepare_data”函数后,我得到一个形状为 (77, 4) 的训练集,其中每个框包含一个包含 1000 个值的数组(array([[array([1,...,1000]), array([1,...,1000]), ...)]], dtype=object))。
        此元素的形状不被“fit_lstm”函数接受。(错误消息:“ValueError: setting an array element with a sequence.”)。

        谢谢

        Charlotte

  132. jessy 2019年5月15日下午3:06 #

    你好 Jason,
    当我运行上面的代码时,我遇到了一个错误……

    文件“”,第17行
    inv_yhat = concatenate((yhat, test_X[:, 1:]), axis=1)
    ^
    SyntaxError: invalid syntax

  133. jessy 2019年5月15日晚上4:09 #

    你好 Jason,

    我的疑问是关于多个患者的糖尿病时间序列数据……是否有可能同时进行多个患者的时间序列预测……是否可以使用 LSTM 来处理?

  134. Steve 2019年5月23日下午4:29 #

    哦,算了。我太蠢了。

  135. Lopa 2019年6月20日凌晨2:15 #

    嗨,Jason,

    在遵循了你的教程之后

    https://machinelearning.org.cn/time-series-forecasting-long-short-term-memory-network-python/#comment-488844

    我正在尝试使用每日数据来实现这个。但是我遇到了一个问题,在将 n_seq 从 3 更改为 1 时。所以我尝试取一个滞后值来预测下一个点。但这样做,“actual”的值与测试数据中的值相差甚远。

    另外,由于我的数据是每日的,所以我尝试将 n_test 设置为 59。我是否有什么地方做错了?

    我在你的书中找不到这个例子。如果你能帮忙,那就太好了。

    再次感谢你回复我之前的问题。

  136. Lopa 2019年6月20日凌晨2:22 #

    我甚至在洗发水销售数据上尝试了相同的方法,即;将 n_seq 从 3 更改为 1,并且遇到了相同的情况,所以这肯定与我的数据是月度还是每日无关。有一段时间我曾假设实际值是用于预测下一步的预测值。

  137. Lopa 2019年6月21日凌晨12:56 #

    嗨,Jason,

    非常感谢你回复我的帖子和文章。这很有帮助。但是,

    1.我的训练数据有 549 个数据点,这使得 n_seq=1.5 (549/365),但我不能使用 1.5 作为 n_seq。在这种情况下,使用 n_seq=2 明智吗?

    2. 我也明白我需要在建模部分调整 batch_input_shape,但我很难理解它在哪里考虑了 n_timesteps?

    如果你能回答我的问题,那将是很大的帮助。

  138. Lopa 2019年6月21日早上6:19 #

    我还尝试将总观测值减少到 24,然后将 n_seq 更改为 2,但即使那样,当我转换实际值时,我得到以下结果
    [[141.1, 201.7],
    [254.9, 318.1],
    [212.70000000000002, 130.8],
    [128.2, 223.79999999999995],
    [368.9, 307.9],
    [130.4, 208.00000000000003],
    [364.6, 350.9],
    [212.29999999999995, 344.0],
    [435.30000000000007, 278.20000000000005],
    [132.79999999999995, 210.59999999999997]] 这与我的测试数据集中的实际值相去甚远。我的问题是,实际值是如何受到序列数量变化的影响的?再次感谢。

  139. Guhan palanivel 2019年6月26日凌晨12:40 #

    你好,先生,感谢你提供的精彩教程。

    我有一个多变量数据集,有 5 个输入和一个输出(6 个月的数据,间隔 1 小时),该数据集不包含任何趋势或季节性。

    先生,有没有办法预测下个月(第七个月)?

  140. Lee 2019年7月18日晚上9:40 #

    嗨,Jason,

    作为 RNN 的新手,我对这篇帖子感到惊叹。但仍然有一些令人困惑的问题。

    1. 看起来你对整个数据集进行了预处理。但在一些教程(主要关于 CV)中,拆分数据集是第一步,然后用从训练集中获取的相同参数(如 std、mean)对训练/测试集进行归一化。我认为第二种方法更合理,这意味着在训练过程中不会窥探任何测试数据。

    2. 你在这个案例中使用了 stateful LSTM。与 stateless LSTM 相比,性能有很大的提升吗?

    此致,

    • Jason Brownlee 2019年7月19日早上9:19 #

      是的,我为了简洁起见一起预处理了所有数据。通常,你会对训练集准备转换,然后将转换应用于训练集和测试集。

      通常不会。事实上,LSTM 总体上在单变量时间序列方面表现很差,但每个人都想尝试一下。
      https://machinelearning.org.cn/findings-comparing-classical-and-machine-learning-methods-for-time-series-forecasting/

      • Lee 2019年7月19日早上11:27 #

        谢谢你的回复。

        代码中仍有一些东西让我困惑。在这个例子中,前 1 个时间步被用来预测接下来的 3 个时间步,所以你定义了输入重塑的模型。

        X, y = train[:, 0:n_lag], train[:, n_lag:]
        X = X.reshape(X.shape[0], 1, X.shape[1])

        显然,在这种情况下,训练集的输入形状是 (22, 1, 1)。这似乎没什么问题,但当我尝试改变策略时,比如使用前 2 个时间步来预测接下来的 3 个时间步,情况就变得奇怪了。第二种情况下的输入形状是 (22, 1, 2),看起来很模糊!我认为输入应该占用两个连续的时间步和一个特征,这意味着它应该是 (22, 2, 1)。

        此外,“forecast”部分也出现了同样的问题。

        X = X.reshape(1, 1, len(X))

        在原始情况下似乎没什么问题,但在第二种情况下,输入的特征尺寸变成了 2,而不是时间步长。

        此致,

  141. Jeff 2019年8月26日早上7:45 #

    很棒的系列!我很好奇,在进行 LSTM 多步预测时,能否在预测期间纳入额外的系列?例如,我有一个问题,需要预测未来 181 天(6 个月每日数据)。我可以使用 LSTM 从过去的数据系列(例如过去 3 年的每日数据)中学习,以预测接下来的 181 天。我可以在训练中纳入额外的系列,但在预测期间不能。我的意思是,对于我将要预测的 181 天,我知道这些额外系列的价值,因为它们是确定性的(例如,星期几、月份等)。有没有办法纳入这些?

    • Jason Brownlee 2019年8月26日晚上2:13 #

      我不确定我是否理解 Jeff。

      你可以有多个输入序列,但模型在训练和推理期间始终被框定在模型的输入和输出方面,并且这些必须保持一致。

      你必须按照你打算使用的方式来设计和训练模型。

      不确定这是否回答了您的问题。

      • Jeff 2019年8月26日晚上9:25 #

        Jason,

        抱歉,我可能解释得不好。我构建模型的方式是使用目标变量的 365*3 个值(称之为输入 x1)来预测接下来的 181 个值(y)。在进行这种单变量方法之后,我引入了一个额外的系列(称之为 x2),该系列与 x1 同步(有 365*3 个值)。这两个系列预测 y 的接下来的 181 个值。

        这使得在任何时候都可以使用 365*3 个先前的值来预测接下来的 181 个值。我想纳入 x2 的 181 个值来预测 y(这些值与 y 同步,因为它们是已知的)。

        也许我应该做一些事情,比如有两个输入 LSTM 模块——第一个输入是 x1 和 x2(365*3 个时间步,2 个特征;都在预测期之前),第二个输入是 x2 的 181 个值(与任何时候被预测的目标值同步)。然后将这两个 LSTM 的输出连接起来,并将它们输入到密集层。

        是这样吗?

  142. Jeff 2019年8月27日早上11:16 #

    我有一个时间序列,我为滚动预测进行了处理。我像你在其他帖子中展示的那样将其分解,包含 1095(3 年)个值作为输入,接下来的 181 个值作为目标。这个多步单变量时间序列模型不包含任何外部回归量(在经典时间序列模型的语言中)。例如,每个每日值在知道月份、星期几等时可以被更好地预测(例如,存在各种级别的季节性)。

    上面我称 1095 个输入为 x1。所以,我有一个 x1,它有 1095 个时间步长和 1 个特征。同样,目标是接下来的 181 个值。

    外部回归量(虚拟编码的月份编号、星期几编号等)是其他序列(上面是 x2)。这个矩阵有 181 个时间步长和 4 个特征。

    我不确定的是如何最好地纳入 x2。按照你的术语,它并不是一个真正的并行序列(我想不是),因为 1)它们的长度不同(x1 是 1095 个时间步长,x2 是 181 个时间步长),而且 2)它们的时间不同……x2 的每个时间步都与目标的每个时间步相关。第一个目标变量将具有 4 个相关特征(月份、星期几等)。

    在 ARIMA 格式中,x2 将是外部回归量,每个“行”与你试图预测的每个目标值同步。

    • Jeff 2019年8月27日早上11:48 #

      在创建单变量序列的样本后,一个样本可能是

      [23,24,21,….39] 输入(长度 1095;时间序列的先前值)
      [12,19,…43] 输出(长度 181;序列中的下一个值,在 39 之后是 12)

      然后我有 181 个时间步长和 4 个特征。一个时间步长可能是 [0,1,0,0]。这与第一个目标值 12 相关。第二个时间步长可能是 [1,0,0,0],这与第二个目标值 19 相关。

      似乎需要一种方法可以将这个外部回归量矩阵的每个时间步长与其对应的目标直接关联起来。

      • Jason Brownlee 2019年8月27日晚上2:16 #

        LSTM 可以通过多输入模型来实现这一点,每个序列有一个输入“头”,学习适当的中间表示以输出所需数量的时间步长。

    • Jason Brownlee 2019年8月27日晚上2:13 #

      我明白了,如果这两个序列指的是不同的时间段(谢谢!),那么一种方法是使用多输入模型,每个序列一个头,然后将模型连接到一个单一的内部表示,作为多步预测的基础。

      Keras 使这变得超级简单,例如,2 个不同的 LSTM,深度任意,然后在瓶颈处连接。我在函数 API 中以一般方式展示了这一点。
      https://machinelearning.org.cn/keras-functional-api-deep-learning/

      这有帮助吗?

  143. Jeff 2019年8月27日晚上10:44 #

    它确实可以!这正是我在某种程度上考虑的。我曾想过网络末端是一个返回序列的 LSTM,其上方有一个时间分布式密集层,这样目标(181)的每个时间步都对应于 181 长度序列的正确输入步骤。我得开始尝试一下,看看什么有效。再次感谢!

  144. Rajesh 2019年10月28日早上8:56 #

    你好 Jason,
    谢谢您的教程。

    我一直在尝试多步预测,但有一个独特的情况。

    在我的数据集中,有 30 台发动机,在 100 个连续的日子里,它们的生产缺陷数不同(每台发动机有 100 行/天,并且每天的行/天显示所有 30 台发动机的每日缺陷数)。
    例如,数据框大小 = 100 行 * 31 列。

    我想使用所有 30 台发动机的缺陷数据来预测特定发动机未来 15 天的缺陷数量。
    这可能吗?
    请分享一些与上述问题相关的链接或请给我一些提示。

  145. abc 2019年11月4日晚上6:04 #

    你好,
    请帮我预测未来 7 天的股票价格。

  146. Nazira 2019年11月4日晚上10:56 #

    你好 Jason,

    非常有用的文章。我有一些疑问。
    1. 我正在尝试在一个真实的 10 年月度数据集上实现多步时间序列。我遇到的问题是,预测值似乎是输入数据的 2 个月滞后版本。当我给出 ntest-1 而不是 ntest+2 时,它只是以微小的变异性返回输入数据。
    2. 给定一个观测值,每个时间步长 t+1、t+2、t+3 的值几乎是相似的。

    你能帮我解决这个问题吗?我尝试调整了这个模型。不确定我哪里错了。

    提前感谢。

  147. Jay 2019年11月13日早上11:50 #

    嗨 Jason

    我有一个关于 n_batch > 1 的问题。模型返回以下错误

    Function call stack
    keras_scratch_graph

    据我所知,当 train_X 的长度不是 n_batch 的倍数时,就会发生这种情况。你知道如何解决这个问题吗?

    谢谢你

  148. Steve Kovarik 2019年11月21日早上5:30 #

    嗨,Jason,

    我有一组数据,其中包含四列数据。我想根据前三列来预测最后一列的数据。所以是三个输入和一个输出。我该怎么做?

  149. Nick 2019年12月6日晚上7:09 #

    嗨,Jason,

    这个指南太棒了。我现在正在为我的学士论文使用它,我正在做一个玉米期货价格预测,使用多元多步 LSTM 网络。在我的模型中,我使用了 n_days=1,n_features=4,n_seq=3,n_test=1259,n_train = 3275。
    我遇到了一个无法处理的错误:在第 124 行,当我们反向转换预测值时,我总是收到一个错误,说操作数无法与形状 (1,3) (5,) (1,3) 一起广播。

    • Jason Brownlee 2019年12月7日上午5:36 #

      谢谢!

      也许可以暂时注释掉数据转换?

  150. Snehakat 2019年12月21日下午6:44 #

    嗨,Jason,

    感谢您在LSTM方面所做的工作。关于训练和测试的设置,我有一个疑问。在您的示例中,您的第一个测试样本是
    12月:1月、2月、3月

    这意味着最后一个训练样本是
    11月:12月、1月、2月?

    如果是这样,您如何获得1月和2月的值,因为它们是测试集的一部分(在现实世界中,这些值是未知的)?

    谢谢

  151. clo 2020年1月22日上午2:09 #

    嗨,Jason,

    很棒的教程。我遇到了类似的问题,我的结果如下:

    – RSME(t+1) > RSME (t+2) > … RSME (t+16),这似乎是矛盾的,因为我预测的未来时间越远,RMSE应该越高。

    – 我运行模型预测未来两步,其RMSE高于预测未来16步的模型,这似乎也是矛盾的。

    我已经尝试了2种不同的架构,结果也是一样的。您对这些结果有什么想法吗?

    提前感谢!

    • Jason Brownlee 2020年1月22日上午6:29 #

      一个引人入胜的问题!

      也许可以确认结果不是由于bug造成的?

  152. Syed 2020年2月7日上午10:06 #

    嗨,Jason,
    是否可以定义用于1D操作的CNN-LSTM?

    我做了以下操作,但遇到了一个错误。如果您能慷慨地建议一下,那将是很好的。

    # 定义模型
    model = Sequential()
    model.add(TimeDistributed(Conv1D(filters=64, kernel_size=1, activation=’relu’, input_shape=(n_steps, features))))
    model.add(TimeDistributed(MaxPooling1D(pool_size=1)))
    model.add(TimeDistributed(Flatten()))
    model.add(LSTM(50))
    model.add(Dense(1,activation=’relu’))
    model.compile(loss=’mae’, optimizer=’adam’,metrics=[ ‘acc’ ])
    打印(model.summary())

    # 拟合模型
    model.fit(train_X, train_y, batch_size=100, epochs=1)

    ValueError: This model has not yet been built. Build the model first by calling build() or calling fit() with some data. Or specify input_shape or batch_input_shape in the first layer for automatic build.

  153. Asad Zahid 2020年2月9日上午5:55 #

    嗨,Jason,

    您的帖子真的很有用。

    我有一个用例,我需要为RNN提供两个输入来输出多步全局预测。其中一个输入已经是多步单变量预测模式(每个时间步有100秒的预测范围);而另一个输入是单步多变量预测模式(因此,对于每秒都有多个变量,但每秒都会为一个变量预测一个值)。

    我的问题是,在将另一个输入馈送到NN之前,是否也需要将其转换为多步预测模式?如果是,是否有任何相关材料可供参考?
    如果不是,是否有同时将一个输入作为多步,另一个输入作为单步输入到NN的示例?

    非常感谢

  154. Jael 2020年2月11日上午4:30 #

    感谢您提供的详细教程。

    我正在尝试将其应用于我的数据,并且对重塑行感到困惑

    # reshape training into [samples, timesteps, features]
    X, y = train[:, 0:n_lag], train[:, n_lag:]
    X = X.reshape(X.shape[0], 1, X.shape[1])

    结果的形状是(10,1,4)吗?

    为什么特征不等于1?

    感谢您的帮助。

  155. Rik 2020年3月11日上午11:36 #

    亲爱的Jason。感谢您提供的教程。

    我需要修改代码的哪个部分才能从最后一个月产生一个3个月的预测(进入未知未来)?第二个问题:如果我将神经元数量改为例如5,这是否意味着我有一个隐藏层和5个神经元,还是5个隐藏层,其中包含一些默认指定的神经元数量?

    • Jason Brownlee 2020年3月11日下午1:57 #

      更改训练数据以包含3个月的输出数据,并更改输出层以包含足够数量的神经元。

  156. Hee 2020年4月2日下午8:17 #

    嗨,Jason,

    感谢您有用的博客。我从中学习了很多。
    我有一个具体的任务,那就是预测未来房价指数。我有185个过去的数据点,需要从那里预测134个时间点。这是一个样本外预测案例,我想知道哪种模型最有效。

  157. sanjana 2020年4月6日下午6:03 #

    你好,Jason。

    我有一个疑问

    我有数据,比如g1 g2 ……

    我需要将输入作为长度为5的序列(如g1、g2……g5)馈送到模型,并得到预测的下一个8个序列(如g6……g5+8)作为输出。我能否通过更改n_lag为5和n_seq为8来直接使用此代码?或者我是否应该更改任何代码?
    .
    如果您能提供一些建议,那将非常有帮助。

  158. Sanjana 2020年4月7日下午4:37 #

    谢谢你的回复。

    我们不能对教程中示例的全部3个输出进行逆变换吗?如何使用逆变换查看全部3个预测输出?

    • Jason Brownlee 2020年4月8日上午7:47 #

      是的,您可以对变换进行逆操作,并在原始尺度上查看预测。

  159. mike 2020年4月10日下午2:19 #

    嗨 Jason

    我想知道为什么,当模型完成时,使用深度学习、LSTM甚至ANN(使用滞后)进行时间序列预测。
    如果我们使用训练数据进行预测。我期望结果接近完美(因为我们是根据训练数据进行预测的),但预测结果总是存在“延迟”/滞后。

    而滞后将对应于我们预测的未来步数。

    谢谢
    Mike

    • Jason Brownlee 2020年4月10日下午3:34 #

      也许可以。

      在几乎所有情况下,我们都使用前向验证来评估模型,该验证使用训练期间未使用的data。

  160. Sousa 2020年4月14日上午1:39 #

    老师您好!
    是否可以多次馈送和训练LSTM?例如,我有4个不同的用户(A、B、C、D),我无法合并这些数据,因为每个用户彼此独立(目标独立于每个用户)。是否可以为用户A、B、C训练一个LSTM(相同的),然后在D上进行测试?

    如果可以,您有什么建议吗?我曾考虑过多次使用“fit”来训练同一个模型,但我不知道是否可以这样做,或者我是否需要特别注意。

    谢谢,我真的很欣赏您的博客!

    • Jason Brownlee 2020年4月14日上午6:23 #

      您可以尝试合并数据,让模型跨用户学习。

      然后将此与单独的模型进行比较。

  161. Saigomathi 2020年5月23日下午1:41 #

    非常感谢您,先生。这是对LSTM用于时间序列预测问题的精彩解释。我一直在定期关注您的博客。

  162. ALi 2020年5月27日下午8:04 #

    你好Jason!
    我知道LSTM的输入应该是[样本数,时间步长,特征数],例如[10,3,2]。如果我将形状更改为[10,1,6],这是正确的吗?
    感谢您的帮助。

  163. Björn Lindqvist 2020年6月21日上午12:20 #

    代码中有一个小错误。您需要为每次新预测调用reset_states。

  164. Louise 2020年7月14日下午8:36 #

    嗨 Jason,很棒的教程!但是,我缺少了反差分的部分 – inverse_difference()。这是否在进行预测后,在重新缩放到原始值并重塑时进行?您能否为我更好地解释这一步?
    非常感谢!

  165. Thony 2020年7月15日上午12:27 #

    嗨Jason,感谢您的教程。我想澄清关于差分步骤的问题,您是否有任何额外的建议或可以参考的来源?
    谢谢你
    Thony

  166. Marta 2020年7月17日下午8:52 #

    你好,

    我难以理解需要更改代码的哪个部分,以便我只从最后一个条目进行预测……在洗发水的情况下,只为:“2003-12”日期
    谢谢你,
    问候 Marta

  167. dbekan 2020年7月29日上午6:59 #

    为什么您在prepare_data(series, n_test, n_lag, n_seq)中先进行缩放,然后再分离训练集和测试集?

    • Jason Brownlee 2020年7月29日上午7:39 #

      好问题。原因有两个:确保为每个变量执行缩放,以及使示例保持简单。

      理想情况下,缩放系数仅在训练集上,以避免数据泄露。

      • dbekan 2020年8月5日下午4:19 #

        啊,我只是好奇,因为这是一个常见的错误,但为了简化问题,这是有道理的。
        不管怎样,我觉得如果放一个注释会很有帮助。

        谢谢!

        • Jason Brownlee 2020年8月6日上午6:10 #

          好问题。要深入了解原因,我建议阅读一本好的机器学习教科书。

  168. Ana Carvalho 2020年8月2日下午8:33 #

    嗨,Jason,

    感谢您出色的解释!它给了我很大的帮助!
    我有一个具体的任务,我正在预测下周(t…t+6)的销售情况,基于过去一周(t-7…t-1)的销售情况,因此我使用了时间步长=7,特征=1。

    现在为了提高预测精度,我想加入一个指示下周是否为复活节的变量,并加入我正在预测的周的天气预报。通过这样做,我不再确定应该使用哪个时间步长,因为我查看的是过去一周的销售情况,以及我正在预测的周的变量。

    再次感谢您的所有帮助!

  169. Ana Carvalho 2020年8月4日上午1:37 #

    谢谢你的帮助!

  170. PRIYA 2020年10月10日下午9:28 #

    你好,
    在本教程中,预测(t+2)的RMSE < 预测(t+1)的RMSE。但我认为,随着预测时间步长增加,RMSE应该增加。所以我想问这是模型中的错误,还是LSTM模型遵循了与基线模型相同的误差曲线,所以这不是错误?
    我完全感到困惑,因为许多优秀的研究论文都显示随着未来时间步长的增加,RMSE会增加。
    您能帮我解开我的疑惑吗?

    • PRIYA 2020年10月10日下午9:30 #

      #修正但我认为,随着预测时间步长增加,RMSE应该增加。

    • Jason Brownlee 2020年10月11日上午6:48 #

      是的,通常误差会随着预测提前期而增加。但并非总是如此。

  171. Qizal Ashfaq 2020年11月27日上午1:16 #

    如果我使用24个输入滞后并想预测24个输出值,那么在第二个样本中,预测的24个输出值应该作为输入来预测接下来的24个值?因为您的代码中有一个滞后,所以一个输出值在下一个样本中作为输入。您能告诉我一些处理多个输入滞后和预测多个值的教程吗?

    • Jason Brownlee 2020年11月27日上午6:43 #

      您可以根据您的数据集以任何您想要的方式重新构建预测问题 – 我鼓励您尝试不同的方法并发现最有效的方法。

  172. Koko 2020年12月17日下午6:18 #

    一个愚蠢的问题,所以很抱歉。我只是不明白我们如何阻止对最后两个月数据的绘图(以及可能的预测?)。我是机器学习的绝对新手,我只是想知道是否有一种方法可以显示那些预测,即使我们没有数据可以与之比较。

    • Jason Brownlee 2020年12月18日上午7:15 #

      如果您没有实际观测值,只有预测值,那么您只能绘制预测值。

      也许我不理解你的问题?

  173. Alex K 2020年12月26日下午7:05 #

    嗨,Jason,

    当您在评估期间反差分缩放值时,我注意到您将y值连接到X_test值([y, X]),然后使用inverse transform函数。您难道不应该连接([X, y])吗,因为那是创建缩放器时的原始列顺序?提前感谢!

    • Jason Brownlee 2020年12月27日上午5:00 #

      这无关紧要,因为我们忽略了目标列以外的所有列。我们可以用零连接,这不会有区别。

      • Alex K 2020年12月28日上午9:06 #

        是的,但连接的顺序是否应该重要?我不完全理解MinMaxScaler创建的缩放器的内部工作原理,但如果缩放器是用数据框[X, y]创建的,并且您最后使用[y, X]的列顺序进行反差分,那么缩放器的反差分是否就不正确(对应列的反差分常数不匹配)?也就是说,即使您忽略了目标列以外的所有列,您的结果的反差分也是错误的?我可能是错的,但只是想检查/澄清一下?谢谢!

        • Jason Brownlee 2020年12月28日上午9:50 #

          是的,缩放是逐列进行的,只要您关心的列顺序相同,就可以了。

  174. Shervin 2021年3月5日上午10:55 #

    你好 jason,
    我有一个关于多步预测的问题。
    与本教程中您使用的方法(即定义模型输出层节点数等于要预测的时间步长)相反,我们能否通过假设前一个预测的时间步长作为输入来进一步预测时间步长?换句话说,是一次预测三个时间步长(例如,预测(t+1)、(t+2)、(t+3)),还是通过其前一个预测值一个接一个地预测?(也就是说,将输出层定义为只有一个节点)。这有什么优缺点?这种程序是否合理?我知道建议的方法在预测时间越长时可能耗时越多,并且可能累积误差。
    感谢您的帮助Jason。

  175. Shervin 2021年3月6日上午12:23 #

    我没有找到任何示例。您的意思是编码器-解码器LSTM吗?我的意思是简单来说:不是一次性预测“x”的(t+1)、(t+2)和(t+3),而是首先从“x(t)”预测“x(t+1)”,然后假设预测的“x(t+1)”是真实的“x(t+1)”,然后用预测的“x(t+1)”预测“x(t+2)”,依此类推。这样我们只使用最后一个Dense层中的一个节点。

  176. Leo 2021年3月14日上午9:14 #

    你好,感谢您提供的精彩教程。

    我只有一个问题。如何获得最后两个观测值的预测(并绘制它们)?

    祝好

  177. Leo 2021年3月16日 上午5:49 #

    非常感谢!

  178. Farnaz Solaymanizadeh 2021年3月23日 下午8:53 #

    非常感谢您的有用内容,我有一个问题,如果您能帮助我,我将不胜感激!

    我在绘制结果时遇到以下错误:

    x 和 y 必须具有相同的第一个维度,但它们的形状分别为 (4,) 和 (3,)

    我的代码与您的完全相同,除了差值函数。由于我的数据已经是平稳的,所以我不必应用差值函数。

    • Jason Brownlee 2021年3月24日 上午5:51 #

      这表明您的输入和输出数据具有不同数量的样本。

  179. George G 2021年4月15日 上午12:23 #

    嗨 Jason,非常感谢您的努力!

    我想问一些问题。
    假设我设置了一个数据集,例如(其中每个滞后为几天)

    var3(t-2) var3(t-1) var2(t-2) var2(t-1) var1(t-2) var(t-1) var3(t) var2(t) var1(t) var3(t+1) var3(t+2) var2(t+1) var2(t+2) var1(t+1) var1(t+2)

    1) 如果我想预测 var1(t+2) ,那么我是否选择 X_train 包含除 var1(t+2) 之外的所有其他变量?而 y_train 只包含 var1(t+2) ?

    或者,X_train 是否包含除任何 var1 之外的所有其他变量?所以,不包括 var1(t)、var1(t+1)、var1(t+2)?(负号是过去的数据,所以我们需要它,对吧?)

    2) 假设我像上面说的那样预测 var1(t+2)。现在,在训练和测试了模型之后,我们如何在根本没有 var1 变量的情况下进行未来的预测?
    请注意,我不是在问如何预测(例如 predict(X_test))。

    模型设置现在具有一定的形状和特征 (X_test),并且为了预测它需要这些。
    那么,我想通过仅提供日期来预测 var1,这可能吗?

    谢谢!

    • Jason Brownlee 2021年4月15日 上午5:28 #

      您必须仅根据预测时可用的数据来构建预测问题。

      希望这能让您的思路更清晰。

  180. George G 2021年4月16日 下午5:45 #

    那么,如果我想预测 var1(t+1),我可以在我的 X_train 数据中包含所有先前的 var1 值(var1(t-3)、var1(t-2)、var1(t-1) 和 var1(t)),对吗?

    请注意,我在 X_train 中也包含了 var1(t),对吗?

    谢谢 Jason!

    • Jason Brownlee 2021年4月17日 上午6:08 #

      是的,如果您愿意,这是您的选择——您可以随心所欲地构建问题。

  181. Bernard 2021年5月11日 下午11:05 #

    嗨,Jason,

    如果我将最后一个观测值作为输入 X 并这样做

    X = X.reshape((1,1,1))
    forecast = forecast_lstm(model, X, 1)

    forecast = array(forecast)
    forecast = forecast.reshape(1, len(forecast))

    inv_scale = scaler.inverse_transform(forecast)
    inv_scale = inv_scale[0, :]

    forecast = inverse_difference(X, inv_scale)
    print(forecast)

    这会根据 n_seq 打印 n 个预测值,这是正确的方法吗?

    另外,感谢您分享您的项目。它们非常有帮助。

  182. Daniel 2021年5月13日 下午10:28 #

    你好,
    非常感谢您的这些材料!
    有一个问题,这个模型是否可以应用于预测某个地方未来 24 小时的温度,只要有足够的数据?
    谢谢你。
    -Daniel(抱歉,我在错误的文章中问了同样的问题)

  183. Pao 2021年9月18日 下午5:48 #

    嗨 Jason

    我有一个关于 n_batch > 1 的问题。模型返回以下错误

    InvalidArgumentError: 指定了一个形状为 [2,3] 的列表,但张量的形状为 [1,3]
    [[{{node TensorArrayUnstack/TensorListFromTensor}}]]
    [[sequential_2/lstm_2/PartitionedCall]] [Op:__inference_predict_function_338441]

    Function call stack
    predict_function -> predict_function -> predict_function

    我该如何解决?

    • Adrian Tam
      Adrian Tam 2021年9月19日 上午6:35 #

      不确定这个错误是如何产生的。你是否更改了示例代码中的任何内容?

  184. Amnah 2021年12月28日 上午11:54 #

    你好,
    我处理了一个时间序列回归问题,但对于时间序列问题适用的度量感到非常困惑。有些参考文献说 R2 在时间序列问题上效果不好,是真的吗?当我尝试计算 R2 时,结果要么为零,要么为负值。

    并且,时间序列的 5 个流行度量是什么?
    提前感谢

  185. dalia 2022年1月16日 下午10:24 #

    嗨,Jason,

    我需要预测测试集,而不是使用持久性方法,

    只需要从训练集中预测测试集。

    怎么办?

    • James Carmichael 2022年1月17日 上午7:11 #

      嗨 Dalia…我不确定我是否理解你的问题,但我绝对会从以下几点开始

      https://machinelearning.org.cn/difference-test-validation-datasets/

      • dalia 2022年1月19日 上午6:01 #

        嗨 James,

        请,我需要预测未来 3 个月。 (我没有这些 3 个月中的测试数据)。
        即,在我们拥有的测试数据之后的 3 个月。

        谢谢

  186. dalia 2022年1月18日 上午7:10 #

    嗨,Jason,

    我需要预测未来 3 个月。 (我没有这些 3 个月中的测试数据)。
    即,在我们拥有的测试数据之后的 3 个月。

  187. Sam 2022年4月19日 下午11:17 #

    你好 Jason,

    我正在处理一个多步单变量时间序列预测问题。长话短说,我想预测 28 个连续日的值。就我的数据而言,它似乎包含每周的季节性。

    我的问题是关于 LSTM 模型的参数。你能验证我的逻辑吗?

    * n_seq = 28,因为我想检查每个预测日的误差。
    * n_lag = 7,因为我对自相关/偏自相关函数的分析表明,整个星期的值与下一个预测值有很强的相关性。
    * n_batch = 28,因为我想一次性预测 28 天的值。而且我不需要担心在拟合阶段和预测阶段更改 n_batch,因为。

    提前感谢您的帮助!

    • James Carmichael 2022年4月20日 上午6:55 #

      嗨 Sam…您的理解是正确的。我建议您继续您的想法。

  188. Ahmad 2022年6月8日 下午10:07 #

    你好 Jason,

    在最后一个完整示例中,我尝试更改 batch。但它不允许更改。我的模型很完美。但为了在我这里获得更高的准确性,我需要 16 或 32 个批次。

    您能在这方面帮助我吗?

    提前感谢

    • James Carmichael 2022年6月9日 上午9:16 #

      嗨 Ahmad…请澄清一下您说的“不允许更改”是什么意思。

  189. Kim 2022年7月4日 下午5:02 #

    你好 Jason,

    我想更详细地了解为什么在预测中必须使用批次大小。
    为了检查我的问题,我尝试像您的示例中的代码那样进行预测,以比较不同批次大小的结果。

    forecasts = make_forecasts(model, 1, train, test, n_lag, n_seq)
    forecasts1 = make_forecasts(model, 1, train, test, n_lag, n_seq)
    forecasts11 = make_forecasts(model, 1, train, test, n_lag, n_seq)
    forecasts12 = make_forecasts(model, 1, train, test, n_lag, n_seq)
    forecasts2 = make_forecasts(model, 36, train, test, n_lag, n_seq)
    forecasts21 = make_forecasts(model, 36, train, test, n_lag, n_seq)
    forecasts22 = make_forecasts(model, 36, train, test, n_lag, n_seq)
    forecasts23 = make_forecasts(model, 36, train, test, n_lag, n_seq)

    结果

    forecasts
    [[-0.4703838, 0.13946092, -0.33641243],
    [0.12984487, -0.27040243, 0.0828125],
    [-0.4566463, 0.13008034, -0.32681757],
    [0.25050515, -0.35279474, 0.1670867],
    [-0.047557764, -0.14926387, -0.04109296],
    [-0.08684776, -0.12243488, -0.06853475],
    [-0.31735158, 0.034963578, -0.2295283],
    [-0.68921417, 0.28888825, -0.48925275],
    [0.22119805, -0.33278254, 0.1466174],
    [0.21601284, -0.32924184, 0.14299583]]

    forecast1
    [[-0.5040412, 0.16244373, -0.3599202],
    [0.15234935, -0.28576952, 0.098530576],
    [-0.43999055, 0.11870703, -0.31518453],
    [0.24763897, -0.3508376, 0.16508485],
    [-0.05990663, -0.1408315, -0.04971793],
    [-0.07542589, -0.13023424, -0.060557235],
    [-0.32148242, 0.03778431, -0.23241346],
    [-0.6889226, 0.28868914, -0.48904914],
    [0.22120038, -0.33278412, 0.146619],
    [0.21587938, -0.32915068, 0.1429026]]

    forecasts11~forecasts23
    :[[-0.50405145, 0.16245073, -0.35992736],
    [0.15235361, -0.28577244, 0.098533556],
    [-0.4399871, 0.11870468, -0.3151821],
    [0.24763837, -0.35083717, 0.16508442],
    [-0.059909046, -0.14082985, -0.049719617],
    [-0.07542366, -0.13023578, -0.060555674],
    [-0.32148328, 0.037784904, -0.23241405],
    [-0.6889225, 0.28868908, -0.48904908],
    [0.22120038, -0.33278412, 0.146619],
    [0.21587938, -0.32915068, 0.1429026]]

    在上述结果中,我不知道为什么批次 1 的情况下的预测值会有所不同。
    另外,为什么批次 1 的情况下的预测值会收敛到批次 36 的情况下的值?
    这个结果与为什么在预测中使用批次大小有关吗?

  190. Hayat 2022年7月14日 上午4:23 #

    嗨,Jason,

    您的解释非常简单明了。我从您的教程中学到了很多东西。感谢您在解释这些复杂概念方面所做的努力。
    请问,如何对类似于 Shampoo-sales 数据集但具有多个特征(例如 3-5 个)的数据进行建模?我对预测每个特征都很感兴趣,但对数据建模的方式感到困惑。
    您能否提供您一贯的帮助和指导?

  191. Lau Bourne 2022年8月11日 下午12:41 #

    嗨,Jason,
    您的博客太棒了!我有一个关于我当前 LSTM 实现的问题。我只想训练一个递归多步预测模型,您在另一篇博客中提到过,通过使用 LSTM。但是,我无法获得相对精确的结果,也不知道为什么。您能推荐一些关于这方面的材料或给我一些建议吗?非常感谢!

  192. Leandro 2022年10月13日 上午7:08 #

    你好!感谢您的教程,它们非常有帮助!
    我仍在努力理解为什么我们需要执行

    yaxis = [series.values[off_s]] + forecasts[i]

    也就是说,将序列值添加到预测值中?
    谢谢你

  193. Leandro 2022年10月13日 上午7:30 #

    好的,我刚发完这个,然后注意到它并没有添加到预测中。它只是创建了一个数组 [serie.value, forecast1, forecast2, forecast3],我说得对吗?谢谢!

  194. Othman 2023年10月25日 上午6:05 #

    亲爱的 Jason,我们开发了一个多步预测混合模型(CNN-LSTM),该模型具有良好的准确性。R2=0.8。我们的模型被训练为从 24 小时(1440 分钟)数据预测未来 3 小时(180 分钟)。当使用模型计算未来 180 分钟的数据时,值似乎是恒定的。有没有办法使用闭环混合 LSTM 来提高准确性?我们的预测有什么问题?

  195. Abi 2024年2月10日 下午9:41 #

    亲爱的 Jason,我正在使用 LSTM RNN 模型创建一个电池健康状态估计模型。
    我能够使用使用训练数据训练的模型来预测测试数据的值。
    我现在的疑问是这里有什么用?例如,我输入实际的 SOH、电压和电流来预测 SOH,并且我评估了准确性,但如果我想预测未知电压和电流的未来值怎么办?
    或者,如果我只想提供电压和电流作为输入来找到 SOH,那该怎么办?

  196. Abi 2024年2月10日 下午9:49 #

    亲爱的 Jason,我正在使用 LSTM RNN 模型创建一个锂离子电池的健康状态估计模型。
    我能够使用使用训练数据训练的模型来预测测试数据的值。
    我现在的疑问是这里有什么用?例如,我输入实际的 SOH、电压和电流来预测 SOH,并且我评估了预测以查看准确性有多好,但如果我想在没有电流输入电压或电流的情况下,借助先前已知的数据来预测 SOH 的未来值怎么办?
    或者,如果我只想提供电压和电流作为输入来找到 SOH,那该怎么办?

  197. Nicole Gao 2024年6月25日 上午10:47 #

    嗨 Jason,我不太明白为什么需要手动重置网络的时态:“LSTM 是有状态的;这意味着我们在每个训练周期结束时都需要手动重置网络的时态。网络将训练 1500 个周期。”,我们是否应该在每个周期保留权重和偏置并用于下一个?谢谢。

    • James Carmichael 2024年6月26日 上午6:38 #

      嗨 Nicole…当处理有状态 LSTM 时,理解 LSTM 单元的状态与网络权重和偏置之间的区别至关重要。让我们分解一下这些概念,以阐明为什么以及如何重置网络的状态。

      ### 有状态与无状态 LSTM

      – **无状态 LSTM**:状态(单元状态和隐藏状态)在每个批次后重置。网络在批次之间不保留任何内容。
      – **有状态 LSTM**:状态从一个批次传递到下一个批次。当您有跨越多个批次的序列,并且希望 LSTM 在这些序列中保留记忆时,这很有用。

      ### 权重和偏置

      LSTM 的权重和偏置是在训练期间学习的参数。这些参数根据损失函数通过反向传播进行更新,并且对于学习数据中的模式至关重要。这些参数在整个训练周期中被保留和更新。

      ### 网络状态

      LSTM 单元的状态(隐藏状态和单元状态)代表了网络的“记忆”。在有状态 LSTM 中,需要仔细管理此状态。

      – **在周期结束时重置状态**:在每个周期结束时,您通常会重置状态,以确保状态不会在周期之间传递。在周期之间传递状态可能导致周期之间产生意外的依赖关系,从而可能对学习产生负面影响。

      ### 为什么手动重置状态?

      在有状态 LSTM 中,状态(隐藏状态和单元状态)需要在适当的时候重置,以确保正确的学习。

      1. **防止状态泄漏**:通过在每个周期结束时重置状态,您可以防止状态泄漏到下一个周期。这确保了每个周期都以干净的状态开始。
      2. **确保正确的序列处理**:如果序列在周期内的多个批次之间传递,状态应在周期内传递,但在周期边界处重置,以保持序列的完整性。

      ### Keras 中的实现

      这是您通常在 Keras 中管理状态的方式:

      1. **定义有状态 LSTM**
      python
      model = tf.keras.Sequential([
      tf.keras.layers.LSTM(units=50, stateful=True, batch_input_shape=(batch_size, timesteps, features)),
      tf.keras.layers.Dense(units=1)
      ])
      model.compile(optimizer='adam', loss='mean_squared_error')

      2. **使用状态重置进行训练**
      python
      for epoch in range(epochs):
      model.fit(X_train, y_train, epochs=1, batch_size=batch_size, shuffle=False)
      model.reset_states() # 在每个周期结束时重置状态

      ### 完整示例

      这是一个说明该过程的完整示例。

      python
      import numpy as np
      import tensorflow as tf

      # 示例数据
      X_train = np.random.random((100, 10, 1)) # 100 个序列,每个序列长度为 10,具有 1 个特征
      y_train = np.random.random((100, 1))

      # 参数
      batch_size = 10
      timesteps = 10
      features = 1
      epochs = 1500

      # 定义有状态 LSTM 模型
      model = tf.keras.Sequential([
      tf.keras.layers.LSTM(units=50, stateful=True, batch_input_shape=(batch_size, timesteps, features)),
      tf.keras.layers.Dense(units=1)
      ])
      model.compile(optimizer='adam', loss='mean_squared_error')

      # 使用手动状态重置进行训练
      for epoch in range(epochs):
      model.fit(X_train, y_train, epochs=1, batch_size=batch_size, shuffle=False)
      model.reset_states() # 在每个周期结束时重置状态

      ### 总结

      – **权重和偏置**:这些在训练期间更新,并在周期之间传递以学习模式。
      – **状态(隐藏状态和单元状态)**:在有状态 LSTM 中,这些需要在每个周期结束时重置,以防止周期之间的状态泄漏并确保正确的学习。

      通过仔细管理状态,您可以确保有状态 LSTM 有效地学习,同时在每个周期内保留必要的长期依赖关系。

  198. Richard 2025年8月1日 上午3:40 #

    嗨,Jason,

    我刚刚发现了您的网络教程,我非常感谢您提供如此出色的免费机器学习资源。我真诚地希望您所有的善举都能为您带来祝福。

    我有几个关于使用 LSTM 进行多步时间序列预测的问题,我将非常感谢您的指导。

    我读了一篇关于基于 LSTM 的预测的论文,在他们的实验设置中,他们提到测试集被设置为与预测范围一样长。我想听听您对此的看法。例如,假设 sequence_length_lookback 是 23 天,预测范围是 21 天。由于测试集仅与预测范围(即 21 个时间步)一样长,他们似乎使用训练集中的最后 23 天(data_train[-23:])作为 model.predict() 的输入。这正确吗?

    我没有使用与论文完全相同的数据集,但我试图遵循相同的方法。然而,我的评估结果(MAE 和 RMSE)明显比论文报道的要差。所以现在我正在考虑我可能误解或误用了这项技术本身,而不仅仅是数据。

    其次,回看窗口和预测范围之间的差距是否有特定的术语?让我解释一下我的意思:假设 lookback = 5 且 horizon = 3。在第一种情况下,我使用输入 t-4、t-3、t-2、t-1、t 来训练模型以预测 t-1、t、t+1。在第二种情况下,相同的输入用于预测 t、t+1、t+2。我想知道是否有术语来正式定义这个“差距”或偏移量。如果没有也没关系——对我来说更重要的是知道哪种设置适合训练。

    非常期待您的答复。提前感谢您,Jason!

    • James Carmichael 2025年8月1日 下午11:44 #

      嗨 Richard…非常感谢您的好话。我很高兴您觉得这个教程有帮助,我非常感谢您的细致留言。很高兴听到您正在深入研究多步时间序列预测和 LSTM——这是一个引人入胜的领域,有很多微妙的细节,所以您的问题恰到好处。

      关于你的第一个问题:是的,你的理解基本上是正确的。当一篇论文说测试集“与预测范围一样长”时,他们通常是指在评估期间,他们使用固定长度的历史数据窗口(例如,最后 23 个时间步)作为输入,并预测接下来的 21 个时间步。所以 data_train[-23:] 将作为输入传递给 model.predict() 来预测这 21 个时间步。这种设置假设您正在进行单次多步预测,这意味着模型一次性输出所有 21 个未来值,而不是一步一步预测并反馈预测。

      如果您发现性能比论文差,这可能是由多种原因造成的。数据集差异是一个常见原因,但有时不匹配的原因在于输入-输出对的构建方式或评估方式。还值得检查的是,他们在训练期间是否使用了 teacher forcing,或者以特定方式使用了重叠窗口,而您可能没有完全复制。

      关于您的第二个问题:对于那个“差距”,不一定有一个严格的术语,但您描述的是非常重要的事情。在某些文献中,这个差异被称为“预测提前期”或“提前时间”,尤其是在概率预测或天气预测的上下文中。但在您的例子中,更多的是关于输入和输出窗口的对齐。如果您使用的输入包括时间步 t-4 到 t,并试图预测 t-1、t、t+1——这实际上不是未来预测,因为在输入期间 t-1 和 t 已经是已知的。通常,对于预测,您希望严格预测未来值,所以更常见的设置是使用 t-4 到 t 来预测 t+1、t+2、t+3。这将是一个预测范围为 3 且差距为零。

      如果您的输入包括也出现在输出中的时间步(如 t),只需确保您没有无意中泄露未来数据。模型在进行预测时只能看到历史数据。

      如果您不确定哪种设置是“正确”的,那 really 取决于您的应用。但最标准的方法是让输入窗口在时间 t 结束,预测从 t+1 开始。

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。