[Formula&Excel&Python] 一次指数平滑、二次指数平滑、三次指数平滑(Holt-Winters)...

指数平滑由移动平均发展而来,和指数移动平均有点相似,也可认为是一种特殊的加权移动平均。按平滑的次数,指数平滑可分为一次指数平滑、二次指数平滑、三次指数平滑。移动平均除了简单预测外另在股市中作为支撑线发光发热;指数平滑主要用于预测,在各个领域应用非常广泛,是最常用的预测方法之一。

  • 一次指数平滑:适用于序列没有趋势和季节性特征

  • 二次指数平滑:适用于序列有趋势特征但无季节性特征

  • 三次指数平滑:适用于序列有趋势特征且有季节性特征

一次指数平滑

简单指数平滑

一次指数平滑中最常用的实现方法就是简单指数平滑,有时我们说指数平滑也是指的简单指数平滑(Single Exponential Smoothing)。

参数:,平滑因子或平滑系数

预测方程:    
平滑方程:

取值范围[0~1],值越大,越关注近期的观测值,远期的观测值影响越小。当时间序列相对平稳时,取较小的;当时间序列波动较大时,取较大的,以不忽略远期观测值的影响。

示例演示 1da288258c631a68b35980f99d90f511.png
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt

data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

# 方法1,alpha=0.7
fit1 = SimpleExpSmoothing(data).fit(smoothing_level=0.7,optimized=False)
print('>> fit1', 'forecast:', fit1.forecast(3), 'sse:', fit1.sse)

# 方法2,不加任何参数,optimized默认为True,能自动选择alpha。
fit2 = SimpleExpSmoothing(data).fit()
print('>> fit2', 'forecast:', fit2.forecast(3), 'sse:', fit2.sse)
895ecdd403df35162dc5090e785bc375.png

推荐使用方法2,自动识别最优参数。statsmodels中通过最小化平滑值和实际值的欧式距离确定最优参数,其实也可通过SSE、MAE、RMSE、SMAPE等评估指标确定最优参数。不使用自动优化时,和可根据场景经验确定,简单指数平滑中statsmodels中默认使用第一个观测值作为初始指数平滑的值。
d554950941d270115ec18ef8456154b3.png

二次指数平滑

二次指数平滑,也叫双指数平滑,是指数平滑的扩展。常用实现为Holt指数平滑,方法中包含一个预测方程和两个平滑方程(水平平滑方程+趋势预测方程)。

其中,趋势部分又可分为加性趋势和乘性趋势,分别对应Holt线性趋势模型、指数趋势模型。

对于较大时间步长的预测,趋势可能不会无限延长,就需要抑制这种趋势,加性趋势和乘性趋势的抑制分别对应加性抑制(抑制线性趋势)、乘性抑制(抑制指数趋势)。

Holt线性趋势模型

Holt 在1957年把简单的指数平滑模型进行了延伸,能够预测包含趋势的数据,

参数1:,水平平滑因子,水平平滑参数
参数2:,趋势平滑因子,控制趋势变化的影响

预测方程:
水平方程:
趋势方程:

其中,代表时刻t的预估水平,代表时刻t的预测趋势,是水平的平滑参数,是趋势的平滑参数。

示例演示 3a2201fa5a19a4675c005c569fd745a1.png
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt
data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

fit1 = Holt(data).fit(smoothing_level=0.7, smoothing_trend=0.2, optimized=False)

print(fit1.summary())
print('forecast:', fit1.forecast(3))
72bbbdd9bffa940b1c6c561bea5fce5f.png

指数趋势模型

另外一种Holt 线性模型的变体是指数趋势模型,水平分量和趋势分量不再是相加的,而是相乘的。

参数1:,水平平滑因子
参数2:,趋势平滑因子

预测方程:
水平方程:
趋势方程:

其中,代表预估的增长率,描述指数趋势。

示例演示 1442edb0210f6a921d9ba06179537921.png
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt
data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

fit1 = Holt(data, exponential=True).fit(smoothing_level=0.7, smoothing_trend=0.2, optimized=False)

print(fit1.summary())
print('>> fit1', 'forecast:', fit1.forecast(3), 'sse:', fit1.sse)
8219477fe5e28267cf1ddfac0fe9704a.png

阻尼趋势模型

Gardner 和 McKenzie (1985)引入了一种阻尼效应,未来的增长趋势会有所放缓。

参数1:,水平平滑因子
参数2:,趋势平滑因子
参数3:,0<<1,阻尼参数,防止预测“失控”

预测方程:
水平方程:
趋势方程:

其中,当时,等同于Holt线性趋势模型。

示例演示 f2865662c9a08082a34e0d29dbd94f76.png
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt
data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

fit1 = Holt(data, exponential=False, damped_trend=True).fit(smoothing_level=0.7, smoothing_trend=0.2, damping_trend=0.8, optimized=False)

print(fit1.summary())
print('>> fit1', 'forecast:', fit1.forecast(3), 'sse:', fit1.sse)
1ca407930171c35ee6e156fe4c17a1b8.png

乘法阻尼趋势

Taylor(2003)将阻尼参数拓展到乘法模型,预测结果不像加法阻尼那么保守。

参数1:,水平平滑因子
参数2:,趋势平滑因子
参数3:,0<<1,阻尼参数

预测方程:
水平方程:
趋势方程:

示例演示 76123192d09408ffb23eed8dba1a5be9.png
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt
data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

fit1 = Holt(data, exponential=True, damped_trend=True).fit(smoothing_level=0.7, smoothing_trend=0.2, damping_trend=0.8, optimized=False)

print(fit1.summary())
print('forecast:', fit1.forecast(3))
6683b7b1ffaa9adc9752b365c0ef9318.png

三次指数平滑

三次指数平滑是二次指数平滑基础上再做一次平滑,使用中通常使用Holt-Winters方法,我们平时讲三次指数平滑方法一般也是特指Holt-Winters指数平滑。

Holt (1957) 和 Winters (1960) 将Holt方法进行拓展,增加了对季节因素的处理。方法中包含一个预测方程和三个平滑方程 (一个用于水平,一个用于趋势,一个用于季节性分量)。

与趋势一样,季节性也有加性(线性)或乘性(指数)过程。当季节变化在时间序列中大致保持不变时,通常选择加法模型;而当季节变化与时间序列的水平成比例变化时,通常选择乘法模型。

Holt-Winters加法模型

用  来表示季节频率,如季度数据的m=4,月度数据的m=12。

参数1:,水平平滑参数
参数2:,趋势平滑参数
参数3:,季节性平滑参数,控制季节成分的影响

预测方程  :
水平方程  :
趋势方程  :
季节性方程:

其中,趋势方程与Holt线性方程相同。

将方程带入方程中,季节性方程也可表示为:
其中,
通常,

示例演示 e8084f4dbaea92996839ccaa23e20e89.png
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt
data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

fit1 = ExponentialSmoothing(data, seasonal_periods=5, trend='add', seasonal='add').fit(smoothing_level=0.7, smoothing_trend=0.2, smoothing_seasonal=0.1, optimized=False)

print(fit1.summary())
print('forecast:', fit1.forecast(3))
7608b6850ce1b145f26795ea1dd4e230.png

Holt-Winters乘法模型

参数1:,水平平滑参数
参数2:,趋势平滑参数
参数3:,季节性平滑参数,控制季节成分的影响

预测方程  :
水平方程  :
趋势方程  :
季节性方程:

示例演示 cd0df3c327acd80628523ed3b07ac6dd.png
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt
data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

fit1 = ExponentialSmoothing(data, seasonal_periods=5, trend='add', seasonal='mul').fit(smoothing_level=0.7, smoothing_trend=0.2, smoothing_seasonal=0.1, optimized=False)

print(fit1.summary())
print('forecast:', fit1.forecast(3))
d82ab83f5c0951a2e02b3e231312c9c6.png

Holt-Winters的衰减法

加性和乘性Holt-Winters方法都可以进一步使用衰减法 。带有衰减趋势和乘性季节性的Holt-Winters方法通常可以为季节数据提供准确的和稳健的预测值。乘法模型增加阻尼参数的形式如下:

参数1:,水平平滑参数
参数2:,趋势平滑参数
参数3:,季节性平滑参数
参数4:,0<<1,阻尼参数

预测方程  :
水平方程  :
趋势方程  :
季节性方程:

示例演示 d15b311201a92a8adcbe4d6e85b1fe9d.png
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt
data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

fit1 = ExponentialSmoothing(data, seasonal_periods=5, trend='add', seasonal='mul', damped_trend=True).fit(smoothing_level=0.7, smoothing_trend=0.2, smoothing_seasonal=0.1, optimized=True)

print(fit1.summary())
print('forecast:', fit1.forecast(3))
7d53b2c64219b4bc38d7870dca79f784.png

写在最后

仍使用本次构造的简单数据,对比展示不同方法下的效果,可以看出Holt-Winters方法对当前周期性的数据拟合很好,但是需要指定周期大小,所以Holt-Winters一般适用于有明确周期性的数据。实践中一般不使用乘性趋势方法,通常效果较差。另外,statoolsmodels中fit训练时,支持对数据进行box-cox变换等处理,下面代码中不再作展示。

import numpy as np
import pandas as pd
from statsmodels.tsa.holtwinters import ExponentialSmoothing, SimpleExpSmoothing, Holt

# 数据
data = [1,2,3,4,5,2,3,4,5,6,3,4,5,6,7]

# 训练
fit1 = SimpleExpSmoothing(data).fit()
fit2 = Holt(data).fit()
fit3 = Holt(data, exponential=True).fit()
fit4 = Holt(data, exponential=False, damped_trend=True).fit()
fit5 = Holt(data, exponential=True, damped_trend=True).fit()
fit6 = ExponentialSmoothing(data, seasonal_periods=5, trend='add', seasonal='add').fit()
fit7 = ExponentialSmoothing(data, seasonal_periods=5, trend='add', seasonal='mul').fit()
fit8 = ExponentialSmoothing(data, seasonal_periods=5, trend='mul', seasonal='add').fit()
fit9 = ExponentialSmoothing(data, seasonal_periods=5, trend='mul', seasonal='mul').fit()
fit10 = ExponentialSmoothing(data, seasonal_periods=5, trend='add', seasonal='add', damped_trend=True).fit()
fit11 = ExponentialSmoothing(data, seasonal_periods=5, trend='add', seasonal='mul', damped_trend=True).fit()
fit12 = ExponentialSmoothing(data, seasonal_periods=5, trend='mul', seasonal='add', damped_trend=True).fit()
fit13 = ExponentialSmoothing(data, seasonal_periods=5, trend='mul', seasonal='mul', damped_trend=True).fit()

# 效果
FIT = [fit1, fit2, fit3, fit4, fit5, fit6, fit7, fit8, fit9, fit10, fit11, fit12, fit13]
SSE = [fit.sse for fit in FIT]
NAME = ['SES', 'Holt-ADD', 'Holt-MUL', 'Holt-ADD-DAM', 'Holt-MUL-DAM', 'HW-ADD-ADD', 'HW-ADD-MUL', 'HW-MUL-ADD', 'HW-MUL-MUL', 'HW-ADD-ADD-DAM', 'HW-ADD-MUL-DAM', 'HW-MUL-ADD-DAM', 'HW-MUL-MUL-DAM']

# 对比
df = pd.DataFrame({'NAME': NAME, 'SSE': SSE})
df['RANK'] = df['SSE'].rank().astype(int)
print(df.head(13))

# 画图
sel_index = np.argmin(SSE)
sel_model = FIT[int(sel_index)]
sel_model_name = NAME[int(sel_index)]

l1, = plt.plot(list(fit1.fittedvalues) + list(fit1.forecast(3)), marker='.')
l2, = plt.plot(list(sel_model.fittedvalues) + list(sel_model.forecast(3)), marker='*')
l3, = plt.plot(data, marker='.')

plt.legend(handles = [l1, l2, l3], labels = ['data', 'SES', sel_model_name], loc='best', prop={'size': 7})
plt.show()  #plot里label顺序错了
8b1a89b2907d7f7d2cd97e700b4dd87e.png

指数平滑各种版本的实现细节过于琐碎,可以后台回复关键字“ES”获取Excel示例下载地址,对于想要了解细节的朋友必会有所帮助。

d2f0fdf890f178446a32dfa01e074773.png 参考链接


[1]https://www.statsmodels.org/v0.11.0/_modules/statsmodels/tsa/holtwinters.html
[2]https://otexts.com/fppcn/holt-winters.html
[3]https://wiki.mbalib.com/wiki/%E6%8C%87%E6%95%B0%E5%B9%B3%E6%BB%91%E6%B3%95
[4]https://www.cnblogs.com/houfei/p/13450880.html
[5]https://blog.csdn.net/fxlou/article/details/79678860
[6]https://www.cnblogs.com/21207-iHome/p/6673573.html

转自:TimeSeries 公众号;

END


版权声明:本号内容部分来自互联网,转载请注明原文链接和作者,如有侵权或出处有误请和我们联系。


合作请加QQ:365242293  

数据分析(ID : ecshujufenxi )互联网科技与数据圈自己的微信,也是WeMedia自媒体联盟成员之一,WeMedia联盟覆盖5000万人群。

d8716fda561212087bdb7c0ab08fccc3.png

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值