Пакетное прогнозирование;используя функцию apply () вместо цикла for.Функция apply () дает другой точечный прогноз - PullRequest
0 голосов
/ 02 октября 2018

До сих пор я использовал этот метод профессора Хиндмана, когда у меня было несколько временных рядов для прогноза.Но когда у меня большое количество 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 голосов
/ 02 октября 2018

Проблема заключается в apply() манипулировании классом объекта time series, retail .Будучи элементарной версией семейства apply , apply() лучше всего использовать для простых матричных объектов.Он будет преобразовывать свои входные данные в матричный объект с as.matrix() при вызове и, следовательно, почему apply() часто предупреждают, что его не следует использовать для фреймов данных.

По ?apply документам:

Если X не массив, а объект класса с ненулевым значением dim (например, фреймом данных), применитепытается привести его к массиву с помощью 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
0 голосов
/ 02 октября 2018

Для отладки я добавил несколько отпечатков в заявке.Интересным является класс (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)

Так что, я думаю, вам нужно снова преобразовать переменные в ts внутри fc_func перед отправкой их в функцию прогноза.

В качестве обходного пути (и потому что японятия не имел, как преобразовать y в нужный объект ts), вы могли бы использовать более удобную версию:

fc_func2 <- function(y){

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

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

Она должна давать желаемые значения, но я не уверен, что она быстрее, чем версия цикла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...