批量预测;使用 apply() 函数而不是 for 循环。 apply() 函数给出不同点的预测

Batch Forecasting; using apply() function instead of for loop. apply() function gives different point forecast

到目前为止,当我有多个时间序列要预测时,我使用的是 Hyndman 教授的 this 方法。但是当我有大量的ts时它是相当慢的。

现在我正在尝试使用 apply() 函数如下

library(forecast)

fc_func <- function(y){
  forecast(auto.arima(y),h=12)$mean
}

retail <- read.csv("https://robjhyndman.com/data/ausretail.csv",header=FALSE)
retail <- ts(retail[,-1],f=12,s=1982+3/12)

  frc<- apply(retail,2 ,fc_func)

它似乎运行良好,但是当我使用 for 循环时,如下所示:

ns <- ncol(retail)
h <- 12
fcast <- matrix(NA,nrow=h,ncol=ns)
for(i in 1:ns){
  fcast[,i] <- forecast(auto.arima(retail[,i]),h=h)$mean
}

我得到不同的点预测。这是什么原因?

编辑: 我通过更改 "fc_func" 函数修复了它。现在它 returns 与 for 循环的结果相同,但现在它也与 for 循环

一样慢
fc_func <- function(x){

ts(x,f=12,s=1982+3/12)->y

 forecast(auto.arima(y),h=12)$mean
}

retail <- read.csv("https://robjhyndman.com/data/ausretail.csv",header=FALSE)
retail <- ts(retail[,-1],f=12,s=1982+3/12)

  frc<- apply(retail,2 ,fc_func)

为了调试,我在应用程序中添加了一些打印件。有趣的是 class(y)

library(forecast)

fc_func <- function(y){
  print(length(y))
  print(class(y))
  #print(y)
  forecast(auto.arima(y),h=12)$mean
}

retail <- read.csv("https://robjhyndman.com/data/ausretail.csv",header=FALSE)
retail <- ts(retail[,-1],f=12,s=1982+3/12)

retail2 = retail

#retail = retail2[1:333,1:42]

frc<- apply(retail,2 ,fc_func)

所有 y 在应用时均以数字形式到达。

> frc<- apply(retail,2 ,fc_func)
[1] 333
[1] "numeric"
[1] 333
[1] "numeric"
[1] 333
[1] "numeric"
[1] 333
[1] "numeric"
[1] 333

这在 for 循环中是不同的:

ns <- ncol(retail)
h <- 12
fcast1 <- matrix(NA,nrow=h,ncol=ns)
for(i in 1:ns){
  print(length(retail[,i]))
  print(class(retail[,i]))
  #print(retail[,i])
  fcast1[,i] <- forecast(auto.arima(retail[,i]),h=h)$mean
}

此处变量作为 ts 传递给 auto.arima。

> for(i in 1:ns){
+   print(length(retail[,i]))
+   print(class(retail[,i]))
+   #print(retail[,i])
+   fcast1[,i] <- forecast(auto.arima(retail[,i]),h=h)$mean
+ }
[1] 333
[1] "ts"
[1] 333
[1] "ts"
[1] 333
[1] "ts"
[1] 333

我想这会导致差异,因为当我将零售减少到一个简单的矩阵时

retail = retail[1:NROW(retail), 1:NCOL(retail)] 

和运行再次使用for循环我得到与应用版本完全相同的结果。

all.equal(frc, fcast1)

所以我猜你必须在 fc_func 中再次将变量转换为 ts,然后再将它们发送到预测函数中。

作为解决方法(因为我不知道如何将 y 转换为所需的 ts 对象),您可以使用 sapply 版本:

fc_func2 <- function(y){

  forecast(auto.arima(retail[,y]),h=12)$mean
}

frc2 <- sapply(1:NCOL(retail), fc_func2)

它应该给出所需的值,但我不确定它是否比循环版本快。

问题是 apply() 操纵 time series 对象 retail 的 class。作为 apply 系列的基本版本,apply() 最适用于简单的矩阵对象。它会在调用时将其输入转换为带有 as.matrix() 的矩阵对象,因此经常警告 apply() 不要用于数据帧。

根据 ?apply 文档:

If X is not an array but an object of a class with a non-null dim value (such as a data frame), apply attempts to coerce it to an array via as.matrix if it is two-dimensional (e.g., a data frame) or via as.array

所以apply在被处理成fc_func之前不保留其输入的class对象:

class(retail)
# [1] "mts"    "ts"     "matrix" 

当使用运行速度与 for 一样慢的 sapply 和删除 dimnames returns 与 for 循环完全相同时,可以看到这一点:

# LOOP VERSION
ns <- ncol(retail)
h <- 12
fcast1 <- matrix(NA,nrow=h,ncol=ns)

for(i in 1:ns) {
  fcast1[,i] <- forecast(auto.arima(retail[,i]), h=h)$mean
}

# SAPPLY VERSION
frc_test <- sapply(retail, fc_func, USE.NAMES = FALSE)
dimnames(frc_test) <- NULL

identical(frc_test, fcast1)
# [1] TRUE