在 R fabletools 中使用滞后的 xregs 时预测行为不一致
Inconsistent forecast behavior when using lagged xregs in R fabletools
这是我作为 issue 打开的一个问题,但没有收到包作者的消息,所以我想我会在这里问这个问题。谢谢!
我注意到在使用滞后的 xreg 进行预测时存在一些不一致之处。具体来说,h <= 滞后期的预测。在生成预测之前,提供给原始模型的历史数据似乎没有添加到新数据中。在下面的示例中,我使用了 fpp3 中的 lag = 2 示例。第一个预测 fc1
与书中生成的预测相同。在第二个预测 fc2
中,我通过将历史广告数据与 insurance_future
中生成的新广告数据绑定来扩充 new_data
。当我这样做时,我在 fc2
和 fc1
中得到了不同的预测。在我看来,fc1
中的预测无法访问历史 (xreg) 数据,因此 TVaderts 在 horizon 的前两个步骤中被视为 NA
。这样对吗?如果是这样,难道不应该像 fc2
中那样包含该数据吗?这可能与。
library(fpp3)
#> ── Attaching packages ──────────────────────────────────────────── fpp3 0.4.0 ──
#> ✓ tibble 3.1.2 ✓ tsibble 1.0.1
#> ✓ dplyr 1.0.6 ✓ tsibbledata 0.3.0
#> ✓ tidyr 1.1.3 ✓ feasts 0.2.1
#> ✓ lubridate 1.7.10 ✓ fable 0.3.1
#> ✓ ggplot2 3.3.3
#> ── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
#> x lubridate::date() masks base::date()
#> x dplyr::filter() masks stats::filter()
#> x tsibble::intersect() masks base::intersect()
#> x tsibble::interval() masks lubridate::interval()
#> x dplyr::lag() masks stats::lag()
#> x tsibble::setdiff() masks base::setdiff()
#> x tsibble::union() masks base::union()
library(fabletools)
library(fable)
library(dplyr)
library(tsibble)
fit <- insurance %>%
# Restrict data so models use same fitting period
# Estimate models
model(
lag2 = ARIMA(Quotes ~ pdq(d = 0) +
TVadverts + lag(TVadverts) +
lag(TVadverts, 2))
)
insurance_future <- new_data(insurance, 20) %>%
mutate(TVadverts = 8)
# Forecast as shown in https://otexts.com/fpp3/lagged-predictors.html
fc1 <- fit %>%
forecast(insurance_future)
# Manually pre-pend historic advert data to future data to ensure presence of
# lagged regressors
fc2 <- fit %>%
forecast(bind_rows(select(insurance, -Quotes), insurance_future)) %>%
filter_index(as.character(min(insurance_future$Month)) ~ .)
print(fc1)
#> # A fable: 20 x 5 [1M]
#> # Key: .model [1]
#> .model Month Quotes .mean TVadverts
#> <chr> <mth> <dist> <dbl> <dbl>
#> 1 lag2 2005 May N(13, 0.23) 13.0 8
#> 2 lag2 2005 Jun N(13, 0.59) 13.0 8
#> 3 lag2 2005 Jul N(13, 0.72) 13.2 8
#> 4 lag2 2005 Aug N(13, 0.72) 13.2 8
#> 5 lag2 2005 Sep N(13, 0.72) 13.2 8
#> 6 lag2 2005 Oct N(13, 0.72) 13.2 8
#> 7 lag2 2005 Nov N(13, 0.72) 13.2 8
#> 8 lag2 2005 Dec N(13, 0.72) 13.2 8
#> 9 lag2 2006 Jan N(13, 0.72) 13.2 8
#> 10 lag2 2006 Feb N(13, 0.72) 13.2 8
#> 11 lag2 2006 Mar N(13, 0.72) 13.2 8
#> 12 lag2 2006 Apr N(13, 0.72) 13.2 8
#> 13 lag2 2006 May N(13, 0.72) 13.2 8
#> 14 lag2 2006 Jun N(13, 0.72) 13.2 8
#> 15 lag2 2006 Jul N(13, 0.72) 13.2 8
#> 16 lag2 2006 Aug N(13, 0.72) 13.2 8
#> 17 lag2 2006 Sep N(13, 0.72) 13.2 8
#> 18 lag2 2006 Oct N(13, 0.72) 13.2 8
#> 19 lag2 2006 Nov N(13, 0.72) 13.2 8
#> 20 lag2 2006 Dec N(13, 0.72) 13.2 8
print(fc2)
#> # A fable: 20 x 5 [1M]
#> # Key: .model [1]
#> .model Month Quotes .mean TVadverts
#> <chr> <mth> <dist> <dbl> <dbl>
#> 1 lag2 2005 May N(14, 0.72) 13.5 8
#> 2 lag2 2005 Jun N(13, 0.72) 13.3 8
#> 3 lag2 2005 Jul N(13, 0.72) 13.2 8
#> 4 lag2 2005 Aug N(13, 0.72) 13.2 8
#> 5 lag2 2005 Sep N(13, 0.72) 13.2 8
#> 6 lag2 2005 Oct N(13, 0.72) 13.2 8
#> 7 lag2 2005 Nov N(13, 0.72) 13.2 8
#> 8 lag2 2005 Dec N(13, 0.72) 13.2 8
#> 9 lag2 2006 Jan N(13, 0.72) 13.2 8
#> 10 lag2 2006 Feb N(13, 0.72) 13.2 8
#> 11 lag2 2006 Mar N(13, 0.72) 13.2 8
#> 12 lag2 2006 Apr N(13, 0.72) 13.2 8
#> 13 lag2 2006 May N(13, 0.72) 13.2 8
#> 14 lag2 2006 Jun N(13, 0.72) 13.2 8
#> 15 lag2 2006 Jul N(13, 0.72) 13.2 8
#> 16 lag2 2006 Aug N(13, 0.72) 13.2 8
#> 17 lag2 2006 Sep N(13, 0.72) 13.2 8
#> 18 lag2 2006 Oct N(13, 0.72) 13.2 8
#> 19 lag2 2006 Nov N(13, 0.72) 13.2 8
#> 20 lag2 2006 Dec N(13, 0.72) 13.2 8
waldo::compare(fc1, fc2)
#> `old$Quotes[[1]]$mu`: 13.0
#> `new$Quotes[[1]]$mu`: 13.5
#>
#> `old$Quotes[[1]]$sigma`: 0.5
#> `new$Quotes[[1]]$sigma`: 0.8
#>
#> `old$Quotes[[2]]$mu`: 13.0
#> `new$Quotes[[2]]$mu`: 13.3
#>
#> `old$Quotes[[2]]$sigma`: 0.77
#> `new$Quotes[[2]]$sigma`: 0.85
#>
#> `old$.mean[1:5]`: 13.0 13.0 13.2 13.2 13.2
#> `new$.mean[1:5]`: 13.5 13.3 13.2 13.2 13.2
奇怪的是,当我手动(而不是在公式中)创建新的滞后变量时,模型结果与 fpp3 中的“基本情况”匹配(在我的示例中为 fc1
)。
insurance_manlag <- insurance %>%
mutate(TVadverts1 = lag(TVadverts),
TVadverts2 = lag(TVadverts, 2))
fit <- insurance_manlag %>%
# Restrict data so models use same fitting period
# Estimate models
model(
lag2 = ARIMA(Quotes ~ pdq(d = 0) +
TVadverts + TVadverts1 + TVadverts2)
)
insurance_man_future <- append_row(insurance, n = 20) %>%
replace_na(replace = list(TVadverts = 8)) %>%
mutate(TVadverts1 = lag(TVadverts),
TVadverts2 = lag(TVadverts, 2)) %>%
slice_tail(n = 20)
# Forecast as shown in https://otexts.com/fpp3/lagged-predictors.html
fc3 <- fit %>%
forecast(insurance_man_future)
waldo::compare(fc1$Quotes, fc3$Quotes)
#> ✓ No differences
waldo::compare(fc2$Quotes, fc3$Quotes)
#> `old[[1]]$mu`: 13.5
#> `new[[1]]$mu`: 13.0
#>
#> `old[[1]]$sigma`: 0.8
#> `new[[1]]$sigma`: 0.5
#>
#> `old[[2]]$mu`: 13.3
#> `new[[2]]$mu`: 13.0
#>
#> `old[[2]]$sigma`: 0.85
#> `new[[2]]$sigma`: 0.77
由 reprex package (v2.0.0)
创建于 2021-06-02
这个复制让我相信 fc1
是正确的,而不是 fc2
。如果是这样,fc2
中发生了什么导致它与 fc1
(和 fc3
)中的预测不同?
在 {fable}
中,生成预测的模型保留生成预测所需的所有信息。当使用推荐的接口获取 fc1
(如书中所示)时,该模型保留了 TVadverts
的 2 个最新值。虽然不需要它们来估计模型,但它们是产生前几个预测所必需的输入。
将 forecast()
函数与 new_data
一起使用时,模型的预期行为是为 new_data
中的每个时间点生成预测。我相信从不在系列末尾的时间点进行预测尚未实现,因此我将更改它以产生错误。
一般来说,在模型公式中使用lag()
函数时,不需要预先添加历史数据。模型将存储和调用预测所需的值。
这是我作为 issue 打开的一个问题,但没有收到包作者的消息,所以我想我会在这里问这个问题。谢谢!
我注意到在使用滞后的 xreg 进行预测时存在一些不一致之处。具体来说,h <= 滞后期的预测。在生成预测之前,提供给原始模型的历史数据似乎没有添加到新数据中。在下面的示例中,我使用了 fpp3 中的 lag = 2 示例。第一个预测 fc1
与书中生成的预测相同。在第二个预测 fc2
中,我通过将历史广告数据与 insurance_future
中生成的新广告数据绑定来扩充 new_data
。当我这样做时,我在 fc2
和 fc1
中得到了不同的预测。在我看来,fc1
中的预测无法访问历史 (xreg) 数据,因此 TVaderts 在 horizon 的前两个步骤中被视为 NA
。这样对吗?如果是这样,难道不应该像 fc2
中那样包含该数据吗?这可能与。
library(fpp3)
#> ── Attaching packages ──────────────────────────────────────────── fpp3 0.4.0 ──
#> ✓ tibble 3.1.2 ✓ tsibble 1.0.1
#> ✓ dplyr 1.0.6 ✓ tsibbledata 0.3.0
#> ✓ tidyr 1.1.3 ✓ feasts 0.2.1
#> ✓ lubridate 1.7.10 ✓ fable 0.3.1
#> ✓ ggplot2 3.3.3
#> ── Conflicts ───────────────────────────────────────────────── fpp3_conflicts ──
#> x lubridate::date() masks base::date()
#> x dplyr::filter() masks stats::filter()
#> x tsibble::intersect() masks base::intersect()
#> x tsibble::interval() masks lubridate::interval()
#> x dplyr::lag() masks stats::lag()
#> x tsibble::setdiff() masks base::setdiff()
#> x tsibble::union() masks base::union()
library(fabletools)
library(fable)
library(dplyr)
library(tsibble)
fit <- insurance %>%
# Restrict data so models use same fitting period
# Estimate models
model(
lag2 = ARIMA(Quotes ~ pdq(d = 0) +
TVadverts + lag(TVadverts) +
lag(TVadverts, 2))
)
insurance_future <- new_data(insurance, 20) %>%
mutate(TVadverts = 8)
# Forecast as shown in https://otexts.com/fpp3/lagged-predictors.html
fc1 <- fit %>%
forecast(insurance_future)
# Manually pre-pend historic advert data to future data to ensure presence of
# lagged regressors
fc2 <- fit %>%
forecast(bind_rows(select(insurance, -Quotes), insurance_future)) %>%
filter_index(as.character(min(insurance_future$Month)) ~ .)
print(fc1)
#> # A fable: 20 x 5 [1M]
#> # Key: .model [1]
#> .model Month Quotes .mean TVadverts
#> <chr> <mth> <dist> <dbl> <dbl>
#> 1 lag2 2005 May N(13, 0.23) 13.0 8
#> 2 lag2 2005 Jun N(13, 0.59) 13.0 8
#> 3 lag2 2005 Jul N(13, 0.72) 13.2 8
#> 4 lag2 2005 Aug N(13, 0.72) 13.2 8
#> 5 lag2 2005 Sep N(13, 0.72) 13.2 8
#> 6 lag2 2005 Oct N(13, 0.72) 13.2 8
#> 7 lag2 2005 Nov N(13, 0.72) 13.2 8
#> 8 lag2 2005 Dec N(13, 0.72) 13.2 8
#> 9 lag2 2006 Jan N(13, 0.72) 13.2 8
#> 10 lag2 2006 Feb N(13, 0.72) 13.2 8
#> 11 lag2 2006 Mar N(13, 0.72) 13.2 8
#> 12 lag2 2006 Apr N(13, 0.72) 13.2 8
#> 13 lag2 2006 May N(13, 0.72) 13.2 8
#> 14 lag2 2006 Jun N(13, 0.72) 13.2 8
#> 15 lag2 2006 Jul N(13, 0.72) 13.2 8
#> 16 lag2 2006 Aug N(13, 0.72) 13.2 8
#> 17 lag2 2006 Sep N(13, 0.72) 13.2 8
#> 18 lag2 2006 Oct N(13, 0.72) 13.2 8
#> 19 lag2 2006 Nov N(13, 0.72) 13.2 8
#> 20 lag2 2006 Dec N(13, 0.72) 13.2 8
print(fc2)
#> # A fable: 20 x 5 [1M]
#> # Key: .model [1]
#> .model Month Quotes .mean TVadverts
#> <chr> <mth> <dist> <dbl> <dbl>
#> 1 lag2 2005 May N(14, 0.72) 13.5 8
#> 2 lag2 2005 Jun N(13, 0.72) 13.3 8
#> 3 lag2 2005 Jul N(13, 0.72) 13.2 8
#> 4 lag2 2005 Aug N(13, 0.72) 13.2 8
#> 5 lag2 2005 Sep N(13, 0.72) 13.2 8
#> 6 lag2 2005 Oct N(13, 0.72) 13.2 8
#> 7 lag2 2005 Nov N(13, 0.72) 13.2 8
#> 8 lag2 2005 Dec N(13, 0.72) 13.2 8
#> 9 lag2 2006 Jan N(13, 0.72) 13.2 8
#> 10 lag2 2006 Feb N(13, 0.72) 13.2 8
#> 11 lag2 2006 Mar N(13, 0.72) 13.2 8
#> 12 lag2 2006 Apr N(13, 0.72) 13.2 8
#> 13 lag2 2006 May N(13, 0.72) 13.2 8
#> 14 lag2 2006 Jun N(13, 0.72) 13.2 8
#> 15 lag2 2006 Jul N(13, 0.72) 13.2 8
#> 16 lag2 2006 Aug N(13, 0.72) 13.2 8
#> 17 lag2 2006 Sep N(13, 0.72) 13.2 8
#> 18 lag2 2006 Oct N(13, 0.72) 13.2 8
#> 19 lag2 2006 Nov N(13, 0.72) 13.2 8
#> 20 lag2 2006 Dec N(13, 0.72) 13.2 8
waldo::compare(fc1, fc2)
#> `old$Quotes[[1]]$mu`: 13.0
#> `new$Quotes[[1]]$mu`: 13.5
#>
#> `old$Quotes[[1]]$sigma`: 0.5
#> `new$Quotes[[1]]$sigma`: 0.8
#>
#> `old$Quotes[[2]]$mu`: 13.0
#> `new$Quotes[[2]]$mu`: 13.3
#>
#> `old$Quotes[[2]]$sigma`: 0.77
#> `new$Quotes[[2]]$sigma`: 0.85
#>
#> `old$.mean[1:5]`: 13.0 13.0 13.2 13.2 13.2
#> `new$.mean[1:5]`: 13.5 13.3 13.2 13.2 13.2
奇怪的是,当我手动(而不是在公式中)创建新的滞后变量时,模型结果与 fpp3 中的“基本情况”匹配(在我的示例中为 fc1
)。
insurance_manlag <- insurance %>%
mutate(TVadverts1 = lag(TVadverts),
TVadverts2 = lag(TVadverts, 2))
fit <- insurance_manlag %>%
# Restrict data so models use same fitting period
# Estimate models
model(
lag2 = ARIMA(Quotes ~ pdq(d = 0) +
TVadverts + TVadverts1 + TVadverts2)
)
insurance_man_future <- append_row(insurance, n = 20) %>%
replace_na(replace = list(TVadverts = 8)) %>%
mutate(TVadverts1 = lag(TVadverts),
TVadverts2 = lag(TVadverts, 2)) %>%
slice_tail(n = 20)
# Forecast as shown in https://otexts.com/fpp3/lagged-predictors.html
fc3 <- fit %>%
forecast(insurance_man_future)
waldo::compare(fc1$Quotes, fc3$Quotes)
#> ✓ No differences
waldo::compare(fc2$Quotes, fc3$Quotes)
#> `old[[1]]$mu`: 13.5
#> `new[[1]]$mu`: 13.0
#>
#> `old[[1]]$sigma`: 0.8
#> `new[[1]]$sigma`: 0.5
#>
#> `old[[2]]$mu`: 13.3
#> `new[[2]]$mu`: 13.0
#>
#> `old[[2]]$sigma`: 0.85
#> `new[[2]]$sigma`: 0.77
由 reprex package (v2.0.0)
创建于 2021-06-02这个复制让我相信 fc1
是正确的,而不是 fc2
。如果是这样,fc2
中发生了什么导致它与 fc1
(和 fc3
)中的预测不同?
在 {fable}
中,生成预测的模型保留生成预测所需的所有信息。当使用推荐的接口获取 fc1
(如书中所示)时,该模型保留了 TVadverts
的 2 个最新值。虽然不需要它们来估计模型,但它们是产生前几个预测所必需的输入。
将 forecast()
函数与 new_data
一起使用时,模型的预期行为是为 new_data
中的每个时间点生成预测。我相信从不在系列末尾的时间点进行预测尚未实现,因此我将更改它以产生错误。
一般来说,在模型公式中使用lag()
函数时,不需要预先添加历史数据。模型将存储和调用预测所需的值。