在Python中使用霍尔特-温特斯法进行预测

24 投票
5 回答
16826 浏览
提问于 2025-04-16 16:52

我一直在尝试在Python中使用这个Holt-Winters算法的实现来进行时间序列预测,但遇到了一些问题……基本上,对于一些(正数)输入序列,它有时会预测出负数,这显然是不应该发生的。即使预测结果不是负数,有时也会非常不准确——比应该的值高出或低出几个数量级。给算法提供更多的数据周期似乎没有帮助,实际上还常常使预测变得更糟。

我使用的数据有以下一些特点,这可能是问题所在:

  • 采样频率非常高(每15分钟一个数据点,而不是像例子中那样的每月数据)——但根据我所了解,Holt-Winters算法应该对此没有问题。也许这说明实现上有问题?

  • 有多个周期性特征——每天都有高峰(即每96个数据点)以及每周的周期性,周末的数据明显低于工作日的数据——例如,工作日的高峰可以达到4000,而周末的高峰只有1000——但即使我只提供工作日的数据,我仍然会遇到负数的问题。

我在使用Holt-Winters算法时,是不是遗漏了什么?我不是统计学家,所以我使用了上面链接中提到的默认值alpha、beta和gamma——这可能是问题所在吗?有没有更好的方法来计算这些值?

或者……有没有比Holt-Winters更好的算法可以使用?最终,我只是想从历史数据中创建合理的预测。我尝试过单指数平滑和双指数平滑,但(据我所知)这两者都不支持数据的周期性。

任何帮助或建议都将不胜感激!

5 个回答

0

我觉得这个方法的问题在于他们计算初始值的方式。他们似乎在用线性模型来处理:

这是一种很糟糕的方法,不应该使用,因为趋势会受到季节性模式的影响。想象一下一个季节性模式,比如说一年中的最后一个时期总是这一年中数值最大的。那么这个趋势就会被向上偏移。不幸的是,Bowerman、O’Connell 和 Koehler(2005)并不是唯一推荐糟糕方法的人。我在其他书籍中也见过类似甚至更糟的推荐。[1]

一个更好的方法是将时间序列分解为趋势和季节性。[1]

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

1

首先,如果你对自己实现的算法不太确定,我建议你先创建一些测试案例。可以找一个其他的实现,比如用matlab,或者任何你知道能正常工作的工具。生成一些输入数据,把这些数据同时输入到参考实现和你的实现中,看看结果是否一致。我就是这样把一些算法从matlab翻译过来的,scipy.io.loadmat在这方面非常好用。

关于你使用算法的方式:你提到的是按天和周的周期性,但你输入的数据是以分钟为单位的。我不确定这个特定的算法是否能很好地处理这种情况,但我建议你可以先做一些低通滤波,然后每小时甚至更慢地输入数据。因为对于一个周期来说,近700个时间步可能太多了,算法可能难以识别。你输入的数据至少应该包含两个完整的周期。如果你的算法支持周期性,你还需要以合适的方式提供数据,这样它才能真正“看到”周期性。你得到这些极端值的事实可能表明,算法只接收到一个方向的稳定趋势的数据。

也许你还想把预测分开,一个优化用于每周预测,另一个用于日内预测,最后再把它们结合起来。

2

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

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

不过我不太确定你是怎么认为这个结果非常不准确,或者觉得它“应该”更低的。


每当你在推测数据的时候,结果可能会让人感到惊讶。你更担心的是实现可能不正确,还是输出结果对于你特定的使用场景不太合适呢?

撰写回答