前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >霍尔特-温特斯的时间序列预测

霍尔特-温特斯的时间序列预测

作者头像
磐创AI
发布2024-04-03 19:17:18
1370
发布2024-04-03 19:17:18
举报

背景

我们讨论一组非常知名的预测模型,指数平滑。指数平滑的基本原则是将更多的权重放在最近的观测值上,而在历史观测值上放置更少的权重,以用来预测时间序列。

最基本的指数平滑模型是(有趣的是)简单指数平滑,也称为单一指数平滑。这个模型只预测时间序列的水平,不考虑趋势或季节性。要了解有关此模型的更多信息,请查看我的先前文章:

https://towardsdatascience.com/forecasting-with-simple-exponential-smoothing-dd8f8470a14c

从这个简单模型出发的下一步是霍尔特的线性趋势方法,也称为双指数平滑。顾名思义,该模型包括趋势以及水平。如果想了解有关霍尔特方法的更多信息,请参阅以下链接:

https://towardsdatascience.com/forecasting-with-holts-linear-trend-exponential-smoothing-af2aa4590c18

最后,从霍尔特方法出发的下一步是找到一种方法,将季节性纳入指数平滑模型中。这就是霍尔特-温特斯(三重指数平滑)发挥作用的地方!

在本文中,我们将回顾指数平滑的理论,深入探讨霍尔特-温特斯模型如何包括季节性的数学原理,最后通过Python进行实际示例演示。

霍尔特-温特斯模型理论

简单指数平滑回顾

让我们快速回顾一下简单指数平滑的工作原理:

有关简单指数平滑的详细解释,请参阅我之前的文章:

其中ŷ_{t+1}是我们要预测的值,y_t 是最近观察到的值,ŷ_{t-1} 是我们以前的预测,α 是平滑因子(0 ≤ α ≤ 1)。

该模型的分量形式是:

其中 h 是我们要预测的时间步,l_t = ŷ_{t+1} 明确表示这是模型的水平分量。

霍尔特的线性趋势方法回顾

霍尔特的线性趋势模型将趋势分量引入到预测中:

其中 b_t 是预测的趋势,b_{t-1} 是先前的预测趋势,β 是趋势平滑因子(0 ≤ β ≤ 1)。

有关霍尔特线性趋势方法的详细解释,请参阅我的先前文章。

霍尔特-温特斯

如上所述,霍尔特-温特斯模型通过将季节性纳入预测进一步扩展了霍尔特的线性趋势方法。季节性的添加导致了两种不同的霍尔特-温特斯模型,加法和乘法。

这两种模型之间的区别在于季节性波动的大小。对于加法模型,季节性波动主要是恒定的。然而,对于乘法模型,波动与该特定时间的时间序列值成比例。有关加法和乘法时间序列模型的更多信息,请查看我的先前博客文章:

https://towardsdatascience.com/time-series-decomposition-8f39432f78f9

现在让我们来看看这两种霍尔特-温特斯模型的方程式:

https://otexts.com/fpp3/holt-winters.html

加法模型:

其中 m 是时间序列的季节性,s_t 是季节性预测分量,s_{t-m} 是上一季度的预测,γ 是季节性分量平滑因子(0 ≤ γ ≤ 1-α)。

乘法模型:

这些方程式的细节我们不再详细讨论,它们的目的是计算时间序列的趋势线,并按季节性变化对趋势线上的值进行加权。

值得注意的是,还有其他形式的这些方程,其中包含一个阻尼参数。我们在本文中不涉及这些内容,但感兴趣的读者可以在此处了解更多信息。

够了,让我们不再讨论这些乏味的数学内容,转而在Python中实现这个模型!

Python示例

我们将像往常一样使用美国航空公司的数据集,并使用statsmodel库中的ExponentialSmoothing类来拟合霍尔特-温特斯预测模型。

https://www.statsmodels.org/dev/generated/statsmodels.tsa.holtwinters.ExponentialSmoothing.html

代码语言:javascript
复制
# Import packages
import plotly.graph_objects as go
import pandas as pd
from statsmodels.tsa.holtwinters import SimpleExpSmoothing, Holt, ExponentialSmoothing

# Read in the data
data = pd.read_csv('AirPassengers.csv')
data['Month'] = pd.to_datetime(data['Month'])

# Split train and test
train = data.iloc[:-int(len(data) * 0.2)]
test = data.iloc[-int(len(data) * 0.2):]


def plot_func(forecast1: list[float],
              forecast2: list[float],
              forecast3: list[float],
              title: str,
              save_path: str) -> None:
    """Function to plot the forecasts."""
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=train['Month'], y=train['#Passengers'], name='Train'))
    fig.add_trace(go.Scatter(x=test['Month'], y=test['#Passengers'], name='Train'))
    fig.add_trace(go.Scatter(x=test['Month'], y=forecast1, name='Simple'))
    fig.add_trace(go.Scatter(x=test['Month'], y=forecast2, name="Holt's Linear"))
    fig.add_trace(go.Scatter(x=test['Month'], y=forecast3, name='Holt Winters'))
    fig.update_layout(template="simple_white", font=dict(size=18), title_text=title,
                      width=700, title_x=0.5, height=400, xaxis_title='Date',
                      yaxis_title='Passenger Volume')
    return fig.show()


# Fit simple model and get forecasts
model_simple = SimpleExpSmoothing(train['#Passengers']).fit(optimized=True)
forecasts_simple = model_simple.forecast(len(test))

# Fit Holt's model and get forecasts
model_holt = Holt(train['#Passengers'], damped_trend=True).fit(optimized=True)
forecasts_holt = model_holt.forecast(len(test))

# Fit Holt Winters model and get forecasts
model_holt_winters = ExponentialSmoothing(train['#Passengers'], trend='mul',
                                          seasonal='mul', seasonal_periods=12)\
                                          .fit(optimized=True)
forecasts_holt_winters = model_holt_winters.forecast(len(test))

# Plot the forecasts
plot_func(forecasts_simple, forecasts_holt, forecasts_holt_winters,  "Holt-Winters Exponential Smoothing")

从上图可以看出,霍尔特-温特斯的预测明显是最好的,因为它捕捉到了时间序列的趋势和季节性。

在调用模型时,我们传递了参数seasonal_periods、trend和seasonal给模型对象。从上图可以看出,有明显的年度季节性,因此我们设置seasonal_periods=12。此外,趋势不是很直线,因此它是乘法的,因此trend='multi'。最后,季节性波动不是一些固定的一致值,而是与时间序列的值成比例,因此季节性是乘法的,即seasonal='multi'。

霍尔特-温特斯模型还可以通过执行summary方法进行诊断:

代码语言:javascript
复制
print(model_holt_winters.summary())

平滑度参数smoothing_level、α和smoothing_seasonal、γ相对较高,表明季节性和水平分量经常变化。然而,平滑趋势参数smoothing_trend、β的值相对较小,意味着趋势变化不是很大。

总结

通过讨论可能是最有用的模型霍尔特-温特斯,我们完成了指数平滑家族的介绍。这个模型考虑了趋势和季节性分量,因此可以有效地用来建模大多数时间序列。正如我们的Python示例所示,它很好地捕捉了季节性和趋势分量。

本文中使用的完整代码在我的GitHub上可用:

https://github.com/egorhowell/Medium-Articles/blob/main/Time%20Series/Exponential%20Smoothing/holt_winters.py?source=post_page-----b78ffc322f24

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 磐创AI 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 霍尔特-温特斯模型理论
    • 简单指数平滑回顾
      • 霍尔特的线性趋势方法回顾
        • 霍尔特-温特斯
        • Python示例
        • 总结
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档