上篇我和小伙伴们分享了简单指数平滑法,简单指数平滑法只能预测那些处于恒定水平和没有季节变动的时间序列,今天和大家分享非恒定水平即有增长或者降低趋势的,没有季节性可相加模型的时间序列预测算法---霍尔特指数平滑法(Holt)。
Holt 指数平滑法估计当前时间的水平和斜率。其平滑水平是由两个参数控制,alpha:估计当前点水平;beta:估计当前点趋势部分斜率。两个参数都介于0-1之间,当参数越接近0,大部分近期的观测值的权值将较小。
我们以1866年到1911年每年女士裙子直径为案例,我们首先录入数据并绘制出该序列:
skirts <- scan("http://robjhyndman.com/tsdldata/roberts/skirts.dat",skip=5) skirtsseries <- ts(skirts,start=c(1866)) plot.ts(skirtsseries)
观察上图可见该序列从1866年的600涨到了1880年的1050,后面又下降到1911年的520,再次使用R中的HoltWinters()进行霍尔特指数平滑预测(gamma=FALSE),并绘出预测和观测值的曲线图,来观看预测结果
skirtsseriesforecasts <- HoltWinters(skirtsseries, gamma=FALSE) plot(skirtsseriesforecasts)
总体看来,预测的效果还不错(黑色为原始序列,红色为预测值),尽管他们对观测值有一点点延迟。同样我们也可以通过变量skirtsseriesforecasts$SSE查看样本内误差平方和
相关预测值如上图,alpha值为0.84;beta预测值为1.0,这些都是非常高的值,充分显示了无论是水平上还是趋势的斜率上,当前值对时间序列上的最近的观测值的依赖关系比较重,这样的结果也符合我们的预期,因为时间序列的水平和斜率在整个时间段内发生了巨大的变化。此外我们可以通过HoltWinters()函数中的“l.start”和“b.start”的参数指定水平和趋势的初始值,常见的设定水平初始值为时间序列的第一个值(608),斜率的初始值则是其第二个值减去第一个值(9),则设定如下:
HoltWinters(skirtsseries, gamma=FALSE, l.start=608, b.start=9)
同样采用forecast包预测未来时间节点的值,假设我们预测未来19期的数据,具体实现和结果展示如下:
library("forecast") skirtsseriesforecasts2 <- forecast.HoltWinters(skirtsseriesforecasts, h=19) plot.forecast(skirtsseriesforecasts2)
上图中预测部分使用蓝色的线条标识出来,深灰色的阴影区域为80%,浅灰色阴影区为95%的预测区间。
为了检验预测效果,我们同样检验延迟1-20阶中的预测误差是否非零自相关,同样继续采用Ljung-Box检验:
acf(skirtsseriesforecasts2$residuals, lag.max=20) Box.test(skirtsseriesforecasts2$residuals, lag=20, type="Ljung-Box")
相关图呈现样本内预测误差在滞后5阶时超过置信边界,其他都为超过,我们认为存在一定的偶尔因素。
Ljung-Box检验时,p =0.4749,意味着置信度只有53%这样的值不足以拒绝“预测误差在1-20阶是非零自相关,则我们接受预测误差在1-20阶是非零自相关的。
同样我们验证测试误差是否符合零均值正态分布,我们画出时间预测误差图和一个附上正态曲线预测误差分布的直方图(这部分借用上次咱自己写的plotForecastErrors函数):
plot.ts(skirtsseriesforecasts2$residuals) source("plotForecastErrors.R") plotForecastErrors(skirtsseriesforecasts2$residuals)
可见预测误差在整个时间段内是方差大致不变的。
由预测误差直方图可见预测误差是零均值的正态分布。