[英]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.