[英]Batch Forecasting; using apply() function instead of for loop. apply() function gives different point forecast
到目前为止,当我有多个时间序列进行预测时,我正在使用Hyndman教授的这种方法。 但是当我有大量的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)
为了调试,我在apply中添加了一些打印。 有趣的是班级(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)
它应该给出所需的值,但我不确定它是否比loop-version更快。
问题是apply()
操纵time series
对象的类, 零售 。 作为apply系列的基本版本, apply()
最适用于简单的矩阵对象。 它会在调用时将其输入转换为带有as.matrix()
的矩阵对象,因此通常会警告apply()
不要用于数据帧。
根据?apply
docs:
如果X不是数组而是具有非空昏暗值的类的对象(例如数据帧),则应用尝试通过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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.