移动平均:最简单的平滑时间序列的方法是实现一个无权重的移动平均,常用窗口函数,平滑统计量 St 就是 k 个观察值的均值,St = 1/k * sum(x(t - n)) = S(t - 1) + (xt - x(t - 1)) / k , 0 =< n <= k - 1;当 k 较小时预测的数据平滑效果不明显,而且突出反映了数据最近的变化;当 k 较大时,有较好的平滑效果,但预测的数据存在延迟,最少需要k个值(窗口有限)。
加权移动平均:sum(wn) = 1,St = sum(wn * x(t+1-n)), 1=<n<=k;通常在选择权重因子时,赋予时间序列中最新数据更大权重,减少对旧数据的权重。最少需要 k 个值,且计算复杂。
一次(简单)指数平滑法:lt = α * yt + (1 - α) * l(t-1),α为平滑因子,0 < α < 1;平滑统计值 lt 是当前统计值 yt 与上一时间平滑值 lt-1 的加权平均。简单指数平滑很容易被应用,只要有两个观察值就能计算,α 的选取可采用最小二乘。
一次指数平滑的预测值:
yt为真实值,lt 为平滑值,为预测值;残差:
初始值 α0 和 l0:
对 lt 展开如下(St 即 lt):
简单指数平滑法适用于没有总体趋势的时间序列;如果用来处理有总体趋势的序列,平滑值将往往滞后于原始数据,除非 α 的值接近1,但这样一来就会造成不够平滑。
from statsmodels.tsa.holtwinters import SimpleExpSmoothing y1 = pd.Series(y1) ets1 = SimpleExpSmoothing(y1) r1 = ets1.fit() pre_r = r1.predict(start=len(y1), end=len(y1) + len(y1) // 2) pd.DataFrame({'origin': y1, 'fitted': r1.fittedvalues, 'prediction': pre_r}).plot(legend=True) plt.show()
二次指数平滑:可解决简答指数平滑的问题,能够保留总体趋势信息,因为将指数平滑应用了两次,所以称为二次指数平滑;与简单指数平滑相比,二次指数平滑加入了时间趋势统计量 bt。
lt = α * yt + (1 - α) * (l(t - 1) + b(t - 1)),
bt = β * (lt - l(t - 1)) + (1 - β) * b(t - 1), 0 < α,β < 1
三次指数平滑:将时间序列的季节性这一特征也考虑进去了。季节性代表时间序列数据的趋势,每一个周期重复自身的行为,像任何周期函数一样。“季节”表示行为每隔时间段 m 就自我重复。在自然界中有不同类型的季节性“累加性”(additive) 和 “累乘性“(multiplicative),就像加法和乘法是数学的基本运算。如果每个12月都比每个11月多卖出1000套公寓,这样的季节趋势是“累加性”的。可用绝对增长来表示。如果夏季比冬季多卖出10%的公寓,那么季节趋势在自然中是“累乘性”的。
α 是数据平滑因子, 0 < α < 1;β是趋势平滑因子,0 < β < 1; γ是季节改变平滑因子0 < γ < 1,
k是 (h - 1) / m 的整数部分,m代表季节周期。
from statsmodels.tsa.holtwinters import Holt x2 = np.linspace(0, 99, 100) y2 = pd.Series(0.1 * x2 + 2 * np.random.randn(100)) ets2 = Holt(y2) r2 = ets2.fit() pred2 = r2.predict(start=len(y2), end=len(y2) + len(y2) // 2) pd.DataFrame({ 'origin': y2, 'fitted': r2.fittedvalues, 'pred': pred2 }).plot(legend=True) plt.show()
对三次指数平滑法,必须初始化完整的“季节” Ci 值,可简单地设置为全 1(针对累乘式)或全 0(针对累加式)。只有当序列的长度较短时才需要慎重考虑初始值的选取。
Holt-Winters模型就是三次指数平滑法;所有的指数平滑法都要更新上一时间步长的计算结果,并使用当前时间步长的数据中包含的新信息,通过“混合”新信息和旧信息来实现,而相关的新旧信息的权重由一个可调整的拌和参数来控制。各种方法的不同之处在于它们跟踪的量的个数和对应的拌和参数的个数。三次指数平滑法,功能最强大,既能体现趋势性又能体现季节性,所以三次指数平滑法的参数最多,有三个。
from statsmodels.tsa.holtwinters import ExponentialSmoothing x3 = np.linspace(0, 4 * np.pi, 100) y3 = pd.Series(20 + 0.1 * np.multiply(x3, x3) + 8 * np.cos(2 * x3) + 2 * np.random.randn(100)) ets3 = ExponentialSmoothing(y3, trend='add', seasonal='add', seasonal_periods=25) r3 = ets3.fit() pred3 = r3.predict(start=len(y3), end=len(y3) + len(y3) // 2) pd.DataFrame({ 'origin': y3, 'fitted': r3.fittedvalues, 'pred': pred3 }).plot(legend=True) plt.show()
与ARIMA的关系:线性指数平滑方法可看作 ARIMA 的特例。例如简单指数平滑等价于 ARIMA(0, 1, 1),Holt's linear trend method 等价于 ARIMA(0, 2, 2),而 Damped trend methods 等价于 ARIMA(1, 1, 2) 等。非线性的指数平滑方法则没有对应的 ARIMA 表示。
参考:
Holt-Winters模型原理分析及代码实现(python)_OraYang的博客-CSDN博客_holt-winters