[Formula&Excel&Python] 一次指数平滑、二次指数平滑、三次指数平滑...

共 2096字,需浏览 5分钟

 ·

2022-03-24 11:25

d91883c4975c863aa96877042bb6fd47.webp

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

简单指数平滑

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

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

预测方程:    
平滑方程:


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

示例演示3772f2ddf4748c08f0cbbeef0eb37966.webp
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)
32697712e0bfe18f36d1053f08307710.webp

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

二次指数平滑

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

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

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

Holt线性趋势模型

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

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

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

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

示例演示4c8027eda827b588458de8c746083e33.webp
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))
1e52df307f392a84be5752042d84378f.webp

指数趋势模型

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

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

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

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

示例演示153be6d6b82c8aa81601a030b2eed44f.webp
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)
ca263505532c1fd70c4fa8f818a50e9f.webp

阻尼趋势模型

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

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

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

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

示例演示d480aa128b81345a2e01f198e53a3817.webp
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)
6ed45fe7c0432cc2dcc843b28cc44456.webp

乘法阻尼趋势

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

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

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

示例演示7de4c4e5d4178290a2166eb669bbb13b.webp
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))
29f214074bb85290d9a2de15f62b3b8a.webp三次指数平滑

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

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

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

Holt-Winters加法模型

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

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

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

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

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

示例演示1456958da003e6c3b890db8f5168a94b.webp
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))
2de45d98d8ae5c00b0fdf1a42c6d3758.webp

Holt-Winters乘法模型

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

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


示例演示7cd8c1240e09b686d6d7f6dc1f552434.webp
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))
70eeec86a145fbd90b45a648d2e174b8.webp

Holt-Winters的衰减法

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

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

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


示例演示a0a29f0501afa1f6f03cd885e523de67.webp
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))
d665036979ea8e4b058b6555cc023fc8.webp写在最后

仍使用本次构造的简单数据,对比展示不同方法下的效果,可以看出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顺序错了
cdfe29ded187a1e61948301ce86b01d6.webp

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

9dfd6876caac3f5f61b3558df351a955.webp参考链接


[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


浏览 91
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报