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

时间:2018-10-02 15:10:46

标签: r for-loop apply forecasting

到目前为止,当我要预测多个时间序列时,我正在使用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”功能对其进行了修复。现在它返回与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)

2 个答案:

答案 0 :(得分:1)

为了调试,我在应用中添加了一些打印件。有趣的是班级(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循环,我得到的结果与Apply版本完全相同。

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)

它应该提供所需的值,但不确定是否比循环版本更快。

答案 1 :(得分:1)

问题是apply()处理time series对象 retail 的类。作为{em> apply 系列的基本版本,apply()最适合用于简单矩阵对象。它将在调用时将其输入转换为带有as.matrix()的矩阵对象,因此为什么经常警告apply()不能用于数据帧。

根据?apply文档:

  

如果X不是数组,而是具有非null暗淡的类的对象   值(例如数据框),尝试将其强制转换为数组   通过as.matrix(如果它是二维的)(例如,数据帧),或者通过   as.array

因此apply在处理为fc_func之前不会保留其输入的类对象:

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

使用sapply运行速度与for一样慢的dimnames并移除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 循环完全相同:

Date-----------    count 

06-01-2017 18.51    1

06-01-2017 19.11    10

20-01-2017 19.55    20

21-01-2017 20.10    30

22-01-2017 20.10    40

23-01-2017 20.10    50

23-01-2017 20.10    60

29-01-2017 21.33    70