\[ ARIMA(p,d,q)(P, D, Q)_{m} \] (p,d,q)为非季节部分,(P, D, Q)_{m}为季节部分,m = 每年的观测数量
比如,一个\(ARIMA(1,1,1)(1,1,1)_4\)模型(不含常数)对应的是季节数据(m=4),可以表示为 \[ (1 - \phi_{1}B)~(1 - \Phi_{1}B^{4}) (1 - B) (1 - B^{4})y_{t} = (1 + \theta_{1}B)~ (1 + \Theta_{1}B^{4})\varepsilon_{t}. \] 即季节性项与非季节性项相乘以后得到。
AR 或者 MA 模型中的季节性特征其实可以从偏自相关图和自相关图中的季节性延迟中被观察到。
例如 ARIMA(0,0,0)(0,0,1)_12模型会显示出: a) 自相关图中延迟期数为 12 上有一个明显突起,但是没有其他明显的突起; b) 偏自相关图中季节性延迟(即当延迟为12,24,36,…)上出现指数性的衰减.
一个ARIMA(0,0,0)(1,0,0)_12: a) 自相关图中季节性延迟上出现指数型衰减; b) 偏自相关图中延迟为 12 上的一个明显突起。
library(fpp2)
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## ── Attaching packages ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── fpp2 2.4 ──
## ✓ ggplot2 3.2.1 ✓ fma 2.4
## ✓ forecast 8.13 ✓ expsmooth 2.3
##
#library(feasts)
#library(fabletools)
#eu_retail <- as_tsibble(fpp2::euretail)
#eu_retail %>% autoplot(value) + ylab("Retail index") + xlab("Year")
autoplot(euretail) + ylab("零售指数") + xlab("年份") +
theme(text = element_text(family = "STHeiti"))+
theme(plot.title = element_text(hjust = 0.5))
### 季节性差分
#数据显然是非平稳的,并且拥有一些季节性的特征,因此我们先对进行季节性差分,季节性差分数据如图8.17所示。
euretail %>% diff(lag=4) %>% ggtsdisplay()
#由于非平稳性仍然存在,我们继续进行一阶差分,
euretail %>% diff(lag=4) %>% diff() %>% ggtsdisplay()
经过了差分变换,通过自相关图和偏自相关图来找到合适的 ARIMA 模型。 ACF图中在延迟为1时的突起显示出数据包含非季节性 MA(1) 的成分,而延迟为4的突起则显示出季节性 MA(1)的成分。 因此,ARIMA(0,1,1)(0,1,1)_4 模型开始,这表明数据经过了一次季节性差分和一次一阶差分,同时包含季节性和非季节性的 MA(1) 成分。
usmelec_stl <- stl(usmelec,t.window=13, s.window="periodic", robust=TRUE)
#head(usmelec)
usmelec_stl_s <- usmelec_stl$time.series[,"seasonal"]
usmelec_stl_t <- usmelec_stl$time.series[,"trend"]
usmelec_stl_r <- usmelec_stl$time.series[,"remainder"]
F_T <- max(0,1-var(usmelec_stl_r)/var(usmelec_stl_t+usmelec_stl_r))
#F_T
F_S <- max(0,1-var(usmelec_stl_r)/var(usmelec_stl_s+usmelec_stl_r))
F_S
## [1] 0.7864134
如果F_S<0.64,不需要进行季节性差分,否则需要进行一次季节性差分。
usmelec %>% log() %>% nsdiffs()
## [1] 1
usmelec %>% log() %>% diff(lag=12) %>% ndiffs()
## [1] 1
usmelec %>% log() %>% diff(lag=12) %>% diff() %>% ndiffs()
## [1] 0
由于nsdiffs()函数返回1,说明需要进行一次季节性差分,我们对季节差分后的数据运行ndiffs()函数。这些函数的运行结果说明我们应该进行一次季节性差分和一次一步差分。
euretail %>%
Arima(order=c(0,1,1),seasonal=c(0,1,1)) %>%
residuals() %>%
ggtsdisplay()
自相关图和偏自相关图都在延迟为2的地方出现了明显的突起,在延迟为3的地方出现了较为明显的突起,这反映出有一些额外的非季节性项需要被补充进入模型。
fit1 <- euretail %>% Arima(order=c(0,1,2),seasonal=c(0,1,1))
fit2 <- euretail %>% Arima(order=c(0,1,3),seasonal=c(0,1,1))
rbind(fit1$aicc,fit2$aicc)
## [,1]
## [1,] 74.26992
## [2,] 68.39031
ARIMA(0,1,2)(0,1,1)_4 模型的AICc值 为 74.26,而 ARIMA(0,1,3)(0,1,1)_4 模型的AICc值为 68.39。 因此,我们最后选择了 ARIMA(0,1,3)(0,1,1)_4模型。
fit3 <- Arima(euretail,order=c(0,1,3),seasonal=c(0,1,1))
checkresiduals(fit3)
##
## Ljung-Box test
##
## data: Residuals from ARIMA(0,1,3)(0,1,1)[4]
## Q* = 0.51128, df = 4, p-value = 0.9724
##
## Model df: 4. Total lags used: 8
所有残差都在显著性临界值内,因此它们类似于白噪声。Ljung-Box 检验也显示残差之间不存在自相关性。
fit3 %>% forecast(h=12) %>% autoplot()
### auto.arima()自动确定模型 我们可以用auto.arima()来完成这里大部分的工作,它的结果如下所示:
fit.arima <- auto.arima(euretail)
fit.arima
## Series: euretail
## ARIMA(0,1,3)(0,1,1)[4]
##
## Coefficients:
## ma1 ma2 ma3 sma1
## 0.2630 0.3694 0.4200 -0.6636
## s.e. 0.1237 0.1255 0.1294 0.1545
##
## sigma^2 estimated as 0.156: log likelihood=-28.63
## AIC=67.26 AICc=68.39 BIC=77.65
# 澳大利亚皮质类固醇药物销量(每月每百万剂)
#图中方差随着销量水平增加而略微增加,因此我们运用log来平稳定方差。
library(fpp2)
head(h02)
## Jul Aug Sep Oct Nov Dec
## 1991 0.429795 0.400906 0.432159 0.492543 0.502369 0.602652
lh02 <- log(h02)
cbind("H02 sales (million scripts)" = h02,
"Log H02 sales"=lh02) %>%
autoplot(facets=TRUE) + xlab("年份") + ylab("")
### 季节性差分 数据拥有很强的季节性,并且显然非平稳,因此我们使用季节性差分 不清楚是否应该再做一次差分,我们决定不继续差分
lh02 %>% diff(lag=12) %>%
ggtsdisplay(xlab="年份",main="季节性差分后的H02药物销量")
在季节性差分后的数据的图中,我们发现偏自相关图在延迟为 12 和 24 的地方存在突起,然而在自相关图中并不存在季节性延迟的突起。 这有可能暗示出模型应含有季节性 AR(2) 的部分。在非季节性的延迟中,偏自相关图有三个明显突起,显示出可能存在的 AR(3) 部分。自相关图并没有任何简单模型的特征,因此我们不作考虑。
确定了数据对应的一个可能的模型 ARIMA(3,0,0)(2,1,0)_12 我们用这个模型以及它的一些衍生模型进行拟合,并且计算出了各自的AICc值
注意: 当我们使用 AICc 值来比较模型时,所有的模型应该是\(\color{red}{同阶差分}\)的,这一点很重要。
fit1 <- lh02 %>% Arima(order=c(3,0,1),seasonal=c(0,1,2))
fit2 <- lh02 %>% Arima(order=c(3,0,1),seasonal=c(1,1,1))
fit3 <- lh02 %>% Arima(order=c(3,0,1),seasonal=c(0,1,1))
fit4 <- lh02 %>% Arima(order=c(3,0,1),seasonal=c(2,1,0))
fit5 <- lh02 %>% Arima(order=c(3,0,0),seasonal=c(2,1,0))
fit6 <- lh02 %>% Arima(order=c(3,0,2),seasonal=c(2,1,0))
fit7 <- lh02 %>% Arima(order=c(3,0,1),seasonal=c(1,1,0))
rbind(fit1$aicc,fit2$aicc,fit3$aicc,fit4$aicc,fit5$aicc,fit6$aicc,fit7$aicc)
## [,1]
## [1,] -485.4754
## [2,] -484.2511
## [3,] -483.6674
## [4,] -476.3086
## [5,] -475.1230
## [6,] -474.8826
## [7,] -463.3951
在这些模型中,ARIMA(3,0,1)(0,1,2)_12模型拥有最小的AICc值,因而是最优模型
Box-Cox transformation parameter. If lambda=“auto”, then a transformation is automatically selected using BoxCox.lambda. The transformation is ignored if NULL. Otherwise, data transformed before model is estimated \[ \begin{align*} &\text{Box-Cox transformation}\\ & y(\lambda) =\frac{y^\lambda - 1}{\lambda} , \lambda != 0 \\ & y(\lambda) =log(y) , \lambda = 0 \\ \end{align*} \]
(fit <- Arima(h02,order=c(3,0,1),seasonal=c(0,1,2),lambda=0))
## Series: h02
## ARIMA(3,0,1)(0,1,2)[12]
## Box Cox transformation: lambda= 0
##
## Coefficients:
## ar1 ar2 ar3 ma1 sma1 sma2
## -0.1603 0.5481 0.5678 0.3827 -0.5222 -0.1768
## s.e. 0.1636 0.0878 0.0942 0.1895 0.0861 0.0872
##
## sigma^2 estimated as 0.004278: log likelihood=250.04
## AIC=-486.08 AICc=-485.48 BIC=-463.28
checkresiduals(fit,lag=36)
##
## Ljung-Box test
##
## data: Residuals from ARIMA(3,0,1)(0,1,2)[12]
## Q* = 50.712, df = 30, p-value = 0.01045
##
## Model df: 6. Total lags used: 36
fit_auto <- auto.arima(h02,stepwise = TRUE,seasonal = TRUE,ic='aicc',lambda=0)
fit_auto
## Series: h02
## ARIMA(2,1,1)(0,1,2)[12]
## Box Cox transformation: lambda= 0
##
## Coefficients:
## ar1 ar2 ma1 sma1 sma2
## -1.1358 -0.5753 0.3683 -0.5318 -0.1817
## s.e. 0.1608 0.0965 0.1884 0.0838 0.0881
##
## sigma^2 estimated as 0.004278: log likelihood=248.25
## AIC=-484.51 AICc=-484.05 BIC=-465
接下来我们将会使用自动的 ARIMA 算法,在默认设置下,auto.arima()函数返回了 ARIMA(2,1,1)(0,1,2)_12模型。然而,这个模型同样没有通过 Ljung-Box 检验。有时候找到一个通过所有检验的模型是不可能的。
包含最近两年数据的测试集对之前拟合出的模型进行比较。 这些模型中没有一个能够通过所有的残差检验,在实际应用中,我们仍然会使用我们找到的最优模型,即使它不能通过所有的检验。
train <- window(h02, start=c(1991,7),end=c(2006,6)) test <- window(h02, start=c(2006,7),end=c(2008,6))
a1 <- fit1 %>% forecast(h=12) %>% accuracy()
a2 <- fit2 %>% forecast(h=12) %>% accuracy()
a3 <- fit3 %>% forecast(h=12) %>% accuracy()
a4 <- fit4 %>% forecast(h=12) %>% accuracy()
a5 <- fit5 %>% forecast(h=12) %>% accuracy()
a6 <- fit6 %>% forecast(h=12) %>% accuracy()
a7 <- fit7 %>% forecast(h=12) %>% accuracy()
a8 <- fit_auto %>% forecast(h=12) %>% accuracy()
rbind(a1[2],a2[2],a3[2],a4[2],a5[2],a6[2],a7[2],a8[2])
## [,1]
## [1,] 0.06245679
## [2,] 0.06269911
## [3,] 0.06321256
## [4,] 0.06445510
## [5,] 0.06509306
## [6,] 0.06441930
## [7,] 0.06751302
## [8,] 0.05015710
ARIMA(2,1,1)(0,1,2) _12模型的预测(拥有最小的均方根误差,并且在只进行季节性差分的模型中拥有最优的AICc值)
h02 %>%
Arima(order=c(2,1,1),seasonal=c(0,1,2),lambda=0) %>%
forecast() %>%
autoplot() +
ylab("H02销量(百万剂)") + xlab("年份")+
theme(text = element_text(family = "STHeiti"))+
theme(plot.title = element_text(hjust = 0.5))
https://zhuanlan.zhihu.com/p/88442615
ARIMA和ETS都是时间序列分析中的有效工具,在实践中经常将两者进行比较。
library(fpp2)
head(qcement)
## Qtr1 Qtr2 Qtr3 Qtr4
## 1956 0.465 0.532 0.561 0.570
## 1957 0.529 0.604
#cement <- window(qcement, start=1988)
#train <- window(cement, end=c(2007,4))
train <- window(qcement, start=c(1988,1),end=c(2007,4))
(fit.arima <- auto.arima(train))
## Series: train
## ARIMA(1,0,1)(2,1,1)[4] with drift
##
## Coefficients:
## ar1 ma1 sar1 sar2 sma1 drift
## 0.8886 -0.2366 0.081 -0.2345 -0.8979 0.0105
## s.e. 0.0842 0.1334 0.157 0.1392 0.1780 0.0029
##
## sigma^2 estimated as 0.01146: log likelihood=61.47
## AIC=-108.95 AICc=-107.3 BIC=-92.63
checkresiduals(fit.arima)
##
## Ljung-Box test
##
## data: Residuals from ARIMA(1,0,1)(2,1,1)[4] with drift
## Q* = 3.3058, df = 3, p-value = 0.3468
##
## Model df: 6. Total lags used: 9
# 进行预测
a1 <- fit.arima %>% forecast(h = 4*(2013-2007)+1) %>% accuracy(qcement)
a1[,c("RMSE","MAE","MAPE","MASE")]
## RMSE MAE MAPE MASE
## Training set 0.1001195 0.07988903 4.372443 0.5458078
## Test set 0.1996098 0.16882205 7.719241 1.1534049