Как согласовать регрессионную модель с ошибками ARIMA для сезонно скорректированного компонента временного ряда (в R)?
Я хочу сделать эти две вещи (в сочетании) с временным рядом T:
- спрогнозировать сезонно скорректированный компонент T (STL используется для разложения) и "добавить обратно" сезонность (я предполагаю, что сезонная составляющая неизменна, поэтому я использую наивный метод для сезонной составляющей)
- соответствовать модели регрессии с ошибками ARIMA (экзогенные регрессоры включены в формулу)
Другими словами, я хочу получать прогнозы с использованием сезонно скорректированного компонента T, интегрируя внешний предиктор и "добавляя" сезонность.
Я могу выполнять эти две операции по отдельности, но не могу заставить их работать вместе
Вот несколько примеров игрушек:
Сначала загрузите библиотеки и данные:
library(forecast)
library(tsibble)
library(tibble)
library(tidyverse)
library(fable)
library(feasts)
library(fabletools)
us_change <- readr::read_csv("https://otexts.com/fpp3/extrafiles/us_change.csv") %>%
mutate(Time = yearquarter(Time)) %>%
as_tsibble(index = Time)
Пример подгонки и прогноза с учетом сезонной составляющей T:
model_def = decomposition_model(STL,
Consumption ~ season(window = 'periodic') + trend(window = 13),
ARIMA(season_adjust ~ PDQ(0,0,0)),
SNAIVE(season_year),
dcmp_args = list(robust=TRUE))
fit <- us_change %>% model(model_def)
report(fit)
forecast(fit, h=8) %>% autoplot(us_change)
Пример регрессионной модели с ошибками ARIMA (доход как предиктор):
model_def = ARIMA(Consumption ~ Income + PDQ(0,0,0))
fit <- us_change %>% model(model_def)
report(fit)
us_change_future <- new_data(us_change, 8) %>% mutate(Income = mean(us_change$Income))
forecast(fit, new_data = us_change_future) %>% autoplot(us_change)
Эти примеры работают, но я хотел бы сделать что-то вроде этого:
model_def = decomposition_model(STL,
Consumption ~ season(window = 'periodic') + trend(window = 13),
ARIMA(season_adjust ~ Income + PDQ(0,0,0)),
SNAIVE(season_year),
dcmp_args = list(robust=TRUE))
fit <- us_change %>% model(model_def)
report(fit)
us_change_future <- new_data(us_change, 8) %>% mutate(Income = mean(us_change$Income))
forecast(fit, new_data = us_change_future) %>% autoplot(us_change)
Я получаю этот вывод в консоли:
> fit <- us_change %>% model(model_def)
Warning message:
1 error encountered for model_def
[1] object 'Income' not found
>
> report(fit)
Series: Consumption
Model: NULL model
NULL model>
Итак, я попытался сделать это в decoposition_model:
model_def = decomposition_model(STL,
Consumption ~ season(window = 'periodic') + trend(window = 13),
ARIMA(season_adjust ~ us_change$Income + PDQ(0,0,0)),
SNAIVE(season_year),
dcmp_args = list(robust=TRUE))
С подгонкой проблем нет, но теперь я получаю ошибку в прогнозе:
> forecast(fit, new_data = us_change_future) %>% autoplot(us_change)
Error in args_recycle(.l) : all(lengths == 1L | lengths == n) is not TRUE
In addition: Warning messages:
1: In cbind(xreg, intercept = intercept) :
number of rows of result is not a multiple of vector length (arg 2)
2: In z[[1L]] + xm :
longer object length is not a multiple of shorter object length
Что я делаю неправильно?
1 ответ
Здесь нет ничего плохого в вашем коде, просто я не думал, что люди будут делать decomposition_model()
. Я обновил метод моделирования декомпозиции, включив в него экзогенные регрессоры, чтобы их можно было использовать в компонентных моделях (https://github.com/tidyverts/fabletools/commit/8dd505f6378327b8e93b8440ec17ecf9badf2561). Если вы обновите пакет, ваша первая попытка моделирования будет работать нормально.
Что касается того, почему вторая попытка не сработала, метод прогнозирования находит us_change$Income и использует это в качестве экзогенного регрессора для будущих прогнозов. Это значение имеет длинуus_change
, что не соответствует длине us_change_future
, что приводит к (запутанной) ошибке.
Реплекс:
library(tidyverse)
library(tsibble)
library(fable)
library(feasts)
us_change <- readr::read_csv("https://otexts.com/fpp3/extrafiles/us_change.csv") %>%
mutate(Time = yearquarter(Time)) %>%
as_tsibble(index = Time)
model_def = decomposition_model(STL,
Consumption ~ season(window = 'periodic') + trend(window = 13),
ARIMA(season_adjust ~ Income + PDQ(0,0,0)),
SNAIVE(season_year),
dcmp_args = list(robust=TRUE))
fit <- us_change %>% model(model_def)
report(fit)
#> Series: Consumption
#> Model: STL decomposition model
#> Combination: season_adjust + season_year
#>
#> ========================================
#>
#> Series: season_adjust
#> Model: LM w/ ARIMA(1,0,2) errors
#>
#> Coefficients:
#> ar1 ma1 ma2 Income intercept
#> 0.6922 -0.5777 0.1975 0.2035 0.5993
#> s.e. 0.1163 0.1305 0.0755 0.0462 0.0883
#>
#> sigma^2 estimated as 0.3234: log likelihood=-157.39
#> AIC=326.77 AICc=327.24 BIC=346.16
#>
#> Series: season_year
#> Model: SNAIVE
#>
#> sigma^2: 0
us_change_future <- new_data(us_change, 8) %>% mutate(Income = mean(us_change$Income))
forecast(fit, new_data = us_change_future) %>% autoplot(us_change)
Создано 9.10.2019 пакетом REPEX (v0.2.1)