auto.arima 与 arima.sim

机器算法验证 r 有马 模型选择
2022-04-05 14:32:00

我注意到 auto.arima 经常给出与模拟不同的模型arima.sim,所以我粗略地测试了它:

results = c(0, 0)
for(i in 1:1000){
  m = auto.arima(
    arima.sim(model = list(order = c(2,0,0), ar = c(0.3, 0.5)), n = 100)
  ) 
  if(!"ma1" %in% names(m$coef)){
    if("ar2" %in% names(m$coef)){
      results[1] = results[1] + 1
    }else{
      results[2] = results[2] + 1
    }
  }else{
    results[2] = results[2] + 1
  }
}
results
[1] 265 735

在这个测试中,auto.arima只有 36% 的时间是正确的。

我搞砸了auto.arimaor的设置arima.sim吗?或者,模型是否auto.arima以某种方式等效?

- - 编辑 - -

我将 arima.sim 上的样本大小提高到n=1000,而 auto.arima 在 60% 的时间里是正确的。

所以...我应该不使用auto.arima,除非我有大量样本,或者模型是由 确定的auto.arima,尽管与模拟不同,但在某种程度上是等效的?

1个回答

不,您的代码没有出错(我可以看到)。

不幸的是,自动 ARIMA 模型选择很少恢复用于模拟输入数据的模型。这仅仅是因为与要估计的参数数量相比,通常数据很少。毕竟,我们不能只计算真实数据生成过程使用的两个 AR 参数——auto.arima()搜索许多不同的可能模型。如果季节性可能是一个问题,那么可能的模型数量会进一步增加。

我一直有一个挥之不去的怀疑,ARIMA 受欢迎的主要原因不是因为它在建模实时序列方面做得很好,而是因为它是一个可以实际证明数学定理的时间序列模型。(作为替代方案,指数平滑过去主要是一种启发式方法,并且仅在大约 15 年前通过状态空间模型建立在坚实的数学基础上。)Makridakis 对原始预测竞争的描述加强了我的这种怀疑- ARIMA 方法已经表现不佳 - 被统计学家接受(Hyndman,2020,IJF - 非常推荐):

许多讨论者似乎都迷恋于 ARIMA 模型。... 有时,讨论退化为质疑作者的能力。

此外,似乎很少有真正令人信服的移动平均过程的真实例子如果您将搜索仅限于 AR(p) 模型,auto.arima()则可能会更好地找到真正的模型。当然,即使那样,参数也只会被估计并且与真实值不同。

请注意,我不认为这是auto.arima()实施的缺点。恰恰相反。我更信任的拟合 ARIMA 模型的方法很少。Rob Hyndman 可能是对此最了解的人。例如,我不会认为 Box-Jenkins 方法会更好。

无论如何,您所做的是一个很好的练习,可以了解 ARIMA 拟合的缺点。我希望更多的时间序列分析和预测课程能包含这么简短的谦逊课程。我鼓励您多尝试一下您的方法,可能包括季节性模型、其他 AR 甚至 MA 参数,或者允许或禁止 Box-Cox 转换。


说了这么多,为什么要拟合 ARIMA 模型?大多数人都会希望这样做来进行预测。(是的,还有其他动机。)在这种情况下,扩展您的实验以包括预测步骤是有意义的。这就是我在下面所做的。我使用 模拟 100(或 1000)个历史数据点加上 50 个保留数据点arima.sim(),然后使用 拟合 ARIMA 模型auto.arima(),使用 计算 90% 区间预测forecast(),计算这些区间预测覆盖真实值的频率,并最终绘制出预测范围的平均覆盖率。结果和代码如下。在我看来,至少区间预测“足够好”。(历史长度为 100 的情节中明显的上升趋势看起来很有趣。我不知道它来自哪里。)

覆盖率_100

覆盖率_1000

library(forecast)
n_sims <- 1000
n_history <- 100
n_forecast <- 50
true_model <- list(ar=c(0.3,0.5))
confidence_level <- 0.9
hit <- matrix(NA,nrow=n_sims,ncol=n_forecast)

pb <- winProgressBar(max=n_sims)
for ( ii in 1:n_sims ) {
    setWinProgressBar(pb,ii,paste(ii,"of",n_sims))
    set.seed(ii)    # for reproducibility
    actuals <- arima.sim(model=true_model,n=n_history+n_forecast)
    model <- auto.arima(actuals[1:n_history])
    fcst <- forecast(model,h=n_forecast,level=confidence_level)

    hit[ii,] <- fcst$lower<=tail(actuals,n_forecast) & tail(actuals,n_forecast)<=fcst$upper
}
close(pb)

coverage <- apply(hit,2,sum)/n_sims
plot(coverage,xlab="Forecast horizon",ylab="Coverage",las=1,
    main=paste("History length:",n_history),
    type="o",pch=19,ylim=range(c(coverage,confidence_level)))
abline(h=confidence_level,lwd=2,col="red")

您可能想要探索的另一种选择是将期望点预测与各种可能的“最佳”情况进行比较,例如:

  • 如果已知真实模型(包括参数),则针对点预测
  • 如果真实模型和 Box-Cox 变换已知,则针对点预测,但需要估计参数
  • 如果真实模型已知,则针对点预测,但需要估计 Box-Cox 变换和参数
  • 如果auto.arima()只能在 AR(p) 模型中选择p=0,,5或者
  • ...