简体   繁体   English

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

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

So far I was using this method from professor Hyndman when I had multiple time series to forecast. 到目前为止,当我有多个时间序列进行预测时,我正在使用Hyndman教授的这种方法。 But when I have a large number of ts it is fairly slow. 但是当我有大量的ts时,它相当慢。

Now I am trying to use apply() function as follows 现在我尝试使用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)

It seem that it is working well but when I use for loop as following: 这似乎是它运作良好,但是当我使用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
}

I get different point forecast. 我得到了不同的预测点。 What is the reason? 是什么原因?

Edit: I fixed it by changing the "fc_func" function. 编辑:我通过更改“fc_func”函数修复它。 Now it returns the same results as for loop but now it is also as slow as for loop 现在它返回的结果相同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)

For debugging i've added some prints in the apply. 为了调试,我在apply中添加了一些打印。 The interesting one is the class(y) 有趣的是班级(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)

All the y arrive as numeric at apply. 所有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

This is different in the for-loop: 这在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
}

here the variables are delivered as ts to auto.arima. 这里变量以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

I guess this causes the differences, because when i reduce retail to a simple matrix by 我想这会导致差异,因为当我将零售减少到一个简单的矩阵时

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

and run the for-loop again i get perfectly the same results as in the apply version. 并再次运行for循环我得到与apply版本完全相同的结果。

all.equal(frc, fcast1)

So i guess you have to transform the variables to ts within the the fc_func again before sending them into the forecast function. 所以我想你必须在将变量发送到预测函数之前再次将变量转换为fc_func中的ts。

As a workaround (and because i had no idea how to transform y into the desired ts object) you could use an sapply version: 作为一种解决方法(因为我不知道如何将y转换为所需的ts对象),您可以使用sapply版本:

fc_func2 <- function(y){

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

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

It should give the desired values, but im not sure if it is any faster than the loop-version. 它应该给出所需的值,但我不确定它是否比loop-version更快。

The issue is apply() manipulating the class of the time series object, retail . 问题是apply()操纵time series对象的类, 零售 Being the rudimentary version of the apply family, apply() is best used for simple matrix objects. 作为apply系列的基本版本, apply()最适用于简单的矩阵对象。 It will cast its input to a matrix object with as.matrix() when called and hence why apply() is often warned not to be used for data frames. 它会在调用时将其输入转换为带有as.matrix()的矩阵对象,因此通常会警告apply()不要用于数据帧。

Per the ?apply docs: 根据?apply docs:

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 (eg, a data frame) or via as.array 如果X不是数组而是具有非空昏暗值的类的对象(例如数据帧),则应用尝试通过as.matrix将其强制转换为数组(如果它是二维的)(例如,数据)框架)或通过as.array

So apply does not preserve the class object of its input before being processed into fc_func : 因此apply在处理成fc_func之前不会保留其输入的类对象:

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

One can see this when using sapply which runs just as slow as for and in removing dimnames returns exactly as for loop: 使用的时候可以看到这个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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM