在 Python 中使用 Holt-Winters 进行预测

Posted

技术标签:

【中文标题】在 Python 中使用 Holt-Winters 进行预测【英文标题】:Using Holt-Winters for forecasting in Python 【发布时间】:2011-08-17 12:49:03 【问题描述】:

我一直在尝试使用this implementation of the Holt-Winters algorithm 在 Python 中进行时间序列预测,但遇到了障碍......基本上,对于某些(正)输入序列,它有时会预测负数,这显然不应该案子。即使预测不是负面的,它们有时也会非常不准确——比应有的高/低几个数量级。给算法更多的数据周期似乎没有帮助,实际上往往会使预测变得更糟。

我使用的数据有以下特点,可能有问题:

非常频繁地采样(每 15 分钟一个数据点,而不是示例使用的每月数据) - 但根据我的阅读,Holt-Winters 算法应该没有问题。也许这表明实施存在问题?

具有多个周期性 - 存在每日峰值(即每 96 个数据点)以及周末数据的每周周期明显低于工作日数据 - 例如,工作日的峰值可能在 4000 左右,但周末的峰值在 1000 -但即使我只给它工作日数据,我也会遇到负数问题。

在实现或使用 Holt-Winters 算法时,我是否缺少一些东西?我不是统计学家,所以我使用上面链接中指示的 alpha、beta 和 gamma 的“默认”值 - 这可能是问题所在,是否有更好的方法来计算这些值?

或者...这里有比 Holt-Winters 更好的算法吗?最终,我只想从这里的历史数据中创建明智的预测。我尝试过单指数和双指数平滑,但(据我所知)都不支持数据的周期性。

任何帮助/输入将不胜感激!

【问题讨论】:

是否可以给出产生错误输出的数据的 sn-p? 一个有趣的问题,但除了偶然使用 Python 之外,它与主题无关。这更适合stats.stackexchange.com。 您能解释一下您认为该算法不应产生负预测的原因吗?是基于你对算法的理解,还是基于你知道数据是积极的? 【参考方案1】:

我尝试生成随机数据,直到得到有趣的结果。在这里,我输入了所有正数并得到了负预测:

y = [0.92, 0.78, 0.92, 0.61, 0.47, 0.4, 0.59, 0.13, 0.27, 0.31, 0.24, 0.01]
holtwinters(y, 0.2, 0.1, 0.05, 4)

...
forecast: -0.104857182966
forecast: -0.197407475203
forecast: -0.463988558577
forecast: -0.258023593197

但请注意,预测符合数据的负斜率。

这可能是您所说的数量级:

y = [0.1, 0.68, 0.15, 0.08, 0.94, 0.58, 0.35, 0.38, 0.7, 0.74, 0.93, 0.87]
holtwinters(y, 0.2, 0.1, 0.05, 4)

...
forecast: 1.93777559066
forecast: 3.11109138055
forecast: 0.910967977635
forecast: 0.684668348397

但我不确定你如何认为它非常不准确或判断它“应该”更低。


每当您推断数据时,都会得到令人惊讶的结果。您是否更担心实现可能不正确或输出没有适合您特定用途的良好属性?

【讨论】:

我所说的数量级是针对从未超过 4k 的输入值或相同的负值获得 100k 的预测。但是,是的:前者而不是后者,尽管我开始怀疑 H-W 并不是首先使用的最佳算法。【参考方案2】:

您观察到数据中存在周期性这一事实意味着您还应该尝试使用可以表达此类特征的模型。

Holt-Winters 是一个简单的平滑模型,无法表达这一点。

经典方法是查看 ARMA 模型(自回归移动平均),以及 SARIMA(季节性调整...)模型的自然扩展。

底线:这确实是一个统计问题。关于该主题的最佳著作之一是 Maddala 的《计量经济学》。

【讨论】:

这里没有什么我可以同意的。 Holt-Winters 是一种季节性预测方法。当然它可以处理周期性。但是,它不能处理多个周期,标准的 SARIMA 模型也不能。 Maddala 的书对预测的覆盖面很差。【参考方案3】:

Firstable,如果您不确定算法的具体实现,我建议您为此创建一些测试用例。采取另一种实现,也许是 matlab,无论如何,任何你知道它有效的东西。生成一些输入,将其提供给参考和您的实现,它应该是相同的。我已经通过这种方式翻译并验证了一些来自 matlab 的算法。 scipy.io.loadmat 非常适合。

关于您对算法的使用:您正在谈论以天和周为单位的周期性,并且您以分钟的时间尺度提供数据。我不知道这个特定算法是否处理得很好,但无论如何我建议尝试一些低通滤波,然后每小时将其输入算法,甚至更慢。一个时期的近 700 个时间步长可能难以识别。您输入的数据还应包含至少两个完整的时间序列周期。如果您的算法支持周期性,您还必须以适当的方式为其提供数据,以便它实际上可以看到周期性。你得到这些极值的事实可能是一个暗示,算法只有一个方向的稳定趋势的日期。

也许您还想将您的预测分开,让一个针对每周预测进行优化,另一个针对日内预测进行优化,最后您再次将它们组合起来。

【讨论】:

【参考方案4】:

我认为这种方法的问题在于他们如何计算初始值。他们似乎在使用线性模型:

这是一个非常糟糕的方法,不应该按照趋势使用 受季节性模式的影响。想象一个季节性模式, 例如,一年中的最后一个时期总是最大的 年的价值。那么趋势就会向上偏。 不幸的是,鲍尔曼、奥康奈尔和科勒 (2005) 没有 独自推荐不好的方法。我见过类似的,更糟糕​​的是, 其他书中推荐的程序。 [1]

一种更好的方法来分解趋势和季节性的时间序列 [1]

[1]http://robjhyndman.com/hyndsight/hw-initialization/

【讨论】:

【参考方案5】:

在选择适当的预测方法之前分析时间序列属性很重要。

1 - 在应用 Holt-Winters 之前,检查您的时间序列是否平稳可能很重要,如果不是,则区分它以实现此属性,这有助于提高准确性。

2 - 数据会随着时间的推移而周期性变化,而看似趋势的数据实际上可能是一个大的季节性周期的一部分。如果这是您的情况(并且确实如此),也许您应该应用 Holt-Winters 两次,每个季节周期一次,因为它无法处理多个周期性,然后分析更适合您的场景。

3 - 尝试不同的平滑参数(alpha、beta 和 gamma)可能很重要。它们越大,最后的少数观察和最后计算的组件变得越重要。尝试找到一个自适应 Holt-Winters 实现,它会自动调整这些参数,看看会发生什么。

我建议您使用 R 语言,它包含通过预测包提供的自适应且易于使用的 Holt-Winters 实现,因此您可以轻松地试验不同的配置。

【讨论】:

以上是关于在 Python 中使用 Holt-Winters 进行预测的主要内容,如果未能解决你的问题,请参考以下文章

Holt-Winters模型原理分析

使用 statsmodels 进行 Holt-Winters 时间序列预测

无法使用 statsmodels 库实现 Holt-Winters 方法

Holt-Winters -- Kibana5.4时间序列分析

基于Holt-Winters方法对资源进行预测

时间序列挖掘-预测算法-三次指数平滑法(Holt-Winters)——三次指数平滑算法可以很好的保存时间序列数据的趋势和季节性信息