如何使用 Python 对 ARIMA 模型超参数进行网格搜索

用于时间序列分析和预测的 ARIMA 模型配置起来可能很棘手。

需要通过迭代试错,结合诊断图和使用 40 年前的启发式规则来估计 3 个参数。

我们可以使用网格搜索过程,自动评估 ARIMA 模型的大量超参数。

在本教程中,您将学习如何使用 Python 中的超参数网格搜索来调整 ARIMA 模型。

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

  • 您可以用来调整 ARIMA 超参数以进行滚动一步预测的通用过程。
  • 如何对标准单变量时间序列数据集应用 ARIMA 超参数优化。
  • 扩展该过程以用于更精细和鲁棒模型的想法。

通过我的新书《使用 Python 进行时间序列预测》**启动您的项目**,其中包括**分步教程**和所有示例的 **Python 源代码**文件。

让我们开始吧。

  • 2019 年 4 月更新:更新了数据集链接。
  • 2019年8月更新:更新了数据加载以使用新的API。
  • **2020 年 12 月更新**:针对 API 更改更新了建模。
How to Grid Search ARIMA Model Hyperparameters with Python

如何使用 Python 对 ARIMA 模型超参数进行网格搜索
图片来源:Alpha,保留部分权利。

网格搜索方法

时间序列的诊断图可以与启发式规则一起使用,以确定 ARIMA 模型的超参数。

这些在大多数情况下都很好,但可能并非所有情况都如此。

我们可以自动训练和评估 ARIMA 模型在不同模型超参数组合上的性能。在机器学习中,这称为网格搜索或模型调优。

在本教程中,我们将开发一种方法来对 ARIMA 超参数进行网格搜索以进行一步滚动预测。

该方法分为两部分

  1. 评估 ARIMA 模型。
  2. 评估 ARIMA 参数集。

本教程中的代码使用了 scikit-learn、Pandas 和 statsmodels Python 库。

停止以**慢速**学习时间序列预测!

参加我的免费7天电子邮件课程,了解如何入门(附带示例代码)。

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

1. 评估 ARIMA 模型

我们可以通过在训练数据集上准备 ARIMA 模型并在测试数据集上评估预测来评估它。

这种方法涉及以下步骤

  1. 将数据集分成训练集和测试集。
  2. 遍历测试数据集中的时间步长。
    1. 训练一个 ARIMA 模型。
    2. 进行一步预测。
    3. 存储预测;获取并存储实际观察值。
  3. 计算预测与预期值相比的误差分数。

我们可以在 Python 中将其实现为一个名为 `evaluate_arima_model()` 的新独立函数,该函数将时间序列数据集作为输入,以及一个包含要评估模型的 p、d 和 q 参数的元组。

数据集分为两部分:66% 用于初始训练数据集,其余 34% 用于测试数据集。

测试集的每个时间步长都进行迭代。只需一次迭代就可以提供一个模型,您可以使用它对新数据进行预测。迭代方法允许在每个时间步长训练新的 ARIMA 模型。

每次迭代都会进行预测并存储在列表中。这样,在测试集结束时,所有预测都可以与预期值列表进行比较,并计算误差分数。在这种情况下,计算并返回均方误差分数。

完整的函数如下所示。

现在我们知道如何评估一组 ARIMA 超参数,接下来我们看看如何重复调用此函数以评估参数网格。

2. 迭代 ARIMA 参数

评估一系列参数相对简单。

用户必须指定要迭代的 p、d 和 q ARIMA 参数网格。为每个参数创建一个模型,并通过调用上一节中描述的 `evaluate_arima_model()` 函数来评估其性能。

该函数必须跟踪观察到的最低误差分数以及导致该分数的配置。这可以在函数结束时通过标准输出打印进行总结。

我们可以将此函数(称为 `evaluate_models()`)实现为一系列四个循环。

还有两个额外的考虑。首先是确保输入数据是浮点值(而不是整数或字符串),因为这可能导致 ARIMA 过程失败。

其次,statsmodels ARIMA 过程内部使用数值优化过程来查找模型的系数集。这些过程可能会失败,进而可能抛出异常。我们必须捕获这些异常并跳过那些导致问题的配置。这种情况比您想象的要频繁。

此外,建议忽略此代码的警告,以避免运行该过程产生大量噪音。这可以通过以下方式完成

最后,即使有所有这些保护,底层的 C 和 Fortran 库仍然可能向标准输出报告警告,例如

为了简洁起见,本教程报告的结果中已将其删除。

评估 ARIMA 超参数网格的完整过程如下所示。

现在我们有了对 ARIMA 超参数进行网格搜索的过程,接下来让我们在两个单变量时间序列问题上测试这个过程。

我们将从洗发水销售数据集开始。

洗发水销售案例研究

洗发水销售数据集描述了三年期间每月洗发水的销售数量。

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

下载数据集并将其放在您当前的工作目录中,文件名为“_shampoo-sales.csv_”。

时间序列中的时间戳不包含绝对年份分量。我们可以在加载数据时使用自定义日期解析函数,并将年份基线设置为 1900,如下所示

加载后,我们可以指定一组要搜索的 p、d 和 q 值,并将它们传递给 `evaluate_models()` 函数。

我们将尝试一组滞后值(p),以及少量差分迭代(d)和残差滞后值(q)。

将所有这些与上一节中定义的通用过程结合起来,我们可以在洗发水销售数据集上对 ARIMA 超参数进行网格搜索。

完整的代码示例如下所示。

运行该示例会打印每个成功评估完成的 ARIMA 参数和 MSE。

最佳参数 ARIMA(4, 2, 1) 在运行结束时报告,均方误差为 4,694.873。

每日女性出生人数案例研究

每日女性出生人数数据集描述了 1959 年加利福尼亚州每日女性出生人数。

单位是计数,共有 365 个观测值。数据集的来源归功于 Newton (1988)。

下载数据集并将其放在您当前的工作目录中,文件名为“_daily-total-female-births.csv_”。

此数据集可以轻松地直接加载为 Pandas Series。

为了简单起见,我们将探索与上一节相同的 ARIMA 超参数网格。

将所有这些放在一起,我们可以在每日女性出生人数数据集上对 ARIMA 参数进行网格搜索。完整的代码列表如下所示。

运行该示例会打印每个成功评估的配置的 ARIMA 参数和均方误差。

最佳均值参数报告为 ARIMA(6, 1, 0),均方误差为 53.187。

扩展

本教程中使用的网格搜索方法很简单,可以轻松扩展。

本节列出了一些您可以探索的扩展方法的想法。

  • **种子网格**。经典的 ACF 和 PACF 图诊断工具仍然可以使用,其结果用于为要搜索的 ARIMA 参数网格提供种子。
  • **替代度量**。搜索旨在优化样本外均方误差。这可以更改为另一个样本外统计量、样本内统计量(如 AIC 或 BIC),或两者的某种组合。您可以选择对您的项目最有意义的度量。
  • **残差诊断**。可以自动计算残差预测误差上的统计量,以提供拟合质量的额外指示。示例包括对残差分布是否为高斯分布以及残差中是否存在自相关的统计检验。
  • **更新模型**。ARIMA 模型是为每个一步预测从头开始创建的。通过仔细检查 API,可以更新模型的内部数据与新的观测值,而不是从头开始重新创建模型。
  • **前置条件**。ARIMA 模型可能对时间序列数据集做出假设,例如正态性和平稳性。可以在训练给定模型之前检查这些条件并针对给定数据集发出警告。

总结

在本教程中,您学习了如何在 Python 中对 ARIMA 模型的超参数进行网格搜索。

具体来说,你学到了:

  • 一个可用于对 ARIMA 超参数进行一步滚动预测网格搜索的过程。
  • 如何在标准单变量时间序列数据集上应用 ARIMA 超参数调整。
  • 关于如何进一步改进 ARIMA 超参数网格搜索的想法。

现在轮到你了。

在您最喜欢的时间序列数据集上尝试此过程。您得到了什么结果?
在下面的评论中报告您的结果。

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

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

Introduction to Time Series Forecasting With Python

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

...只需几行python代码

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

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

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

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

查看内容

对《如何使用 Python 对 ARIMA 模型超参数进行网格搜索》的 161 条回复

  1. Gerrit Govaerts 2017 年 1 月 18 日晚上 9:01 #

    如果您愿意考虑 R 解决方案,我可以向您推荐 R 包“forecast”中的 auto.arima 函数:https://cran.r-project.cn/web/packages/forecast/forecast.pdf
    这将完成您所需的所有网格搜索,而无需编写一行代码。
    现在,一般来说,使用网格搜索来解决机器学习模型中的超参数优化问题是一种低效的选择。事实证明,随机搜索更快,贝叶斯搜索甚至更快。请看这个:https://www.youtube.com/watch?v=cWQDeB9WqvU(Geoff Hinton 的讲座)。对于 Python,有一个名为 hyperopt 的包提供了此功能:https://github.com/hyperopt/hyperopt
    hyperopt 简介在此:https://www.youtube.com/watch?v=Mp1xnPfE4PY

    • Jason Brownlee 2017 年 1 月 19 日上午 7:34 #

      感谢您提供的链接,Gerrit。

      一个值得注意的区别是样本外统计量的优化,即测试性能。

      关于网格搜索与随机搜索,ARIMA 网格足够小,可以枚举。当使用计算时间较短的小型网格时,随机搜索效率会低得多。

  2. Abdallah 2017 年 1 月 31 日下午 1:49 #

    你好,我使用了评估模型函数来选择最佳配置,但它跳过了我根据 Box-Jenkins 方法预期是最佳的那些配置。这是什么意思?有什么办法可以检查这些配置吗?

    • Jason Brownlee 2017 年 2 月 1 日上午 10:44 #

      好问题 Abdallah,我也为此感到沮丧。

      我相信您可以进一步修改 ARIMA 配置,例如配置它使用或不使用趋势常数。

      这个问题是由底层使用的 linalg 和优化库的不稳定性引起的。

      您可以尝试其他实现(R?),尝试手动从头开始实现该方法,或者尝试在使用相同 ARIMA 操作转换后的数据集版本上拟合线性回归模型。

      这有帮助吗?

  3. Andres Kull 2017 年 2 月 8 日晚上 11:47 #

    您在这里进行一步滚动预测来调整 ARIMA 参数。结果模型是否最适合仅预测下一个观测值?假设我想在接下来的 30 个观测值期间获得最佳预测。在这种情况下,是否应该将参数调整更改为 30 步滚动预测?

    • Jason Brownlee 2017 年 2 月 9 日上午 7:25 #

      是的,安德烈斯,说得很对。为实现您所需的结果进行优化至关重要。

  4. Stuart Farmer 2017 年 5 月 24 日上午 1:04 #

    太棒了,老兄。爱它。继续努力!

  5. Arkojyoti 2017 年 6 月 6 日上午 4:30 #

    嗨,Jason,

    感谢您的帖子。然而,在尝试解析洗发水销售示例中的日期列时,我遇到了问题。我从以下链接(csv 格式)下载了数据,并且正在使用 Python 3

    https://datamarket.com/data/set/22r0/sales-of-shampoo-over-a-three-year-period#!ds=22r0&display=line

    我在解析过程中遇到了 2 个问题
    1) 月份列的格式是“1-Jan”,表示我们需要指定“%Y-%b”而不是“%Y-%m”
    2) 对于大于 9 的值,即 10-Jan、11-Jan 等,解析后的日期将无效。因为它将采用:“19010-Jan”和类似格式。

    请找到为我工作的修改后的函数

    def parser(x)
    # 以下代码块将处理两种情况下的解析
    #1. 对于日期 < 10
    测试 = int(x.split(‘-‘)[0])
    #print(test)
    if(test < 10)
    return(datetime.strptime("190"+str(x),"%Y-%b"))
    else
    return(datetime.strptime("19"+str(x),"%Y-%b"))
    series = read_csv('sales-of-shampoo-over-a-three-ye.csv', header=0, parse_dates=[0], index_col=0,
    squeeze=True, date_parser=parser)

    如果方法有误,请纠正我。希望这有帮助。再次感谢这篇文章。祝您有美好的一天 🙂

    • Jason Brownlee 2017 年 6 月 6 日上午 10:08 #

      我已测试并确认该示例在 Python3 中有效。

      也许确认您拥有相同的数据集,已从文件中删除了页脚,并且已准确地从帖子中复制了代码?

  6. Hans 2017 年 6 月 20 日上午 3:00 #

    在我的电脑上,第一个示例脚本出现以下错误

    ** 进入 DLASCL 时,参数 4 的值非法

    所以我没有得到最好的设置。

    第二个脚本出现“Best ArimaNone MSE=inf”错误

    我已经删除了页脚行。有什么提示吗?

  7. TaeWoo Kim 2017 年 6 月 23 日上午 3:10 #

    嘿,Jason

    这种网格搜索方法与使用 SARIMAX 有什么区别(或好处)?(参考:https://www.digitalocean.com/community/tutorials/a-guide-to-time-series-forecasting-with-arima-in-python-3

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

      我没有读过那篇文章,但粗略地看了一下,它表明他们使用了与我的教程中相同的 for 循环。

  8. Priya Srinivasan 2017 年 7 月 4 日上午 2:28 #

    “测试集的每个时间步长都进行迭代。只需一次迭代就可以提供一个模型,您可以使用它对新数据进行预测。迭代方法允许在每个时间步长训练新的 ARIMA 模型。”

    首先,感谢您的本教程!我对使用您上面的迭代方法有点困惑。我的问题是

    1. 为什么您将测试示例添加到训练集(在历史记录中)并重新训练 ARIMA 模型?这样,每个后续测试预测都将在原始训练集加上先前测试示例中添加的一个元素上进行训练。这是为了通过向模型添加更多训练数据(现在包括原始训练 + 测试示例)来改进测试预测吗?

    2. 使用预测函数,我可以直接在训练集上训练 ARIMA,然后将内置的预测函数用于预留的测试示例集吗?使用这种方法有什么缺点?

    再次感谢!

  9. Sam 2017 年 7 月 14 日上午 6:44 #

    这个错误“Best ARIMANone RMSE=inf”是什么意思?

    • Jason Brownlee 2017 年 7 月 14 日上午 8:37 #

      Sam,没有找到好的结果。您是按原样运行代码还是根据您的问题进行了调整?也许调试一下示例?

      • Kailash 2018 年 4 月 23 日晚上 10:06 #

        首先让我感谢您的这个精彩博客。关于我的问题,我用我自己的数据集运行了这段代码。我得到了相同的错误。之后我也尝试了相同的数据集。仍然得到相同的错误。请帮助我,先生。

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

          谢谢。

          您在使用教程中的确切代码时遇到了什么错误?

        • jay 2018 年 11 月 26 日上午 9:38 #

          您能解决这个问题吗?

          • Nurdaulet 2023 年 5 月 9 日晚上 10:05 #

            您好,我也遇到了这个问题。您能解决这个问题吗?如何解决?

  10. Marianico 2017 年 7 月 20 日下午 4:32 #

    输入数据量会影响预测吗?我的意思是,也许最旧的滞后数据与当前数据不太相关。如果是这样,将历史记录的长度限制为 500 行,例如,会不会更好?我如何找到最佳的训练数据量?

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

      这会影响预测。我建议测试所用预测数据的数量。这是一个例子
      https://machinelearning.org.cn/sensitivity-analysis-history-size-forecast-skill-arima-python/

      • Marianico 2017 年 7 月 21 日晚上 9:20 #

        谢谢 Jason,非常有用!但现在我有了另一个困境:我应该在找到最佳数据量之前还是之后执行网格搜索?

        • Jason Brownlee 2017 年 7 月 22 日上午 8:35 #

          这是一个很好的问题。这也是一个开放性问题。

          纯粹主义者可能会将训练数据量视为另一个需要进行网格搜索的变量。

      • Tayyab 2019 年 6 月 1 日上午 4:34 #

        如果第一年的数据不是从一月一日开始,而去年(例如 2019 年)仍在继续,该如何相应地制定模型?

    • pique 2024 年 3 月 20 日上午 12:51 #

      检查代码行(如果是自己编写,而不是复制/粘贴)。即使是最小的差异也会导致**引用结果**。删除警告模块也无济于事。我也遇到了同样的问题,只有通过文件比较(比较此处示例中的代码和手动编写的代码)才找到错误。

  11. Andrew 2017 年 9 月 9 日上午 3:26 #

    这个模型加载时间太长了——我能做些什么来优化性能吗?

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

      删除一些数据?

      • Simran 2021 年 5 月 14 日晚上 10:47 #

        我也有同样的疑问。

        • Jason Brownlee 2021 年 5 月 15 日上午 6:33 #

          尝试在更快的电脑上运行?
          尝试用更少的数据运行?
          尝试用更少的配置运行?

  12. Udi 2017 年 11 月 2 日上午 8:10 #

    您好。
    我正在尝试将 ARIMA 模型拟合到金融数据集,但结果非常差。预测趋势与真实趋势差异很大,相对 MSE 比要求高一个数量级。我很难识别我的问题来源。
    我有几个问题。如果我的问题对于本次讨论来说过于广泛,请告诉我。

    1. 您如何选择网格搜索的范围?ACF 和 PACF 图暗示 p、q 的阶数为 0,0,但相关模型仍然给出较差的结果(我使用 aic 作为我的误差分数,我运行中最流行的模型是 ARIMA(0,0,0)...)

    2. 另一个可疑之处是我的拟合预测过程。我将模型拟合了一个 X 小时的时间段,并预测了接下来的 y 分钟(无限重复)。令人惊讶的是,使用较小的 x 值只会得到更差的结果,而不是更好的结果,尽管数据高度波动。

    3. 您能否证明 ARIMA 模型对于某些数据集(例如已经平稳(已差分)的数据集,Dickey-Fuller 检验结果良好)来说是预测的糟糕选择?

  13. Udi 2017 年 11 月 2 日上午 8:13 #

    啊,最后一个(暂时是)

    4. 数据平滑过程能否提高 ARIMA 模型的性能?在我看来,如果数据本身是波动的,任何平滑都必然会搞砸预测,但这只是直觉,而不是数学证明

    • Jason Brownlee 2017 年 11 月 2 日下午 3:56 #

      它可能会有帮助,尝试一下看看——成本很低。

  14. Qian 2017 年 12 月 6 日上午 9:12 #

    嗨,Jason,

    根据下面“计算样本外误差”的代码,最佳拟合模型是通过测试集的最低误差来选择的吗?如果我想使用训练集的 MSE 和 R 平方来找到最佳拟合模型,我该怎么做?

    (# 计算样本外误差
    error = mean_squared_error(test, predictions)
    return error)

    先谢谢您了。

  15. Pratik 2018 年 1 月 4 日上午 10:22 #

    嗨,Jason,

    我正在进行超参数搜索。如何处理类似情况

    ValueError:计算出的初始 AR 系数不平稳
    您应该引入平稳性,选择不同的模型顺序,或者您可以
    传递您自己的 start_params。

    我有多个数据集(大约 500 个),我无法单独分析它们。有什么建议吗?

    提前感谢你

  16. Siddharth Das 2018 年 1 月 5 日晚上 8:14 #

    选择 pdq 范围的最佳选项是什么,然后将其传递给函数以根据 MSE 预测最佳 pdq 结果?如何确定需要传递的 pdq 范围?

    因为如果我们盲目地传递 range(0,9),整个模型将花费大量时间来找出最佳结果。

  17. Charles 2018 年 2 月 20 日下午 4:49 #

    非常感谢 Jason 的又一篇精彩文章。

    本文(
    https://www.linkedin.com/pulse/comparison-between-classical-statistical-model-arima-deep-virmani)比较了 ARIMA 与 RNN 和 LSTM 在时间序列预测上的表现。LSTM 的结果远优于 ARIMA(RMSE:1.02 对 4.74)。鉴于 ARIMA 的 p、q、d 选择不易,看来在预测中使用 ARIMA 是明智的。

    查尔斯

  18. Charles 2018 年 2 月 22 日下午 12:49 #

    谢谢 Jason,如果我错了请纠正我。

    1). 大多数时间序列问题是非线性问题。我们必须将它们简化为线性问题才能应用 ARIMA,因为 ARIMA 是线性模型。这就是为什么 ARIMA 的预测在时间序列问题上总是很差的原因。

    2). RNN 和 LSTM 能够处理非线性问题。当然,其结果优于 ARIMA。

    3). 因此,人们应该避免任何用于时间序列问题预测的线性模型。

    我从您的文章中学到了很多。非常感谢您!

    lcy1031

    • Jason Brownlee 2018 年 2 月 23 日上午 11:52 #

      大部分是。ARIMA 确实是捕捉线性关系的线性模型。

      您对数据进行的预处理越多,使数据中的关系越简单/越好地暴露,建模就越容易,无论使用何种方法。

  19. Charles 2018 年 2 月 24 日上午 4:37 #

    谢谢 Jason 的回复。

    我担心任何预处理都可能过度简化问题,并使预测不可靠。到目前为止,还没有一种方法可以衡量预处理是否有效,以及是否会删除重要信息。

    顺便说一句,趋势和季节性是曲线的非常好的特征,可以极大地帮助预测。使用平稳过程将它们移除是错误的。

    再次感谢您!

    查尔斯

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

      最好的衡量标准是经过处理和未经处理的数据的模型技能。

  20. Ajay 2018 年 3 月 7 日晚上 8:16 #

    我运行此行时出现以下错误
    model = ARIMA(history, order=(4,1,0))
    错误
    TypeError: 描述符'__sub__'需要一个'datetime.datetime'对象,但接收到一个'int'

    • Jason Brownlee 2018 年 3 月 8 日上午 6:22 #

      很抱歉听到这个。您是否完全按照教程中的代码和数据进行复制?

  21. Germán 2018 年 3 月 20 日上午 2:37 #

    嗨,Jason,

    我正在深入研究“历史”列表更新(基于“前向验证”),我发现如果以您的代码编写方式打印“预测值与预测值”对,它实际上显示的是“添加到历史记录的最后一个元素的预测”与“当前添加到历史记录但尚未预测的元素 test[t]”。

    我建议进行此更改,您觉得怎么样?

    • Germán 2018年3月20日 凌晨2:39 #

      * 我的意思是“预测值 VS 实际值”对 🙂

    • Jason Brownlee 2018年3月20日 早上6:29 #

      在步进验证中,我们希望将真实的观测值添加到历史数据(用于拟合模型),而不是预测值。

      否则,我们将使用递归多步预测模型(例如,与我们的目标不同),并且效果会差很多。

      • Germán 2018年3月21日 凌晨3:21 #

        你好 Jason,谢谢你的回复,但我认为你误解了我的意思,我实际上并没有改变你添加到“history”列表中的内容。

        我所做的更改(通过一个时间序列示例运行我的代码并验证运行良好)是为了显示正确的“预测值 VS 实际值”对(你能检查一下我上次输入的代码吗?)

  22. Germán 2018年3月20日 凌晨2:43 #

    抱歉有错别字,以下是建议的代码

  23. Ajay Verma 2018年3月23日 凌晨2:08 #

    你好 Jason,感谢你的精彩分享。我有从2017年1月到2018年1月的工单数量。
    我应用了AREMA模型,得到了如下的测试数据预测值,这是到2018年1月的,如何预测数据库中没有的2018年2月和2018年3月的数据呢?
    预测值=2440.666667,实际值=2593.000000
    预测值=2642.187500,实际值=2289.000000
    预测值=2317.411765,实际值=2495.000000
    预测值=2533.277778,实际值=3062.000000
    预测值=3128.105263,实际值=2719.000000
    预测值=2764.650000,实际值=3159.000000
    预测值=3223.428571,实际值=3510.000000
    预测值=3587.454545,实际值=3155.000000
    预测值=3213.652174,实际值=2628.000000

  24. Adam Dziedzic 2018年3月29日 早上11:38 #

    你好 Jason,感谢你的精彩内容。你写道:“可能可以通过新观测值更新模型的内部数据,而不是从头开始重新创建模型。”我仔细检查了代码:statsmodels/tsa/arima_model.py,但没有找到如何在不修改参数(使用model.fit方法)的情况下计算新观测值的残差(如何为新观测值更新模型)。你知道怎么做吗?在 R 中这是可能的:https://stats.stackexchange.com/a/34191/149565

    • Jason Brownlee 2018年3月29日 下午3:17 #

      抱歉,我没有例子。

      • Adam Dziedzic 2018年3月30日 早上8:19 #

        Jason,谢谢你的回复。你知道是否有可能吗?如果可能,你有什么提示吗?例如,我尝试重建模型,将新观测值添加到历史记录(变量)中,并尽可能重用之前模型中的参数(我创建了一个继承自 ARIMA 的新类)。endog(之前的观测值)和 exog(误差项)的形状不一致(它们可以在内部以不同的方式转换),所以我省略了之前模型中的 exog 参数,并用一次迭代重新训练了新模型(使用 fit)。它有点作用,但可能有一个更好的方法来做到这一点。

        • Jason Brownlee 2018年3月31日 早上6:29 #

          编写一个带有您所需功能的自定义 ARIMA 可能更容易。这没什么大不了的,我确实发现 statsmodels 的实现并非完全可扩展(我相信您也发现了这一点)。

          • Adam Dziedzic 2018年4月3日 早上7:35 #

            好的,谢谢你的回答。我很感激。

  25. Kate Williams 2018年6月8日 晚上10:33 #

    嗨,Jason,
    对于我的网格搜索,所有 MLE 值都返回 0。这表明 MLE 可能未能收敛。但是,手动尝试一些 p、d 和 q 值,某些组合完美收敛,但无论如何都返回 0.0 的 MSE。
    你有什么想法可能导致这种情况吗?

    • Jason Brownlee 2018年6月9日 早上6:53 #

      或者模型具有完美的技能。也许问题太简单了?

  26. Saurabh Dhokare 2018年6月20日 早上10:00 #

    嘿,Jason!!

    一篇非常有帮助的文章。

    我只是想估算一下运行时间,考虑到我有一台第六代 i5 处理器。已经两天了,程序还在运行,没有显示任何结果。我阅读了帖子中的大部分评论并尝试调试代码。我确认代码正在运行,但它没有产生任何结果。

    你的帮助将不胜感激!!
    谢谢 🙂

    • Jason Brownlee 2018年6月21日 早上6:03 #

      或许可以添加一些 `print()` 语句来帮助查看进度?

  27. Ajay 2018年7月2日 凌晨12:55 #

    你好,我在这里创建了一些关于这个的原始代码:https://github.com/decisionstats/pythonfordatascience/blob/master/Quarterly%2BTime%2BSeries%2Bof%2Bthe%2BNumber%2Bof%2BAustralian%2BResidents.ipynb

    基本上,搜索函数是为了最小化 AIC

    这与最小化 MSE 的网格搜索相比如何

    warnings.filterwarnings(“ignore”) # 指定忽略警告消息
    c4=[]
    for param in pdq
    for param_seasonal in seasonal_pdq
    尝试
    mod = sm.tsa.statespace.SARIMAX(y,
    order=param,
    seasonal_order=param_seasonal,
    enforce_stationarity=False,
    enforce_invertibility=False)

    results = mod.fit()

    print(‘ARIMA{}x{}12 – AIC:{}’.format(param, param_seasonal, results.aic))
    c4.append(‘ARIMA{}x{}12 – AIC:{}’.format(param, param_seasonal, results.aic))
    except
    continue

  28. Galen 2018年11月20日 凌晨12:59 #

    这很棒,但我很好奇

    这里我们正在进行预测,但是如何使用 AIC、BIC 或其他标准来评估模型本身,而不进行预测呢?

  29. Hikmet Yavuz 2018年11月20日 晚上11:54 #

    嗨,Jason,

    我有一个生产问题要问你。

    我有微型数据集(每个数据集10行),并且每个数据集都需要一个ARIMA模型。我有21060个数据集,我需要创建21060个ARIMA模型,并且必须对每个ARIMA模型执行网格搜索。

    我将您的ARIMA网格搜索代码通用化,并在我的计算机上成功运行。然而,我观察到在我的计算机上创建1000个ARIMA模型(1000次网格搜索)大约需要1小时。如果我在我的计算机上运行代码,创建21060个ARIMA模型(21060次网格搜索)大约需要21小时。

    我的团队负责人问我是否可以在 Spark 环境中运行您的代码,或者是否可以在多线程模式下运行您的代码以减少执行时间(21小时)。

    你有什么建议吗?

  30. jay 2018年11月22日 早上7:45 #

    嗨 Jason

    谢谢你的文章!
    我用相同的数据库运行了相同的代码。它运行没有错误,但没有打印任何结果。它打印以下内容
    最佳 ARIMANone MSE=inf

    有什么想法吗?

      • jay 2018年11月26日 早上9:39 #

        我用相同的代码和相同的数据尝试了一切,但仍然得到相同的结果
        即最佳 ARIMANone MSE=inf

        • Jason Brownlee 2018年11月26日 下午2:03 #

          这很奇怪,你能确认一下 statsmodels 是否是最新的吗?

    • Rima 2018年11月24日 凌晨4:26 #

      你好,我也遇到了同样的问题。
      我想我找到了答案,我们应该在“Evaluate_arima_model”函数中重置测试集的索引,因为我们正在使用从0到其长度的范围进行for循环。
      必须在函数“Evaluate_arima_model”中添加以下代码行:test.reset_index(drop=True,inplace = True)

      该函数将变为

  31. jay 2018年11月26日 早上8:33 #

    你是在终端还是在anaconda中运行的?

  32. Benny Late 2018年12月21日 早上7:02 #

    嗨,Jason,

    我遇到了和其他人一样的“最佳 ARIMA None MSE=inf”错误。我正在尝试运行代码,但使用我为一个项目创建的训练/测试集。我删除了准备数据集下的第2和第3行,并将 X 的实例更改为 X_train,将 train 更改为 X_train,将 test 更改为 X_test,以匹配我之前创建的数据集。

    有没有什么想法告诉我哪里出错了?抱歉,我还是 Python 和 TS 的新手。

    谢谢,
    Benny

  33. haris ahmed 2019年2月28日 凌晨1:08 #

    我正在尝试预测客户交易,但使用 ARIMA 模型没有输出,需要帮助

  34. Alexander 2019年3月16日 凌晨1:23 #

    嗨,Jason!

    我正在用 R 语言编写这个教程,但我没有得到相同的结果。
    例如,对于洗发水数据集,ARIMA(4,2,1) 的 MSE 我得到的是 5508.63。
    我想这可能是因为我分割数据的方式与你不同。
    你能告诉我你的两个数据集的训练集分别有多少个观测值吗?

    如果事实并非如此,那么同一个数据集,使用相同的 p,d,q 参数,是否有可能得到不同的结果?

    • Jason Brownlee 2019年3月16日 早上7:56 #

      如果你改变代码,我预计会得到不同的结果。

      你可以通过打印 numpy 数组的形状来发现使用的示例数量。

  35. supradha 2019年4月10日 凌晨1:01 #

    train, test = X[0:train_size], X[train_size:]。这行代码我收到错误 TypeError: slice indices must be integers or None or have an __index__ method。数据集相同。请问有人能帮我解决这个问题吗?

    • Jason Brownlee 2019年4月10日 早上6:13 #

      如果你的变量是浮点数,或许可以将其转换为整数?

      例如:train_size = int(train_size)

  36. Daniel K. 2019年6月12日 早上6:13 #

    嗨,Jason,
    感谢您的所有帮助性帖子。

    我有一个关于搜索超参数艺术的问题。对于不应用于时间序列的机器学习方法,我通常使用嵌套 k 折交叉验证:两个较小的测试集和验证集,以及一个大的训练集。

    我认为你的方法存在的问题是,模型性能评估和模型参数调整使用了相同的数据。这样,你的性能估计可能会存在偏差。

    这里有一个关于这一点的参考资料
    https://scikit-learn.cn/stable/auto_examples/model_selection/plot_nested_cross_validation_iris.html

    为了克服这个问题,我建议做一些类似嵌套步进验证的事情,其中另一个时间步被保留用于验证目的。

    这篇文章似乎解决了这个问题(作为日向前链接),希望会很有趣:https://towardsdatascience.com/time-series-nested-cross-validation-76adba623eb9

    这种方法的缺点是,你不会有一个“最终”模型(正如 Courtney Cochrane 在评论区回复的那样),而只是所有已渲染模型的性能估计。此外,这至少使评估的计算成本增加一倍。

    当需要单个最终模型时,你有什么需要考虑的想法吗?我的想法仍然是使用你的方法,但保留最后一个时间步来测试最终模型的性能。不幸的是,这将受到测试集任意选择的影响。

  37. rituka 2019年7月24日 凌晨2:24 #

    你好,谢谢你的文章。非常感谢你的努力。
    我无法理解你选择 p、d、q 值的基础是什么
    p_values = [0, 1, 2, 4, 6, 8, 10]
    d_values = range(0, 3)
    q_values = range(0, 3) 来找到它们的最佳值?如果我有按小时采样的数据,我应该选择什么值。我正在使用 python 中的 auto_arima 函数,我想知道 max_p、max_q、start_p、d、D 的值应该传递什么?

  38. John Jewell 2019年8月19日 凌晨4:44 #

    嗨,Jason,

    我正在使用与您使用的类似的 ARIMA 模型实现,并且我一直遇到 ValueError。这是堆栈溢出线程的链接

    https://stackoverflow.com/questions/57547339/arima-model-not-invertible-producing-valueerror

    您知道问题出在哪里吗?

  39. Ahmed 2019年8月21日 凌晨12:22 #

    这真是一篇好文章。我进行了一次网格搜索,并找到了 SARIMAX 的 p、d、q 和 P、D、Q、S 的最佳值。然而,当我使用相同的配置在训练数据加上之前用作测试/保留集(在网格搜索期间)的数据上训练模型时,模型预测出指数级大数,甚至负数。您能给我一个关于这可能是什么原因以及如何避免这种情况的意见吗?谢谢。

    • Jason Brownlee 2019年8月21日 早上6:46 #

      这很有趣。

      也许在建模之前尝试对数据进行缩放?
      也许可以将结果与朴素方法进行比较,看看它们是否真的非常糟糕?

      • Ahmed 2019年8月24日 凌晨4:57 #

        为了缩放,我确实尝试使用 (x-mean)/std 方法对数据进行归一化,但问题仍然存在。我甚至尝试使用 (x-mean)/std 对数据进行归一化,然后对这些值应用 MinMax(这意味着双重归一化),但这仍然没有帮助。

        是的,我尝试将结果与 Holt-Winters 的结果进行比较,Holt-Winters 给我带来了正常的正值,但我在 SARIMAX 上获得的准确度更好(显然是在测试集上),这就是为什么我想坚持使用它。

        我无法理解的是,对于给定的一组 p,d,q,P,D,Q,S,SARIMAX 对训练集给出了非常好的值。但是,当我使用更多数据,比如说 7、8 个月(我处理的是月度数据)并且配置相同的时候,模型表现得非常异常(给出负值或指数级大/小值)。是什么导致 SARIMAX 在只添加少量数据点并使用相同配置的情况下表现得如此异常?

        • Jason Brownlee 2019年8月24日 早上8:01 #

          这太奇怪了。

          我的直觉(蜘蛛侠感)告诉我,仔细调试模型会有帮助,逐月仔细审查数据+模型可能会揭示原因。可能是输入不良。

          • Ahmed Meer 2019年8月28日 凌晨12:07 #

            为了找到 SARIMAX 的阶数和季节性阶数,我的方法是对可能的参数值进行广泛的网格搜索,然后选择在与测试数据比较时具有最小加权 MAPE 的最佳参数。这意味着,我不是根据 AIC/BIC 选择最佳模型,而是根据模型在我的测试数据上提供更好的 WMAPE 来选择。您认为这可能是我的模型在添加测试数据时失败的原因吗?我需要重新调整并使用 AIC/BIC 等方法找到最佳模型吗(尽管我知道这些模型不一定会给我最佳的 MAPE 或 WMAPE 值)。谢谢

          • Jason Brownlee 2019年8月28日 早上6:40 #

            不,听起来你的策略很棒!

  40. Le Nhu 2019年9月6日 下午1:04 #

    我不明白你为什么选择 p_values = [0, 1, 2, 4, 6, 8, 10]?

  41. Yawar Abbas 2019年9月13日 早上5:55 #

    感谢您的精彩教程。
    我有一个简单的问题,我们也可以用深度学习模型 LSTM 来对各种时间序列数据集(如洗发水销售或每日女性出生数据)进行预测,它比 ARIMA 或网格搜索 ARIMA 提供更好的预测结果。
    那么为什么不直接选择 LSTM 模型而不是这些模型呢?

  42. Shivendra Sharma 2019年10月27日 凌晨4:12 #

    Jason,太棒的教程了。有没有办法可以在我的 Python 笔记本中引用这个页面?

  43. Mark 2020年1月16日 凌晨4:27 #

    嗨 Jason

    感谢您的文章,这正是我所寻找的。我是一个 Python 新手,以前使用 Eviews 进行分析,一直在寻找优化方法。

    我成功地让你的函数运行起来,并应用到我自己的一个时间序列上。我发现处理速度非常慢。你能提供一些关于加快代码速度的最佳方法的见解吗?或者它本身就是一个相当慢的过程?

    谢谢

    Mark

  44. Mark 2020年1月28日 凌晨1:06 #

    再次感谢 Jason。我会在某个阶段买一些你的书!

  45. Jon 2020年5月23日 下午1:25 #

    感谢 Jason 的教程。当可以网格搜索这么多 ARIMA 组合时,你认为手动迭代 Box-Jenkins 搜索还有什么好处吗?即使目标是更深入地了解时间序列问题,也可以通过网格搜索来指导,不是吗?

    • Jason Brownlee 2020年5月24日 早上6:02 #

      不客气。

      我喜欢尝试两种方法。首先手动操作,看看我是否理解问题,然后进行网格搜索,看看我是否遗漏了什么,或者是否有非显而易见的解决方案效果更好。

      • Jon 2020年5月24日 晚上11:40 #

        谢谢你的回答。仅仅进行网格搜索而不深入理解问题,这种诱惑让我想起我对商业智能工具(例如 Tableau 和 Power BI)发展的担忧:当如此看似良好的预测和可视化如此容易实现时,我担心用户/客户可能没有意识到他们在理解问题方面错过了什么,例如意识到预测是一种探索不确定情景的工具,也许是其背后原因行为的工具,而不是一个水晶球。如果他们没有意识到他们错过了什么,那么他们就不会看到它的价值。你明白我的意思吗?

        • Jason Brownlee 2020年5月25日 早上5:52 #

          是的,这可能会发生。

          • Jon 2020年5月25日 晚上5:52 #

            您认为是否存在某些情境(甚至整个行业),这种情况发生得多一些或少一些?

            例如,我正在思考,在对实际理解有需求的情境中,比如投资决策或公用事业公司,可能有一种力量促使他们想要更好地理解自己的系统,而在成功更为主观的领域,比如营销,或者更长期的领域,比如公共政策,可能由充满政治斗争的层级管理,可能有一种更强的力量促使他们想要一个模型/咨询/水晶球来归咎于某个过于精确的预测(当它没有实现时)。您是否注意到这种情况或类似情况?或者相反?

            我想我是在想:您能提供一些经验法则来找到那些希望深入了解问题情境的客户,而不是那些想要一个过于精确的水晶球来推卸责任的客户吗?

          • Jason Brownlee 2020年5月26日 早上6:17 #

            哦天哪,这个问题很深刻。我的回答是:可能吧。

            我更喜欢以相反的方式解决这类问题。发出一个我能做些什么的需求,然后等待感兴趣的人举手。不需要销售,因为每个人都已经达成共识。

  46. Jon 2020年5月28日 下午2:28 #

    谢谢 Jason。

  47. Wayne Davis 2020年7月7日 早上8:18 #

    感谢这篇教程。

    我知道用 AIC 比较不同 'd' 值的模型是无效的。如果这是真的,并且您想使用 AIC,那么您的网格搜索中只能使用单个 'd' 值吗?您对将 AIC 和 MSE 混合在一起以创建更广泛的网格搜索有什么看法?您知道 Auto_ARIMA 是如何解决这个问题的吗?

    您是否也会在网格搜索中包含检查 p 值,还是仅通过 MSE 或 AIC 进行选择就足够了?

    我也对使用 ACF 和 PACF 图的值来为网格播种感兴趣。您对此有什么想法或示例吗?

    • Jason Brownlee 2020年7月7日 下午1:59 #

      通常,我建议只选择一个指标,并将其用于模型选择。

      是的,ACF 和 PACF 的结果可以为网格搜索的值提供思路。我通常手动播种搜索。

  48. Perpetual newbie 2020年7月21日 晚上10:23 #

    致遇到 `Best ARIMANone MSE=inf` 错误的人

    检查您的导入,特别是 metrics。

  49. Vidya 2020年8月4日 下午3:50 #

    嗨,Jason。

    在 statsmodel 的 'plot_acf' 和 'plot_pacf' 函数中,我们如何确定 'lags' 参数的值?

    谢谢!

  50. Vidya 2020年8月5日 下午12:38 #

    谢谢!

  51. Jimmy Rico 2020年8月13日 晚上7:45 #

    感谢这篇很棒的文章,它真的帮助我完成了一个具有挑战性的时间序列练习!

    我遇到了一种情况,在对模型参数(我的情况是 SARIMA)进行网格搜索后,误差几乎集中在零附近,方差恒定,自相关性也远低于置信区间,所以到目前为止我没问题,但是自相关性中有一个独特的单一观测值(第50个),它具有巨大的负值……

    在这种特殊且独特的情况下,您建议我怎么做?

    提前感谢您的支持!

    Jimmy Rico

    • Jason Brownlee 2020年8月14日 早上6:03 #

      不客气。

      不确定,或许可以尝试对原始数据进行转换?

  52. cmelan 2020年9月7日 下午3:51 #

    你好 Jason,这太棒了。谢谢你!

    我知道我的数据不是平稳的,但最佳结果是 d=0。那么,不使数据平稳地继续下去可以吗?

    ARIMA(8, 0, 2) MSE=30823882221855.320

  53. schrondinger 2020年11月25日 早上7:19 #

    你好 Jason!我运行了你的代码,它运行良好,但当我尝试插入我自己的数据集时,它有很多日期和许多 ID。在这种情况下,我应该在 read_csv('data.csv',header = 0 ,index_col =?) 中填入什么?

  54. Yazan M. 2020年12月7日 晚上6:54 #

    你好 Jason。感谢你宝贵的帖子!

    2 个问题

    1) 对于洗发水案例研究,我在 Jupyter 中运行它,最后几行是
    ARIMA(4, 2, 1) RMSE=68.519
    ARIMA(6, 0, 0) RMSE=91.283
    ARIMA(6, 1, 0) RMSE=82.523
    ARIMA(6, 1, 1) RMSE=66.742
    ARIMA(6, 2, 0) RMSE=79.127
    ARIMA(8, 1, 0) RMSE=81.112
    ARIMA(10, 1, 0) RMSE=86.852

    最佳 ARIMA(6, 1, 1) RMSE=66.742

    我注意到你的输出没有 (6,1,1)。你认为我们得到不同结果的原因是什么?

    2) 有一个关于 ARIMA 的弃用警告。我尝试按照警告指示更新库,但 RMSE 值相差甚远。你认为新库意味着我们必须以不同的方式指定模型才能匹配旧库吗?我担心的是,如果新库也有不同的算法,这意味着我们无法匹配旧库和新库之间的结果。

    • Jason Brownlee 2020年12月8日 早上7:41 #

      不客气。

      是的,我们可能会得到不同的结果
      https://machinelearning.org.cn/faq/single-faq/why-do-i-get-different-results-each-time-i-run-the-code

      我希望尽快更新示例。

    • Alo Alvarez 2020年12月27日 早上9:15 #

      @Jason 首先,非常感谢 Jason 提供了这些精彩的教程。真的促使我不断学习!

      @Yazan 我刚刚运行了这个教程,发现了 RMSE 值有相同的差异。教程中显示的值是我们较小 RMSE 结果的 2 次方。如果您从第 24 行删除“sqrt”,您将得到与样本中相同范围的结果。

      为什么?不知道,我只是一个业余初学者……也许有人对为什么以及这个更改是否会影响结果有更好的见解。

  55. David Andrian 2021年2月22日 凌晨12:41 #

    你好,谢谢 Jason 先生的精彩博客,对我帮助很大。我一直在尝试对我的数据进行时间序列分析,目前我正在使用你的方法来编写程序。在试运行你发布的这段代码后,我得到了一个非逻辑的预测值,即销售额为负值,尽管使用了 MSE 阶数组合的最小值。你能给我一些关于如何纠正它的建议吗,谢谢

    • Jason Brownlee 2021年2月22日 早上5:03 #

      不客气。

      或许你可以通过后期处理来修正预测结果?
      或许你可以尝试在建模之前进行另一种数据准备?
      或许你可以尝试另一种模型配置?
      或许你可以尝试另一种模型?

  56. John Nancelot 2021年8月13日 晚上9:43 #

    嗨,Jason,

    方法中必须进行平稳性检查吗?如果不检查会发生什么?我们可以对 ARIMA 进行如下所述的假设,对吗?

    前提条件。ARIMA 模型可以对时间序列数据集做出假设,例如正态性和平稳性。可以在训练给定模型之前对这些进行检查,并在给定数据集时发出警告。

    谢谢你。

    • Adrian Tam
      Adrian Tam 2021年8月14日 凌晨3:25 #

      如果序列不平稳,即使你得到了模型,它也无法有效地预测未来。ARIMA(其中的“I”)允许拟合非平稳时间序列,方法是找到积分(I 部分),即重复对时间序列进行差分,直到它变得平稳。因此,你可以看到,平稳性是必需的。要么你检查它,要么模型必须自己找出这一点。

      • John Nancelot 2021年8月16日 早上10:54 #

        非常感谢您的回复。这非常有启发性。您能进一步解释一下“模型必须自己找出这一点”吗?我可以说,因为我正在进行网格搜索,我正在训练集中使用交叉验证,同时使用测试集来避免过拟合,如果我的结果令人满意(例如从 RMSE 判断),那么这很可能来自选择了 ARIMA 中适当的 I 值以使时间序列平稳的模型。从这个意义上说,模型已经自己找出了这一点,并学会了如何获得一个平稳的时间序列?否则结果就不会好?

        • Adrian Tam
          Adrian Tam 2021年8月17日 上午7:38 #

          你是对的!

  57. Onari 2022年7月28日 晚上10:41 #

    嗨,Jason,你能用ARIMAX模型做一个例子吗?

发表回复

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