背景

指数平滑是在 20 世纪 50 年代后期提出的,并激发了一些十分成功的预测方法。使用指数平滑方法生成的预测是过去观测值的加权平均值,并且随着过去观测值离预测值距离的增大,权重呈指数型衰减。换句话说,观察值越近,相应的权重越高。该框架能够快速生成可靠的预测结果,并且适用于广泛的时间序列,这是一个巨大的优势并且对于工业应用来说非常重要。

本文主要学习四种常见的指数平滑方法:

  • Exponential smoothing:针对「没有趋势和季节性」的序列

    一次指数平滑,从最邻近到最早的数据点的权重呈现指数型下降的规律。

  • Holt exponential smoothing:针对「有趋势但没有季节性」的序列

    二次指数平滑,通过引入一个额外的系数来解决指数平滑无法应用于具有趋势性数据的问题。

  • Holt-Winters exponential smoothing:针对「有趋势且有季节性」的序列

    三次指数平滑,通过再次引入一个新系数的方式同时解决了 Holt exponential smoothing 无法解决具有季节性变化数据的不足。

所有的指数平滑法需要更新上一时间点的计算结果,并使用当前时间点的数据中包含的新信息。它们通过”混合“新信息和旧信息来实现,而相关的新旧信息的权重由一个可调整的参数来控制。

Exponential smoothing

一次指数平滑的递推公式如下

其中 表示时间序列第 时间点对应的观测值, 表示第 个时间点平滑后的值;衰减因子 可以控制对历史数据的遗忘程度,当 接近 1 时表示只保留当前时间点的值。

递归公式展开可以得到以下形式:

从上式即可看出指数平滑考虑所有历史观测值对当前值的影响,但影响程度随时间增长而减小。对应的时间序列预测公式:

其中 表示最后一个时间点对应的值; 表示下个预测值。

Holt exponential smoothing

指数平滑考虑的是数据的 baseline,二次指数平滑在此基础上将「趋势」作为一个分量考虑。

趋势,即斜率定义: ,其中 坐标轴的变化值, 表示 值变换。

二次指数平滑保留并更新两个量的状态:「平滑后的信号」「平滑后的趋势」。公式如下:

从上式可以看出仅是在一次指数平滑的基础上添加了趋势项,趋势也使用一次指数平滑进行处理。对应的时间序列预测公式:

Holt-Winters exponential smoothing

二次指数平滑考虑了序列的 baseline 和趋势性,三次指数平滑在此基础上引入季节性分量考虑时间序列周期性模式。

季节性(周期性)是指一个序列在每个固定的时间间隔中都出现某种重复的模式,令 表示周期长度。

Holt-Winters 指数平滑方法有两种不同的季节性组成部分:

  • 当季节变化在该时间序列中大致保持不变时,通常选择加法模型;

  • 当季节变化与时间序列的水平成比例变化时,通常选择乘法模型;

加法模型

计算公式如下:

其中 表示周期性分量,第三个公式中 表示 。对应的预测公式如下:

乘法模型

计算公式如下:

对应的预测公式为

Python 实践

为了节约时间,本文中直接采用 「statsmodels」 库中实现的 Holter-Winters 方法进行测试。

采用一周的时间序列数据为例,如下图所示

先将时间序列进行分解看下趋势项和周期项:

from statsmodels.tsa.seasonal import seasonal_decompose
from statsmodels.tsa.holtwinters import SimpleExpSmoothing, ExponentialSmoothing

decompose_result = seasonal_decompose(data, model="multiplicative", period=288)

可视化结果如下

一次指数平滑

## 一次指数平滑
data["1exp"] = SimpleExpSmoothing(data["value"]).fit(smoothing_level=alpha).fittedvalues

可视化结果如下

二次指数平滑

data["2exp_add"] = ExponentialSmoothing(data["value"], trend="add", seasonal=None).fit().fittedvalues
data["2exp_mul"] = ExponentialSmoothing(data["value"], trend="mul", seasonal=None).fit().fittedvalues

可视化结果如下

三次指数平滑

data["3exp_add"] = ExponentialSmoothing(data["value"], trend="add", seasonal="add", seasonal_periods=288).fit().fittedvalues
data["3exp_mul"] = ExponentialSmoothing(data["value"], trend="mul", seasonal="mul", seasonal_periods=288).fit().fittedvalues

可视化结果如下

序列预测

取一天数据进行预测,周期为 1D = 288 * 5min;

## 预测
model = ExponentialSmoothing(data["value"], trend="add", seasonal="add", seasonal_periods=288).fit()
pred = model.forecast(288)

可视化结果如下

时间序列的整体预测效果还是不错的,大体上符合趋势 ~

建议阅读:

高考失利之后,属于我的大学本科四年

【资源分享】对于时间序列,你所能做的一切.

【时空序列预测第一篇】什么是时空序列问题?这类问题主要应用了哪些模型?主要应用在哪些领域?

【AI蜗牛车出品】手把手AI项目、时空序列、时间序列、白话机器学习、pytorch修炼

公众号:AI蜗牛车

保持谦逊、保持自律、保持进步

个人微信

备注:昵称+学校/公司+方向

如果没有备注不拉群!

拉你进AI蜗牛车交流群

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐