用于时间序列预测的随机森林

随机森林是一种流行且有效的集成机器学习算法。

它广泛用于结构化(表格)数据集的分类和回归预测建模问题,例如电子表格或数据库表中的数据。

随机森林也可用于时间序列预测,尽管它要求时间序列数据集首先转换为监督学习问题。它还需要使用一种称为“滚动预测验证”的特殊技术来评估模型,因为使用 k 折交叉验证评估模型会导致乐观偏颇的结果。

在本教程中,您将学习如何开发用于时间序列预测的随机森林模型。

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

  • 随机森林是决策树算法的集成,可用于分类和回归预测建模。
  • 时间序列数据集可以通过滑动窗口表示转换为监督学习。
  • 如何使用随机森林回归模型进行时间序列预测的拟合、评估和预测。

让我们开始吧。

Random Forest for Time Series Forecasting

用于时间序列预测的随机森林
照片由 IvyMike 拍摄,保留部分权利。

教程概述

本教程分为三个部分;它们是:

  1. 随机森林集成
  2. 时间序列数据准备
  3. 用于时间序列的随机森林

随机森林集成

随机森林是决策树算法的集成。

它是决策树的引导聚合(bagging)的扩展,可用于分类和回归问题。

在 bagging 中,生成多个决策树,其中每个树都是从训练数据集的不同引导样本创建的。 引导样本是训练数据集的一个样本,其中一个示例可能在样本中出现多次。这被称为“有放回抽样”。

Bagging 是一种有效的集成算法,因为每个决策树都在略有不同的训练数据集上拟合,因此性能也略有不同。与正常的决策树模型(例如分类和回归树 (CART))不同,集成中使用的树未经剪枝,使它们对训练数据集略有过拟合。这是可取的,因为它有助于使每棵树更不同,并且预测或预测误差的相关性更小。

来自树的预测在所有决策树上进行平均,从而产生比模型中任何单个树更好的性能。

回归问题的预测是集成中所有树的预测的平均值。分类问题的预测是集成中所有树的类别标签的多数投票。

  • 回归:预测是决策树的平均预测。
  • 分类:预测是决策树预测的多数投票类别标签。

随机森林涉及从训练数据集的引导样本中构建大量决策树,就像 bagging 一样。

与 bagging 不同,随机森林在树的构建过程中,在每个分裂点还涉及选择输入特征(列或变量)的子集。通常,构建决策树涉及评估数据中每个输入变量的值以选择一个分裂点。通过将每个分裂点可能考虑的特征减少到随机子集,它迫使集成中的每个决策树更加不同。

其结果是,集成中每棵树所做的预测以及预测误差更加不同或相关性更小。当这些相关性较小的树的预测进行平均以进行预测时,它通常会比 bagging 决策树产生更好的性能。

有关随机森林算法的更多信息,请参阅教程

时间序列数据准备

时间序列数据可以被表述为监督学习。

给定一个时间序列数据集的数字序列,我们可以重新构造数据,使其看起来像一个监督学习问题。我们可以通过使用先前的时间步作为输入变量,并将下一个时间步作为输出变量来实现这一点。

让我们用一个例子来具体说明这一点。假设我们有一个时间序列如下:

我们可以通过使用前一时间步的值来预测下一时间步的值,将此时间序列数据集重构为监督学习问题。

以这种方式重新组织时间序列数据集,数据将如下所示

请注意,时间列被删除,并且某些数据行无法用于训练模型,例如第一行和最后一行。

这种表示被称为滑动窗口,因为输入和预期输出的窗口随时间向前移动以创建用于监督学习模型的新“样本”。

有关准备时间序列预测数据的滑动窗口方法的更多信息,请参阅教程

我们可以使用 Pandas 中的 shift() 函数,根据所需的输入和输出序列长度自动创建时间序列问题的新框架。

这将是一个有用的工具,因为它将允许我们使用机器学习算法探索时间序列问题的不同框架,以查看哪个可能产生性能更好的模型。

下面的函数将把一个带有多列或单列的 NumPy 数组时间序列作为时间序列,并将其转换为具有指定数量输入和输出的监督学习问题。

我们可以使用此函数来为随机森林准备时间序列数据集。

有关此函数逐步开发的更多信息,请参阅教程

一旦数据集准备好,我们必须小心如何使用它来拟合和评估模型。

例如,在未来的数据上拟合模型并让它预测过去是无效的。模型必须在过去的数据上训练并预测未来。

这意味着不能使用在评估过程中随机化数据集的方法,例如k 折交叉验证。相反,我们必须使用一种称为“滚动预测验证”的技术。

在滚动预测验证中,数据集首先通过选择一个截止点来分割成训练集和测试集,例如,除了最后 12 个月的所有数据都用于训练,最后 12 个月用于测试。

如果我们对进行一步预测(例如一个月)感兴趣,那么我们可以通过在训练数据集上训练模型并预测测试数据集中的第一步来评估模型。然后我们可以将测试集中的真实观测值添加到训练数据集,重新拟合模型,然后让模型预测测试数据集中的第二步。

对整个测试数据集重复此过程将为整个测试数据集提供一步预测,可以从中计算误差度量以评估模型的技能。

有关滚动预测验证的更多信息,请参阅教程

下面的函数执行滚动预测验证。

它将时间序列数据集的整个监督学习版本以及用作测试集的行数作为参数。

然后,它逐步遍历测试集,调用 `random_forest_forecast()` 函数进行一步预测。计算误差度量并返回详细信息以供分析。

调用 `train_test_split()` 函数将数据集分割成训练集和测试集。

我们可以在下面定义这个函数。

我们可以使用 RandomForestRegressor 类进行一步预测。

下面的 `random_forest_forecast()` 函数实现了这一点,它将训练数据集和测试输入行作为输入,拟合模型并进行一步预测。

现在我们知道如何准备时间序列数据以进行预测并评估随机森林模型,接下来我们可以看看如何在真实数据集上使用随机森林。

用于时间序列的随机森林

在本节中,我们将探讨如何使用随机森林回归器进行时间序列预测。

我们将使用一个标准的单变量时间序列数据集,目的是使用模型进行一步预测。

您可以使用本节中的代码作为您自己项目的起点,并轻松将其用于多变量输入、多变量预测和多步预测。

我们将使用每日女性出生数据集,即三年内的每月出生人数。

您可以从这里下载数据集,并将其放置在当前工作目录中,文件名为“daily-total-female-births.csv”。

数据集的前几行如下所示

首先,让我们加载并绘制数据集。

完整的示例如下所示。

运行示例会创建数据集的折线图。

我们可以看到没有明显的趋势或季节性。

Line Plot of Monthly Births Time Series Dataset

每月出生时间序列数据集的折线图

在预测最后 12 个月时,持久性模型可以实现大约 6.7 次出生的平均绝对误差 (MAE)。这提供了一个基准性能,高于该性能的模型可以被认为是熟练的。

接下来,我们可以评估随机森林模型在数据集上对过去 12 个月数据进行一步预测时的表现。

我们将仅使用前六个时间步作为模型输入和默认模型超参数,除了我们将使用 1000 棵树的集成(以避免欠学习)。

完整的示例如下所示。

运行示例会报告测试集中每个步骤的预期值和预测值,然后报告所有预测值的 MAE。

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

我们可以看到该模型的性能优于持久性模型,MAE 约为 5.9 次出生,而持久性模型为 6.7 次出生。

你能做得更好吗?

您可以测试不同的随机森林超参数和输入时间步数,看看是否可以获得更好的性能。在下面的评论中分享您的结果。

创建了一个折线图,比较了数据集中最后 12 个月的预期值系列和预测值系列。

这提供了模型在测试集上表现如何的几何解释。

Line Plot of Expected vs. Births Predicted Using Random Forest

使用随机森林预测的出生人数与预期人数的折线图

一旦选择了最终的随机森林模型配置,就可以最终确定模型并用于对新数据进行预测。

这被称为样本外预测,例如预测超出训练数据集。这与模型评估期间进行预测相同,因为我们总是希望使用我们期望模型用于对新数据进行预测的相同过程来评估模型。

下面的示例演示了在所有可用数据上拟合最终随机森林模型并对数据集末尾之外进行一步预测。

运行示例会在所有可用数据上拟合一个随机森林模型。

使用已知数据的最后六个月准备新输入行,并预测数据集末尾之外的下个月。

进一步阅读

如果您想深入了解,本节提供了更多关于该主题的资源。

教程

API

总结

在本教程中,您了解了如何开发用于时间序列预测的随机森林模型。

具体来说,你学到了:

  • 随机森林是决策树算法的集成,可用于分类和回归预测建模。
  • 时间序列数据集可以通过滑动窗口表示转换为监督学习。
  • 如何使用随机森林回归模型进行时间序列预测的拟合、评估和预测。

你有什么问题吗?
在下面的评论中提出你的问题,我会尽力回答。

想用Python开发时间序列预测吗?

Introduction to Time Series Forecasting With Python

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

...只需几行python代码

在我的新电子书中探索如何实现
Python 时间序列预测入门

它涵盖了**自学教程**和**端到端项目**,主题包括:*数据加载、可视化、建模、算法调优*等等。

最终将时间序列预测带入
您自己的项目

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

查看内容

对《时间序列预测中的随机森林》的 151 条回复

  1. Winly Williamdy 2020 年 11 月 6 日上午 5:25 #

    一如既往地非常有帮助!感谢分享。

  2. Dorina Grossu 2020 年 11 月 6 日上午 10:43 #

    太棒了,谢谢

  3. Dr. Satish Chinchorkar 2020 年 11 月 6 日下午 12:50 #

    内容丰富、文章精彩,用简单易懂的语言解释了复杂的概念。感谢您分享这些有价值的知识。

  4. A. Aboukarima 2020 年 11 月 6 日下午 6:14 #

    太棒了,谢谢

    • Jason Brownlee 2020 年 11 月 7 日上午 6:26 #

      谢谢。

      • Fawad 2020 年 11 月 7 日下午 4:17 #

        感谢你的笔记本。我们如何进行多变量输入(而不是只用滞后)并进行 4-5 步提前预测呢?

        • Jason Brownlee 2020 年 11 月 8 日上午 6:38 #

          我相信随机森林可以直接支持多个输出。

          例如,准备您的数据并拟合您的模型。

          • Gunjan Hense 2020 年 12 月 12 日上午 4:27 #

            你好 Jason……
            非常感谢这篇文章。我发现您的大部分文章都非常有用和信息丰富。

            需要您的建议——我有一系列产品,包含 3 年的历史数据以及其他预测变量。是否有直接的方法可以一次性训练所有产品,并生成长达 18 个月的多步预测。

          • Jason Brownlee 2020 年 12 月 12 日上午 6:32 #

            谢谢。

            我建议您测试一套不同的方法,以发现哪种方法最适合您的数据集。

        • Gunjan 2020 年 12 月 12 日下午 9:05 #

          嗨,Fawad

          您找到解决办法了吗——我们如何进行多变量输入(而不是仅滞后)并进行 4-5 步的提前预测。另外我有很多产品。如何为随机森林构建这种输入?

          • Jason Brownlee 2020 年 12 月 13 日上午 6:02 #

            相同的函数可用于准备多变量数据,相同的模型可用于建模。

  5. Kegomoditswe Boikanyo 2020 年 11 月 12 日下午 6:23 #

    嗨 Jason

    我一直在尝试运行该程序,但我收到这些错误

    第 56 行,在 walk_forward_validation 中
    testX, testy = test[i, :-1], test[i, -1]
    IndexError:轴 1 的索引 -1 超出范围,大小为 0

  6. Christophe 2020 年 12 月 2 日下午 9:27 #

    太棒了,非常感谢。即使经过粗略的法语翻译,它也易于理解、具有教育意义且可用 🙂

  7. manon 2020 年 12 月 2 日下午 9:36 #

    有没有更简单的函数来定义滚动训练?

  8. mlmuser001 2020 年 12 月 24 日上午 12:33 #

    嘿,我不明白 testX 怎么像一行数据,而 testy 只有一个值。你们是怎么拟合这两个东西的?我的意思是,通常你会拟合两个值相同的数据集。我不明白 testX 怎么会是 [x, x2, x3, x4, x5, x6],而 testy 是 [y],然后你们拟合它们?我的意思是,对于每个 x,你们应该拟合一个 y,不是吗?希望您能解释一下。

    谢谢你。

  9. Joseph 2020 年 12 月 24 日上午 2:31 #

    如何使用随机森林进行多步预测?

    谢谢。

    • Joseph 2020 年 12 月 24 日上午 2:58 #

      我想那应该只是 model.predict(testX) 而不是 model.predict[testX]),对吧,这样它就可以预测 testX 的所有值而不是逐个预测?

    • Jason Brownlee 2020 年 12 月 24 日上午 5:32 #

      随机森林直接支持多输出回归,只需准备好数据,模型就会学习它。

  10. Ömer 2021 年 1 月 12 日上午 7:23 #

    Jason,我可以用什么来对时间序列数据进行随机抽样。哪种方法,哪种算法?我手头有时间序列数据,但样本非常不规则。谢谢你的回答和这个博客

  11. Ömer 2021 年 1 月 13 日上午 12:11 #

    哦,天哪,太感谢了。所以,您是说,如果我的数据真的是随机样本,——我可以通过您的博客检查这个随机游走测试——我就不能使用任何模型,比如 AR、ARIMA、随机森林、LSTM、XGBoost、CNN 等。可能所有这些都不会有用,对吗?

    是的,我尝试了上面提到的许多算法,但它们都没有很好地工作。

    • Jason Brownlee 2021 年 1 月 13 日上午 6:15 #

      不客气。

      没错。如果数据是随机的,就无法预测。你所能做的最好就是使用一个持久性模型(最坏的情况)。

      • Ömer 2021 年 1 月 13 日上午 9:21 #

        非常感谢,我非常感激

  12. Agron 2021 年 1 月 22 日上午 9:16 #

    嗨,Jason,

    感谢您发表的这篇有意义的文章。

    我正在从事一个项目,试图预测我的国家未来几个月的 Covid-19 传播情况。

    您认为这种方法适用于 Covid-19 病例等时间序列数据吗?

    谢谢,
    Agron。

  13. Juan Mantilla 2021 年 1 月 24 日上午 2:44 #

    嗨,Jason!

    我正在做关于预测时间序列观测值的本科论文。在我的论文中,我涵盖了 ARIMA、随机森林、支持向量回归器和 LSTM 模型,以评估预测能力。

    我使用了一个包含 RSSI 和 LQI 值(IEEE 802.15.4 网络中链路质量的度量)的数据集,我的结果显示 RF、SVR 和 LSTM 的 MAPE > 20%,而在使用滚动预测验证的 ARIMA 中,我得到 <10%。

    然而,我在哥伦比亚的 COVID-19 活跃病例中测试了这些相同的模型,没有对时间序列进行任何更改。SVR、RF 和 LSTM 的结果保持不变。我不知道为什么会发生这种情况。如果您能帮助我,我将不胜感激。

    • Jason Brownlee 2021 年 1 月 24 日上午 6:01 #

      抱歉,我没听懂你的问题,你能不能重新表述一下?

  14. Priya 2021 年 2 月 3 日上午 1:03 #

    嗨,Jason,

    非常感谢您的精彩解释。您能解释一下如何在这里对随机森林模型进行网格搜索吗?

  15. Ben 2021 年 2 月 10 日下午 12:12 #

    嗨,杰森,这个效果真是太棒了。我正在用这个相同的样板代码来预测水位。它有多个变量,如温度、降雨量、水文学、水量,以及目标变量地下水位深度。总之,模型在训练集和测试集上工作得很好,但是当我尝试在整个数据集上拟合模型时,我收到了一个关于维度错误的提示

    ValueError: 模型特征数必须与输入匹配。模型 n_features 为 62,输入 n_features 为 53

    总共有 9 个特征,最后一个是目标,“深度”。

    我没有做任何修改,使用了你用于在整个数据集上训练模型以获得预测的精确代码。这段特定的代码不能用于多个变量吗?

    • Jason Brownlee 2021 年 2 月 10 日下午 1:41 #

      谢谢!

      您可能需要调整代码以处理多个输入变量——特别是数据的准备工作。

      我相信这会有帮助
      https://machinelearning.org.cn/convert-time-series-supervised-learning-problem-python/

      • Harvey Benjamin Smith 2021 年 2 月 14 日上午 8:26 #

        我用这种方法设置了我的多变量数据,但我仍然遇到同样的问题。输入模型的特征数量是 79,但是它试图用于基于模型的最终预测的数量只有 60。问题出在这一行

        row = values[-6:].flatten()
        yhat = model.predict(asarray([row]))

        训练数据是所有列,每个特征的 t 和 t-1,但根据您的代码,最终预测应该只从原始数据集馈送数据维度,而不带滞后列。我希望您能在这个特定文章中使用多变量数据集提供一个示例,就像您在所有其他时间序列文章中那样

        • Jason Brownlee 2021 年 2 月 14 日下午 2:15 #

          我会在将来尝试提供一个额外的示例。

        • Liah 2022 年 4 月 5 日上午 4:09 #

          你最终找到解决这个问题的办法了吗?

  16. Diana 2021 年 2 月 24 日上午 3:40 #

    嗨,Jason!首先,非常感谢您分享您的知识,您有没有使用递归策略进行多步预测的例子?例如,如果我想预测 12 个周期而不是一个呢?

    • Jason Brownlee 2021 年 2 月 24 日上午 5:37 #

      嗯,抱歉我不记得了。也许有。我建议搜索博客(页面顶部的搜索框)。

  17. Core 2021 年 2 月 26 日晚上 11:31 #

    你好,文章写得很好。
    如何预测不在测试数据集中的下一个值?例如,预测未来 5 天

  18. Ashwani 2021 年 3 月 25 日下午 5:54 #

    嗨,Jason,

    感谢这篇内容丰富的文章!
    我有一个简单的问题,但在网上找不到明确的答案。如何使用滞后变量预测下个月(样本外)?例如,今天我需要预测下个月。由于我没有下个月的可用数据,如何解决这个问题?

    • Jason Brownlee 2021 年 3 月 26 日上午 6:22 #

      不客气!

      您必须根据您在预测时预期可用的数据来定义模型和准备数据。

      如果某些数据在预测时不可用,则在定义模型和准备数据时不要将其用作输入。

      例如,如果您想预测下个月,但您只有两个月前的数据,那么请定义您的数据和模型,始终根据两个月前的数据进行预测。

  19. bip 2021 年 3 月 26 日上午 5:27 #

    嘿,谢谢你的教程。由于我们需要保持数据顺序以进行未来预测,那么假设通过滑动窗口生成子集时,仅仅在该滑动窗口子集内发生“bagging”(有放回抽样)以及像标准 RF 那样随机选择特征子集是否正确?我想我有点困惑,因为数据顺序需要保持,但是又需要 RF 的“bagging”和随机选择列,这两者是如何结合在一起的呢?

    • Jason Brownlee 2021 年 3 月 26 日上午 6:29 #

      只要模型未在测试集中的数据上进行训练,我们就没问题。模型本身不知道未来/过去。数据准备必须正确处理这个问题。

  20. reyner 2021 年 4 月 15 日下午 4:33 #

    你好 Jason,很棒的帖子!

    在这种情况下,使用 RF 和 ARIMA 预测时间序列有什么区别?

    • Jason Brownlee 2021 年 4 月 16 日上午 5:29 #

      一个是决策树的集成,一个是线性模型。

  21. Tarun 2021 年 5 月 17 日晚上 11:26 #

    嗨,Jason,

    好文章。当我复制你的代码时,我得到了一个错误。请告诉我如何修复它。

    代码 –

    # 拟合模型

    model = RandomForestRegressor(n_estimators=1000)
    model.fit(trainX, trainY)

    # 构建新预测的输入

    row = values[-6:].flatten()

    # 进行一步预测

    yhat = model.predict(asarray([row]))
    print(‘Input: %s, Predicted: %.3f’ % (row, yhat[0]))

    错误 –

    此 RandomForestRegressor 实例尚未拟合。在使用此估计器之前,请使用适当的参数调用“fit”。

  22. Liliana 2021 年 5 月 20 日上午 10:38 #

    嗨 Jason
    是否可以参考一个多变量时间序列的例子?

    感谢您的关注。

    • Jason Brownlee 2021 年 5 月 21 日上午 5:55 #

      抱歉,我想我没有随机森林用于多变量时间序列的示例。

  23. Liliana 2021 年 5 月 20 日晚上 11:28 #

    嗨 Jason

    我想请问,为了使随机森林模型适用于多并行输入和多步输出类型的多变量时间序列预测,我需要做些什么?

    感谢您的关注。

  24. Tarun 2021 年 5 月 21 日下午 4:27 #

    嗨,Jason,

    你的博客很有帮助。我是机器学习新手,需要知道从何开始。如果你能告诉我如何从头开始浏览你的博客,我将不胜感激。

  25. Sarthak 2021 年 5 月 28 日晚上 10:50 #

    嗨,Jason,

    感谢您精彩的博客。它确实有助于理解概念。

    我读过一些文章提到 RF 模型不擅长捕捉趋势,这似乎是正确的。

    有没有什么建议来解决这个问题?我们是否不需要像机器学习中通常那样对时间序列数据进行任何预处理?

  26. Liliana 2021 年 5 月 29 日上午 5:50 #

    嗨 Jason

    我想知道,随机森林模型通常不能用于预测未来多于一步,这是正确的吗?或者,是否有可能将它们调整为多并行输入和多步输出模型?

    感谢您的关注。

    • Jason Brownlee 2021年5月29日上午6:55 #

      试试看。是的,你可以根据你的喜好调整上面的例子!

      • Liliana 2021年6月5日上午9:37 #

        好的,谢谢,我会尝试的。

  27. Evan Millikan 2021年6月5日下午7:35 #

    感谢布朗利博士的课程。我只想指出,在你对 walk_forward_regression 的第一个定义中,返回语法有拼写错误。

    它应该是 return error, test[:, 1-], predictions 而不是 return error, test[:, 1], predictions。尽管完整代码中的函数是正确的。

  28. Nick 2021年6月8日凌晨12:15 #

    你好,有没有办法让 RandomForestRegressor 优化 MASE?我查了源码,但只有 MSE 和 MAE 可用。

  29. Liliana 2021年6月10日上午5:24 #

    嗨,Jason,

    我真的认为我们会非常感谢一个多元时间序列的随机森林示例,即使它是一个非常简单的示例,因为你知道,关于多元时间序列的信息非常少。而且,例如,我已经完全整理了数据,但使用这个模型进行多元时间序列并不那么直观,而且模型执行仍然失败。

    请,如果你能给一个这样的例子,那将会有很大的帮助。

    谢谢您的关注,我正在等待您的答复。

  30. MARTIN SGATTONI 2021年6月27日凌晨12:15 #

    很棒的教程。当我尝试所有代码时,为什么会收到此错误?
    ValueError: 无法将字符串转换为浮点数:“1959-01-01”
    提前感谢。

  31. MARTIN SGATTONI 2021年6月27日凌晨12:17 #

    抱歉,我的错。CSV 的导入配置错误,抱歉!🙂

  32. Abdelrahman Shouman 2021年7月12日下午8:55 #

    你好 Jason,

    一如既往地感谢这篇精彩的文章。

    你提到使用步进验证是必须的,但我不太明白为什么。

    我理解在步进验证中,模型首先使用训练数据进行训练。然后,我们在测试数据集的第一步上评估模型,然后将其添加到训练数据中,模型在新训练数据上重新训练,依此类推。

    但为什么它对时间序列数据集特别有用呢?

    你在另一篇文章中(为了方便起见,下面附上链接)提到,使用正常的训练-测试拆分或 k 交叉验证“会导致乐观偏颇的结果”,原因是“它们假设观测之间没有关系,每个观测都是独立的。”

    但是当我们转换数据并包含先前时间步的值时,我们不是保留了这一点吗?

    例如,如果我们的特征值是 [t-2, t-1],而标签是 [t] 的值。

    所以在这种情况下,以前的观测值用于估计我们感兴趣的值。因此我假设观测之间的关系得以保留。这正确吗?或者我遗漏了什么?

    文章:https://machinelearning.org.cn/backtest-machine-learning-models-time-series-forecasting/

    • Jason Brownlee 2021年7月13日上午5:18 #

      必须确保我们不训练未来数据或评估过去数据,例如,对序列数据提供公平的模型性能估计。

      • Abdelrahman Shouman 2021年7月13日下午6:36 #

        我明白了。

        但是,即使我们将数据转换为正常的监督学习问题后,序列仍然重要吗?

        即使序列很重要,我们是否可以使用简单的非随机测试分割?(例如,在前三年训练,在第四年测试)

        • Jason Brownlee 2021年7月14日上午5:27 #

          是的。

          是的,这正是步进验证的作用。

  33. nisa 2021年7月28日下午5:54 #

    你好。我想问一下,walk_forward_validation 中的 n_test = 12 是预测最后 12 天的出生人数,对吗?

    mae, y, yhat = walk_forward_validation(data, 12)

    持久性模型预测最后 12 个月的 mae 值是 6.7 次出生,这个值是根据预测最后 12 天与模型的 mae 值 5.9 次出生进行比较计算出来的吗?

  34. Giulia 2021年7月28日下午11:30 #

    嗨,Jason,
    非常感谢这篇好文章!!
    在使用不同的数据时,我遇到了这个错误

    TypeError: float() 参数必须是字符串或数字,而不是 'Timestamp'

    我该怎么办?

    谢谢!

    • Jason Brownlee 2021年7月29日上午5:12 #

      看起来你正试图将日期/时间作为数据输入到你的模型中。你不能这样做。

  35. Bob Snack 2021年7月30日凌晨2:14 #

    嗨,Jason,

    使用随机树进行预测时,您是否总是得到一个已输入到训练集中的预测,或者您可能会收到一个以前从未见过的预测?

    谢谢,

    Bob

    • Jason Brownlee 2021年7月30日上午6:31 #

      我想这取决于模型和数据集。这可能并不重要。

  36. Tom 2021年8月4日下午11:18 #

    嗨,Jason,

    非常喜欢使用这些资源,它们帮助我深入研究机器学习,并为我的第一个数据科学职位进行了一些很好的研究。我有一个关于数据泄露的问题。我理解步进验证通过不训练未来数据来避免目标泄露,但是你建议在上述代码的哪里实现数据缩放,以避免对整个数据集进行归一化/标准化?

    我阅读了你关于数据泄露的精彩文章,并理解了如何将这个过程融入 K 折交叉验证。只是在如何将其应用于你的自定义步进方法上有些困难。

    谢谢!

    • Jason Brownlee 2021年8月5日上午5:19 #

      谢谢!

      在训练数据上拟合缩放器对象,并将其应用于训练和测试数据。如果/当您重新拟合模型对象时,您可以重新拟合缩放器对象。

      • Tom 2021年8月6日凌晨3:11 #

        感谢您的回复。

        我一直在尝试实现它,但在修改你的随机森林模型代码时有点打转。最初,我以为我可以在 WF 验证中的 train_test_split 函数之后立即将缩放器拟合到训练数据上,并在循环之前将其应用于训练/测试数据集。

        然后我意识到模型在添加新观察值到历史记录后会重新拟合,对吗?那么缩放器是否需要在每次迭代中,在这个之后,在 for 循环内重新拟合并应用于测试数据集?或者只对训练数据拟合一次然后对测试数据应用一次就可以了?

        谢谢你。

        • Jason Brownlee 2021年8月6日上午4:59 #

          您可能需要为您的案例开发一个新的例子。

  37. Liliana 2021年9月11日上午4:24 #

    嗨,Jason,

    我对时间序列的随机森林超参数有两个担忧。

    1.)如果你想增加 n_estimators 超参数中的决策树数量,如果你从 100 开始,从 1000 开始,那么这个值应该按什么比例增加?是从 100 到 100,从 1000 到 1000,还是如何?

    2.)如果你有一个回归,并且你想调整每个分裂点要考虑的随机特征的数量,使其保持 total_input_features / 3,那么 max_features 超参数是否必须调整?如果是这种情况,要以这种方式调整它,应该如何配置?

    感谢您的关注。

    • Adrian Tam
      Adrian Tam 2021年9月11日上午6:50 #

      (1) 这里没有规则,但你需要证明你为什么这样做。最好的答案是你的实验证明的那个。
      (2) 是的。

      • Liliana 2021年9月11日上午7:46 #

        但是如果我希望超参数 max_features = total_input_features / 3,我应该如何配置它呢?是像“auto”、“sqrt”、“log2”这样吗?

        • Adrian Tam
          Adrian Tam 2021年9月14日下午1:02 #

          你说的是设置模型的参数吗?我建议先保留默认值,然后尝试一下。

          • Liliana 2021年9月15日上午8:00 #

            是的,我说的正是配置模型的参数,如果我希望 max_features = total_input_features / 3,我应该如何配置它?

            感谢您的关注。

          • Adrian Tam
            Adrian Tam 2021年9月15日下午11:58 #

            你可以这样设置:`sklearn.ensemble.RandomForestRegressor(max_features=0.33)` 或者 `sklearn.ensemble.RandomForestRegressor(max_features=int(total_input_features/3.0))`

          • Liliana 2021年9月16日上午8:08 #

            哦,好的,我会这样做的,但是正如你所说,我首先会尝试默认值。

            感谢你的帮助,Adrian,它对我总是很有用。

  38. Liliana 2021年9月11日上午7:50 #

    嗨,Jason,

    又有一个问题,在实际工作中,使用随机森林对多元多并行时间序列进行多步回归时,有没有什么情况是我应该或方便对数据进行某种转换的?

    感谢您的关注。

    • Adrian Tam
      Adrian Tam 2021年9月14日下午1:04 #

      随机森林(即决策树)通常不需要缩放。但如果你正在考虑特征提取(例如 PCA),那可能就是你需要做的转换。然而,这取决于问题。例如,它通常对宏观经济回归很有用。

      • Liliana 2021年9月15日上午8:02 #

        好的,谢谢你的回答。

  39. Waleska 2021年10月7日上午6:13 #

    嗨,Jason,首先感谢你的博客,我非常喜欢它,而且解释得非常清楚。
    我正在尝试将其用于一个使用 3 个不同标签的多元时间序列数据集。然而,对于每个主题,标签会在某个时候从 1 更改为 3 或从 1 更改为 2。我正在尝试找出哪些特征导致了我的数据集中标签的这种变化。机器学习领域是否实现了类似的功能?
    此外,这段代码使用 n_test 值来确定测试数据,并且它总是取数据集的最后 n_test 个值。有没有办法改变这一点,而是使用介于两者之间(当标签发生变化时)作为测试?这有意义吗?

    • Adrian Tam
      Adrian Tam 2021年10月12日凌晨12:14 #

      标签取决于一些随机因素。这是你使用的标签编码器的性质。如果你不喜欢它,你最好手动操作:创建一个带有标签映射的 python 字典,然后在使用机器学习模型之前用它替换一列。

  40. Kaelan 2021年11月18日上午4:27 #

    嗨 Jason 和 Adrian,

    我很好奇是否可以计算滞后变量的聚合统计量?目前我的数据维度相当高,我想通过引入滞后来限制我引入的新特征的数量。我也尝试预测啮齿动物的行为,我觉得这需要我有一个相当大的窗口(即 2 秒),而我的数据由 200 毫秒的时间步长组成。我的想法是,与其为该窗口内的每个时间步引入特征,不如我可以采取一些聚合统计量,例如标准差或均值。这在机器学习领域常见吗?你认为我采用这种方法会丢失多少信息?

    非常感谢您的帮助!

    • Adrian Tam
      Adrian Tam 2021年11月18日上午5:57 #

      我不太明白你所说的滞后变量的聚合统计量是什么意思。但在某些模型中,添加新的派生特征以帮助预测是有意义的。例如,除了时间序列本身,将时间序列的移动平均值一起添加使其成为多维是一种常见的技巧,可以帮助提高准确性。

  41. dhuha 2021年12月19日上午5:44 #

    你好,时间序列预测中树如何分裂节点?我们有一个特征需要处理和预测,此外还有日期特征。

    • Adrian Tam
      Adrian Tam 2021年12月19日下午2:14 #

      我认为这个例子中没有考虑日期。

  42. Anthony Sligar 2022年1月27日下午6:43 #

    谢谢你。我很好奇,在大多数非时间序列类型的分类或回归问题中,您都希望打乱数据。然而,我在这里搜索了一下,没有看到任何关于打乱数据的内容。我的想法是,您永远不应该打乱时间序列数据,但我没有找到任何关于为什么应该或不应该打乱时间序列数据的原因。只是好奇您的想法?

    • James Carmichael 2022年1月28日上午10:41 #

      嗨,Anthony……你不应该打乱时间序列数据,因为深度学习模型正在学习数据中固有的相关性并提取基于数据顺序的特征。这就是为什么你不应该随机分割数据。

  43. Anthony Sligar 2022年1月27日下午6:52 #

    抱歉,我之前的帖子应该澄清一下,即使您使用“series_to_supervised”函数准备了数据,它会创建一系列过去的 数据和未来一步的数据。在这个步骤之后,在将其分割成训练数据和测试数据之前,有没有任何充分的理由打乱数据?

    • James Carmichael 2022年1月28日上午10:43 #

      嗨,Anthony……你不应该打乱时间序列数据。

  44. Jing 2022年1月28日凌晨1:23 #

    嗨 Jason 和 Adrian

    感谢这篇精彩的帖子。你们有没有关于多元分析的类似帖子或研究,其中包括几个因素?

    非常感谢您的回复!
    此致!

  45. Chandrakant 2022年1月28日下午11:48 #

    你好 Jason,
    很高兴与您分享,我能够在我的数据上运行代码。
    但我发现我的 MAE 始终在 41 左右。我已将 n_estimators 从 1000 更改为 5000。但 MAE 仍保持在 41 左右,没有变化。我现在应该进行哪些更改?

  46. Farjam 2022年3月9日上午6:43 #

    我如何实现带有自定义步长或步进的 def series to supervised,我希望在滑动窗口中移动多于一步。
    谢谢

    • James Carmichael 2022年3月10日上午10:41 #

      嗨 Farjam……请参阅之前关于设置所需值的回复。

  47. Farjam 2022年3月10日上午6:16 #

    你好,Jason
    你能帮我一下,我如何自定义步长,我的意思是,在 def series_to_supervised 中,如何让步长大于一步?

    • James Carmichael 2022年3月10日上午10:24 #

      嗨 Farjam……以下代码定义设置为步长为 1,但是您可以通过将“n_in”和“n_out”更改为对您的目标有意义的其他值,将其更改为您需要的任何步长。

      def series_to_supervised(data, n_in=1, n_out=1, dropnan=True)

  48. Enzo 2022年4月27日凌晨2:16 #

    嗨,Jason,

    首先,感谢您的出色工作和教训。

    我有一个问题:如果我们最终需要多个样本外值,该怎么办。
    我的意思是,如果我们要从我们的实际历史数据最后一个样本开始预测未来许多天、周、年等,该怎么办?

    我们应该将我们的第一个样本外预测纳入其中,然后从头开始重新整个过程,还是有更好的方法!

    示例:假设我们有一个正在进行的体育赛季。想象一下,我们有该赛季 50 轮中的 11 轮结果,我们想预测剩下的直到赛季结束。

  49. Enzo 2022年4月27日凌晨2:20 #

    *[...]数据的最后一个样本
    **[...]整个过程[...]或者有更好的方法?
    ****[...]“任何体育赛季”[...]其余直到结束

    • James Carmichael 2022年4月30日上午10:21 #

      嗨,Enzo……请澄清你的问题,以便我们更好地帮助你。

  50. tiago 2022年5月4日上午7:55 #

    嗨,Jason!

    感谢又一堂精彩的课!

    我有一个疑问

    我如何调整上述代码以进行多步预测?

  51. Yogesh 2022年8月23日下午7:38 #

    在步进验证的情况下,如何调整随机森林的超参数?我们可以使用网格搜索来优化超参数,一旦获得最佳参数,我们再次使用步进验证吗?

  52. Bim 2022年9月7日下午6:57 #

    嗨 Jason,我发现你的帖子和解释非常有帮助!

    但是由于我是 Python 编码和机器学习的新手,你会如何编写代码来进行多步预测,比如在数据集结束后的 30 步?你会更改代码中的哪些部分?

    非常感谢您的回复!

  53. mona 2023年1月6日凌晨12:53 #

    嗨 Jason,我发现你的帖子非常有帮助!

    使用随机森林或分位数回归随机森林来预测波动性是否正确?

  54. jeff T. 2023年4月11日上午8:16 #

    你好 Jason,
    感谢你们所有的辛勤工作。请问您能评论一下以下内容吗?我注意到在您的时间序列 RF 示例中,random_forest_forecast 方法在每次预测请求(步骤)时被调用一次。但是,它在进行预测之前也会重新构建随机森林模型本身。随着预测窗口循环变长,模型构建越来越多地基于它已经预测过的数据。为什么有必要不断重建 RF 模型?

    • James Carmichael 2023年4月11日上午10:14 #

      嗨 Jeff……模型正在用新数据更新。所以这实际上只是对同一个模型的更新。

  55. dvd 2023年8月22日下午7:47 #

    你好,James,

    我们如何添加一个外生变量?

    例如,我们有一个包含 Demand 和 IsWeekend 变量的数据框。我们使用 series_to_supervised 函数和 10 个滞后,我们将得到一个包含 Demand、IsWeekend 和 t-n 变量(从 t-1 到 t-10)的数据框。我们是否以相同的方式应用 walkfoward 函数?如果不是,有没有这方面的示例或参考?

    提前感谢

  56. Brendan Casboult 2023年12月8日下午10:25 #

    一个疑问

    单考虑您的代码
    trainX, trainy = train[:, :-1], train[:, -1]

    这在我看来不太对,因为 trainy 包含在 trainX 中

    如果 y = f(X),那么 y 不应该包含在 trainX 集中吗??

    尽管如此,我仍然得到了一个非常好的预测误差。

  57. yassine hattay 2024年3月3日下午4:22 #

    你好,根据这个官方链接,使用 scikit-learn 的随机森林无法进行增量学习

    https://scikit-learn.cn/0.15/modules/scaling_strategies.html#incremental-learning

    所以如果您理解正确的话,您每次都在重新构建森林,所以这不是步进的真实应用,还是我弄错了?

    def random_forest_forecast(train, testX)
    # 将列表转换为数组
    train = asarray(train)
    # 分割成输入和输出列
    trainX, trainy = train[:, :-1], train[:, -1]
    # 拟合模型
    model = RandomForestRegressor(n_estimators=1000)
    model.fit(trainX, trainy)
    # 进行一步预测
    yhat = model.predict([testX])
    return yhat[0]

    # 单变量数据的滚动预测验证
    def walk_forward_validation(data, n_test)
    predictions = list()
    # 分割数据集
    train, test = train_test_split(data, n_test)
    # 使用训练数据集初始化历史数据
    history = [x for x in train]
    # 遍历测试集中的每个时间步
    for i in range(len(test))
    # 将测试行拆分为输入和输出列
    testX, testy = test[i, :-1], test[i, -1]
    # 在历史数据上拟合模型并进行预测
    yhat = random_forest_forecast(history, testX)
    # 将预测结果存储到预测列表中
    predictions.append(yhat)
    # 将实际观测值添加到历史数据中以供下一次循环使用
    history.append(test[i])
    # 总结进展
    print('&#gt;预期=%.1f,预测=%.1f' % (testy, yhat))
    # 估计预测误差
    error = mean_absolute_error(test[:, -1], predictions)
    return error, test[:, -1], predictions

    • James Carmichael 2024年3月4日凌晨1:41 #

      嗨 Yassine……您执行过您的模型吗?如果没有,请执行并告诉我们您的发现。这将更好地帮助我们指导您下一步。

      • yassine hattay 2024年3月4日凌晨3:44 #

        你好,谢谢你花时间,但是你没有回答我的问题,这是一个简单的问题,也许我应该重新表述一下,在你上面这份我相信是你的代码中,你每次用测试集扩展数据时,都会用新模型覆盖旧模型,这并不是步进的真正应用,我的证据是来自官方 sklearn 网站的这个链接,它讨论了增量学习,而随机森林不是其中之一。

        • James Carmichael 2024年3月5日上午10:34 #

          嗨 Yassine……请按照您从 sklearn 文档中理解的建议进行操作。然后告诉我们您的发现。

          • yassine hattay 2024年3月5日下午1:47 #

            嗨,现在我明白了你的代码展示了步进的原理,而不是如何实际实现它,部分困惑来自于我不知道 sklearn 中的随机森林不能增量训练,我以为你正在使用步进技术来增量训练模型。

  58. GT 2024年5月8日凌晨2:43 #

    嗨,Jason,

    您的博客信息量很大。我有几个疑问。

    根据 Goehry, 2020 的研究,对于相关数据随机森林的理论,使用块自举法代替用于独立同分布数据的标准自举法。在 R 或 Python 中实现用于时间序列数据的 randomForest 时,使用的是哪种自举法?
    另一个问题是,’rangerts’ 包与 ‘randomForests’ 包相比如何?

    先谢谢您了。

    • James Carmichael 2024年5月8日上午8:51 #

      嗨 GT……在 R 或 Python 中实现时间序列数据的随机森林时,通常使用一种称为“时间序列交叉验证”的方法,而不是传统的自举方法。时间序列交叉验证通过按顺序将数据分成训练集和测试集来考虑数据中的时间依赖性,确保模型在未见过的未来数据上进行评估。

      在 R 中,您可以使用 `caret` 包和 `timeslice` 方法进行时间序列交叉验证。此方法将数据分成多个连续的训练/测试集。

      对于 Python,`scikit-learn` 等库通过 `TimeSeriesSplit` 类提供时间序列交叉验证功能。

      关于您的第二个问题,`randomForest` 包和 `ranger` 包(不是 `rangerts`)都是 R 中随机森林的流行实现。以下是比较

      1. **randomForest 包:**
      – `randomForest` 包由 Leo Breiman 和 Adele Cutler 开发,是 R 中最早、使用最广泛的随机森林实现之一。
      – 它提供了一个简单的界面来构建随机森林模型,并包含用于调整参数(例如树的数量和每次分裂时考虑的特征数量)的选项。

      2. **ranger 包:**
      – `ranger` 包是 R 中随机森林的一个较新的实现。
      – 它旨在比 `randomForest` 包更快、更节省内存,尤其适用于大型数据集。
      – `ranger` 还包括其他功能,例如变量重要性度量和处理具有超过 53 个级别的分类变量的能力。

      总的来说,这两个包都有效地用于在 R 中构建随机森林模型,但您可能更喜欢 `ranger`,因为它具有改进的性能和附加功能,尤其是在处理大型数据集时。然而,两者的选择最终取决于您的具体要求和偏好。

      • GT 2024年5月9日上午4:52 #

        非常感谢您的详细回复。不胜感激。

发表回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。