【统计】时间序列预测之 Holt-Winters 指数平滑模型
Holt-Winters Exponential Smoothing
原文连接:link
作者作者:Sachin Date
翻译校对:datamonday
Holt-Winters 指数平滑法用于预测既显示趋势又显示季节性变化的时间序列数据。 Holt-Winters 技术由以下四种相互叠加的预测技术组成:
加权平均值(Weighted Averages):加权平均值是 n 个数字的平均值,其中每个数字都被赋予一定的权重,分母是这些 n 个权重的总和。权重通常根据某些加权函数分配。常用的加权函数有对数、线性、二次、三次和指数。平均作为一种时间序列预测技术,具有在计算预测时平滑历史值变化的特性。通过选择合适的加权函数,预测者可以确定在计算时间序列的未来值时应该强调哪些历史值。
指数平滑(Exponential Smoothing):指数平滑 (ES) 技术使用所有的加权平均值来预测下一个值,其中权重从最近的历史值到最早的历史值按指数规律衰减。 ES 做出了一个假设:时间序列的最新值比之前的值更重要。 ES 技术有两大缺点:当数据呈现趋势和/或季节性变化时无法使用。
Holt 指数平滑:Holt ES 技术解决了 ES 技术的两个缺点之一。 Holt ES 可用于预测具有趋势的时间序列数据。但是 Holt ES 在时间序列中存在季节性变化时会失败。
Holt-Winters 指数平滑:Holt-Winters ES 修改了 Holt ES 技术,使其可以在存在趋势和季节性的情况下使用。
要了解 Holt-Winters 指数平滑法的工作原理,必须了解时间序列的以下四个方面:
Level
通过一个例子可以更好地理解水平(level)的概念。以下时间序列显示了默克公司在纽约证券交易所的收盘价。水平方向的红线表示时间序列在上升和下降过程中的一些水平:
Trend
水平以某种模式变化的时间序列被称为具有趋势(Trend)。水平在某个平均值附近随机变化的时间序列可以说呈现出随机趋势。除了知道趋势是随机的之外,与趋势可以通过某些函数建模的趋势相比,趋势的概念在随机时并不是那么有用。
一些常见的趋势是线性的、平方的、指数的、对数的、平方根的、逆的和三次或更高的多项式。使用相应的数学函数,即 log(x)、linear、x²、exp(x) 等,这些趋势可以轻松建模。
高度非线性的趋势需要复杂的建模技术,例如人工神经网络来对其建模。
查看趋势的一种有用方法是将时间序列在给定水平上的速率或速度。这使趋势成为具有大小(变化率)和方向(增加或减少)的向量。
可以将趋势解释为速率或速度。将在解构 Holt-Winters 指数平滑的预测方程时使用它。
Seasonality
许多时间序列显示围绕当前水平的周期性上下运动。这种周期性的上下运动被称为季节性。以下是展示季节性模式的时间序列示例:
Noise
噪声只是时间序列数据中无法 (或不想) 解释的一个方面。
水平、趋势、季节性和噪声被认为以相加或相乘的方式相互作用,从而产生观察到的时间序列的最终值:
Multiplicative combination (with additive trend)
Fully additive combination
The Holt-Winters Exponential Smoothing Equation
我们现在准备看看霍尔特-温特指数平滑技术的预测方程。我们将首先考虑趋势增加到当前水平的情况,但是季节性是倍增的。这是现实世界时间序列数据中的常见情况。
我们现在准备看看 Holt-Winter 指数平滑技术的预测方程。我们将首先考虑趋势增加当前水平的情况,但季节性是相乘的。这是现实世界时间序列数据中的常见情况。
在上面的等式中,我们从任意步骤 iii 开始预测未来 kkk 个时间步长的时间序列的值。假设季节性变化具有 mmm 个时间步长的已知周期长度。例如对于年度变化,mmm = 12。
让我们看看如何估计 LiL_iLi、BiB_iBi 和 SiS_iSi。
从第 iii 步的趋势 BiB_iBi 估计开始:
上式通过以下两种不同的方式来估计在步骤 iii 观察到的趋势 BiB_iBi:
[Li−L(i−1)][L_i−L_{(i-1)}][Li−L(i−1)]:两个连续水平之间的差异,它表示在水平 L(i−1)L_{(i-1)}L(i−1) 的水平变化。看待这个术语的一种方法是将其视为数据在 LiL_iLi 层的速度,就像它从 L(i−1)L_{(i-1)}L(i−1) 层进入一样。
B(i−1)B_{(i-1)}B(i−1):简单地表示 L(i−1)L_{(i-1)}L(i−1) 处的水平变化率,以递归方式表示。为了计算 B(i−1)B_{(i-1)}B(i−1),对 BiB_iBi 使用相同的等式,将 iii 替换为 (i−1)(i-1)(i−1),并且一直这样做,直到达到 B0B_0B0,将其值假设为初始条件。下图说明了对 BiB_iBi 的上述递归关系的递归分解:
现在应该清楚 Holt-Winters 技术中指数加权平均值的缺点了。以下是三个重要的观察结果:
权重 β(1−β)β(1-β)β(1−β)、β(1−β)2β(1-β)^2β(1−β)2、β(1−β)3β(1-β)^3β(1−β)3…形成一个等比级数(geometric series)。
这个级数的每一项 β(1−β)kβ(1-β)^kβ(1−β)k 对时间序列中两个连续水平 [L(i−k)—L(i−k−1)][L_{(i-k) }— L_{(i-k-1)}][L(i−k) — L(i−k−1)] 之间的差进行加权。
最近两个水平之间的差异 [Li—L(i−1)][L_i — L_{(i-1)}][Li — L(i−1)] 具有最大的权重 βββ,并且随着时间的推移,权重会以 (1−β)(1-β)(1−β) 倍指数衰减。
还要注意,BiB_iBi 的估计需要我们知道步骤 iii 和 (i−1)(i-1)(i−1)、(i−2)(i-2)(i−2) 等处的水平,直到我们假设为初始条件的 L0L_0L0。
现在看看如何评估在时间步 iii 处的水平 LiL_iLi:
与趋势 BiB_iBi 一样,上述等式通过两种不同的方法计算 LiL_iLi,然后对两个估计值进行加权平均,从而估算出 LiL_iLi 水平,如下所示:
Ti/S(i−m)T_i/S_{(i-m)}Ti/S(i−m):回想一下,我们假设水平和季节性是相乘的,即 Ti=Li∗S(i−m)∗NiT_i=L_i*S_{(i-m)}*N_iTi=Li∗S(i−m)∗Ni。因此,如果选择忽略噪声 NiN_iNi 的影响,则对 LiL_iLi 的良好估计只需 Ti/S(i−m)T_i/S_{(i−m)}Ti/S(i−m)。
[L(i−1)+B(i−1)][L_{(i-1)}+B_{(i-1)}][L(i−1)+B(i−1)]:通过将从 L(i−1)L_{(i-1)}L(i−1) 到 LiL_iLi 发生的水平变化添加到 L(i−1)L_{(i-1)}L(i−1) 来估计水平 LiL_iLi,即趋势 B(i−1)B_{(i-1)}B(i−1)。
与 BiB_iBi 一样,我们递归求解这个方程,直到达到 T0T_0T0、S0S_0S0、B0B_0B0 和 L0L_0L0。 T0T_0T0 是训练数据集中最旧的数据点。S0S_0S0、B0B_0B0 和 L0L_0L0 是水平、趋势和季节变化的初始值。估计的方法将在下文介绍。现在,假设它们被设置为一些合理的初始值。
在上面的 LiL_iLi 方程中,为了估计 LiL_iLi,还需要估计季节性分量 S(i−m)S_{(i−m)}S(i−m) 的贡献。看看如何在步骤 iii 估计季节性分量:
可以看到,季节性分量 SiS_iSi 的估计策略与趋势 BiB_iBi 和水平 LiL_iLi 的估计策略类似,都是通过两种不同的方式计算 SiS_iSi,然后取这两个估计值的加权平均值。
现在我们知道如何估计时间步 iii 的水平、趋势和季节性分量,将这三个估计值放在一起,以获得第 (i+k)(i+k)(i+k) 步的预测 F(i+k)F_{(i+k)}F(i+k) 的估计值, 如下:
Estimation of Initial conditions
由于 Holt-Winters 方法的所有方程都是递推关系,因此我们需要为这些估计方程提供一组初始值以启动预测引擎。具体来说,我们需要设置 L0L_0L0、B0B_0B0 和 S0S_0S0 的值。
设置这些初始值有几种方法。我将解释 Python statsmodels 库使用的技术。下文将使用 statsmodels 来构建 Holt-Winters ES 估计器,并用它来预测未来 12 个时间步长。
估计 L0L_0L0:Statsmodels 将 L0L_0L0 设置为时间序列的所有观测值的平均值,位于索引 0、m、2m、3m 等处,其中 m 是季节性周期。例如如果时间序列有 12 个月的季节性周期,它将按如下方式计算 L0L_0L0:
当数据没有季节性变化时,L0=T0L_0 = T_0L0=T0。
估计 B0B_0B0:如果时间序列显示加性趋势,即其水平呈线性变化,则 statsmodels 通过计算观察到的变化率来估计初始趋势 B0B_0B0 跨 mmm 个时间步的值 TiT_iTi,然后取这些速率的平均值。例如,如果时间序列呈现加性趋势并且它的季节性周期为 12 个月,它将按如下方式计算 B0B_0B0:
如果时间序列呈现出乘法趋势,即水平以与当前水平成比例的速度增长,则 statsmodels 对 B0B_0B0 使用看起来稍微复杂的估计器。最好使用年度季节性(m=12m=12m=12)的例子来说明:
如果时间序列没有显示季节性变化,那么如果趋势是乘性的,则 B0B_0B0 只需设置为 T1/T0T_1/T_0T1/T0,如果趋势是加性的,则设置为 (T1—T0)(T_1 — T_0)(T1 — T0)。
估计 S_0:如果季节性是乘法,即给定水平的季节变化值与水平的值成正比,则 S_0 估计如下:
而当季节性变化是恒定的或在每个水平上增加一个固定的量,即它是可加的,那么 S0S_0S0 估计如下:
当时间序列中没有季节性变化时,S0S_0S0 是 [],一个空向量。
请注意一件重要的事情。虽然 LiL_iLi 和 BiB_iBi 是标量,但 SiS_iSi(因此 S0S_0S0)是长度为 m 的向量,其中 m 是季节性周期。在时间序列中的每个时间步 i=0,1,2,…ni=0,1,2,…ni=0,1,2,…n,对应的季节因子位于向量位置 (0 mod m), (1 mod m), (2 mod m),…,(i mod m),…,(n mod m) 用于计算预测 FiF_iFi。
Estimating α, β and γ
权重系数 ααα、βββ 和 γγγ 通过给它们初始值来估计,然后迭代地优化它们的值以获得一些合适的分数。 MSE(均方误差)的最小化是常用的优化目标。 Statsmodels 将初始 α 设置为 1/2m1/2m1/2m,βββ 设置为 1/20m1/20m1/20m,并在存在季节性时将初始 γγγ 设置为 1/20∗(1−α)1/20*(1 -α)1/20∗(1 −α)。
一旦估计 L0L_0L0、B0B_0B0 和 S0S_0S0,并且 ααα,βββ 和 γγγ 被设置,就可以使用 LiL_iLi, BiB_iBi, SiS_iSi, FiF_iFi 和 F(i+k)F_{(i+k)}F(i+k) 的递推关系来估计时间序列在时间步 0,1,2,3,...,i,...,n,n+1,n+2,...,n+k0, 1, 2, 3, ..., i,...,n,n+1,n+2,...,n+k0,1,2,3,...,i,...,n,n+1,n+2,...,n+k 的值。
如果训练数据集有 nnn 个数据点,则位置 n+1,n+2,...,n+kn+1,n+2,...,n+kn+1,n+2,...,n+k 对应于将使用 Holt-Winters 估计技术生成的 kkk 个样本外预测。
Using the Holt-Winters Exponential Smoothing in Python
Python 源码实现
作者:Lleyton Ariton
import matplotlib.pyplot as plt
from typing import *
def initial_trend(series: List, uppercase_m: int) -> float:return sum([float(series[i+uppercase_m] - series[i]) / uppercase_mfor i in range(uppercase_m)]) / uppercase_mdef initial_seasonality(series: List, uppercase_m: int) -> List:initial_season = []n_seasons = int(len(series)/uppercase_m)season_averages = [sum(series[uppercase_m * i:uppercase_m * i + uppercase_m]) / uppercase_m for i in range(n_seasons)]initial_season.extend([sum([series[uppercase_m*j+i]-season_averages[j]for j in range(n_seasons)]) / n_seasonsfor i in range(uppercase_m)])return initial_season
def winters_es(series: List,uppercase_m: int,alpha: float=0.2,beta: float=0.2,gamma: float=0.15,future_steps: int=1) -> List:i_l = [series[0]]i_t = [initial_trend(series, uppercase_m)]i_s = initial_seasonality(series, uppercase_m)forecasts = []for t in range(len(series) + future_steps):if t >= len(series):m = t - len(series) + 1forecasts.append((i_l[-1] + m * i_t[-1]) + i_s[t % uppercase_m])else:l_t = alpha * (series[t] - i_s[t % uppercase_m]) + (1 - alpha) * (i_l[-1] + i_t[-1])i_t[-1] = beta * (l_t - i_l[-1]) + (1 - beta) * i_t[-1]i_l[-1] = l_ti_s[t % uppercase_m] = gamma * (series[t] - l_t) + (1 - gamma) * i_s[t % uppercase_m]forecasts.append((i_l[-1] + i_t[-1]) + i_s[t % uppercase_m])return forecasts
if __name__ == '__main__':plt.figure(figsize=(32, 20))data = pd.read_csv('../data/shampoo.csv')["Sales"]data = data.values.tolist()k = 10last_months = list(range(34, 34 + k))forecast = winters_es(data, 12, future_steps=10)plt.plot(data, linewidth=5, label='Shampoo Sales')plt.plot(forecast, linewidth=4, label='Forecast')plt.axvspan(*(last_months[0], last_months[-1]), facecolor='grey', alpha=0.25)plt.legend()plt.show()
Statesmodel 包实现
将使用 Holt-Winters 指数平滑技术估计美国二手车经销商零售额时间序列的 12 个未来值。数据集可在此处下载。
将数据集读取到 Pandas data frame 中。请注意,日期列(列 0)是索引列,格式为 MM-DD-yyyy。将索引频率明确设置为每月,以便 STATSMODEL 不必尝试推断它。
import pandas as pd
from matplotlib import pyplot as plt
from statsmodels.tsa.holtwinters import ExponentialSmoothing as HWESdf = pd.read_csv('retail_sales_used_car_dealers_us_1992_2020.csv', header=0, infer_datetime_format=True, parse_dates=[0], index_col=[0])
df.index.freq = 'MS'df.plot()
plt.show()
得到下图:
在训练和测试数据集之间分开。最后 12 个时期构成了测试数据。
df_train = df.iloc[:-12]
df_test = df.iloc[-12:]
训练模型。在上图中,时间序列的水平似乎正在线性增加。因此,我们将趋势设置为加法。但是,每个水平周围的季节变化似乎与当前水平成比例增加。因此,我们将季节性设置为乘法。
model = HWES(df_train, seasonal_periods=12, trend='add', seasonal='mul')
fitted = model.fit()print(fitted.summary())
得到以下输出:
预测接下来的 12 个时间步。在同一图上绘制训练数据,测试数据和预测。
sales_forecast = fitted.forecast(steps=12)fig = plt.figure()
fig.suptitle('Retail Sales of Used Cars in the US (1992-2020)')
past, = plt.plot(df_train.index, df_train, 'b.-', label='Sales History')
future, = plt.plot(df_test.index, df_test, 'r.-', label='Actual Sales')
predicted_future, = plt.plot(df_test.index, sales_forecast, 'g.-', label='Sales Forecast')
plt.legend(handles=[past, future, predicted_future])
plt.show()
放大最后 12 个时间步。可以看到,预测滞后于急剧的转折点,这对于任何基于移动平均线的预测技术都是正确的:
【统计】时间序列预测之 Holt-Winters 指数平滑模型相关推荐
- 时序预测 | MATLAB实现趋势外推时间序列预测(含移动平均、指数平滑对比)
时序预测 | MATLAB实现趋势外推时间序列预测(含移动平均.指数平滑对比) 目录 时序预测 | MATLAB实现趋势外推时间序列预测(含移动平均.指数平滑对比) 基本介绍 程序设计 学习总结 参考 ...
- 【机器学习】时间序列预测:三次指数平滑(Holt-Winters)
statsmodels是一个Python模块,它提供对许多不同统计模型估计的类和函数,并且可以进行统计测试和统计数据的探索. # -*- encoding:utf-8 -*-import pandas ...
- Holt Winter 指数平滑模型
1 指数平滑法 移动平均模型在解决时间序列问题上简单有效,但它们的计算比较难,因为不能通过之前的计算结果推算出加权移动平均值.此外,移动平均法不能很好的处理数据集边缘的数据变化,也不能应用于现有数据集 ...
- 基于指数平滑模型与ARIMA模型在苹果股价的预测应用
一.项目背景 股票投资已经随着人们生活水平的逐步提高而变得普遍,更多的人开始逐渐关注并参与到股票投资市场中来.股票具有高收益的同时也伴随着较高的风险,我们知道,股票价格的变动受很多因素的影响,因此对于 ...
- java三次指数平滑_时间序列挖掘-预测算法-三次指数平滑法(Holt-Winters)
所有移动平均法都存在很多问题. 它们都太难计算了.每个点的计算都让你绞尽脑汁.而且也不能通过之前的计算结果推算出加权移动平均值. 移动平均值永远不可能应用于现有的数据集边缘的数据,因为它们的窗口宽度是 ...
- 一次指数平滑预测matlab,一次指数平滑法matlab
一次指数平滑法 一次指数平滑法是利用前一期的预测值 F t 代替 x t n 得到预测的通式,即: F t1xt (1)F t 回总目录 回本章目录 由一次指数平滑法的通式...... [编辑 本段 ...
- spss三次指数平滑_15.2.2 指数平滑模型的SPSS操作(1)
15.2.2 指数平滑模型的SPSS操作(1) 在SPSS Statistics数据编辑器窗口中建立指数平滑模型的具体操作步骤如下. 1)在菜单栏中选择"分析"|"预测 ...
- 时间序列挖掘-预测算法-三次指数平滑法(Holt-Winters)——三次指数平滑算法可以很好的保存时间序列数据的趋势和季节性信息...
from:http://www.cnblogs.com/kemaswill/archive/2013/04/01/2993583.html 在时间序列中,我们需要基于该时间序列当前已有的数据来预测其在 ...
- 预测算法-三次指数平滑法(Holt-Winters)
指数平滑 一次指数平滑 一次指数平滑法是一种特殊的加权平均法,对本期观察值和本期预测值赋予不同的权重,求得下一期预测值的方法.这种方法既不需要存储全部历史数据,也不需要存储一组数据,从而可以大大减少数 ...
最新文章
- 解读:欧盟委员会2021年《人工智能法》提案
- 如何利用脚本方法清除文本框中汉字,从而保留英文字母和数字等
- 【Python CheckiO 题解】Flatten a List
- ivx中字体显示_html-中文字体在CSS中的显示(Unicode编码)(转载)
- 今天,我背完了考研5500词!!!
- 软件汉化工具:eXeScope
- ansys通过扫掠(sweep)方法划分网格的方法
- 第七周作业-任务分解
- 【历史上的今天】9 月 3 日:谷歌发布 Android 10;微软收购诺基亚;eBay 诞生
- 功能安全专题之端到端(E2E) 的通信保护
- 《平衡掌控者》笔记(结)
- 本地电脑如何搭建web网站,并发布到公网访问?1-2
- D3临摹作业_分词与词云可视化(西安交大国家艺术基金数据可视化培训第28天)
- matlab 零速检测,一种基于车辆零速检测的惯性导航误差修正方法与流程
- 计算机counta函数怎么用,Excel函数公式:Counta函数的多功能应用~
- python 爬取 世界空气污染:空气质量指数历史数据
- 如何接入银联在线支付网关
- 解决EXP-00003问题
- vue项目实现文件下载中心:下载、取消下载、列表展示
- 关于对目前所学习到的测绘专业软件的评价
热门文章
- poj2249Binomial Showdown
- java制作手机投射电脑_将Android手机投影到Win10计算机的最简单教程
- Problem A: 零起点学算法93——矩阵转置
- 平台交叉打包 GYP
- 动感影集制作音乐相册,超简单实用的方法!风靡QQ空间、微信、抖音
- 共阴极数码管,学号显示实验
- Java exception was raised during method invocation
- nodejs追加写入日志文件
- 生物竞赛初赛报名已截止!各省往届真题超全汇总,建议收藏
- jpress连接数据库mysql_通过Tomcat jpress连接不到数据库