我正在使用 fable 包来获取一组分层时间序列的预测。我想指定一个层次结构,它在所有节点上都没有相同的深度。
现实例子:
- 时间序列 B1 和 B2 相加为时间序列 M1。
- 时间序列 M1 和 M2 相加为时间序列 T,它位于层次结构的顶部。
- 时间序列 M2 不是一组时间序列的总和;这是它自己的时间序列。
创建一个小的随机数据集,tsibble
格式为:
library(dplyr)
library(tsibble)
library(fable)
set.seed(1)
B1 <- rnorm(12, mean = 5) + (1:12)
B2 <- rnorm(12, mean = 5)
M2 <- rnorm(12, mean = 25)
ts_data <- tibble(value = c(B1, B2, M2),
month = rep(yearmonth(paste("2020", 1:12, sep="-")), 3),
B = c(rep("B1", 12), rep("B2", 12), rep("B3", 12)),
M = c(rep("M1", 24), rep("M2", 12))) %>%
as_tsibble(key = c("B", "M"), index = month)
在 3 个时间序列中的每一个上估计单独的 ARIMA 模型,聚合和预测:
fcsts <- ts_data %>%
# Specify hierarchy
aggregate_key(M / B, value = sum(value)) %>%
# Fit models
model(arima = ARIMA(value)) %>%
# Set up reconciliation
mutate(mint = min_trace(arima)) %>%
# Produce the forecasts
forecast(h = 1)
我之所以担心结果可能是错误的,是因为我可以创建一个病态的例子,即使没有实际的聚合,对账给出的置信区间也更小:
病理例子:
- 时间序列 B3 是 M2 的孩子,M2 是 T 的孩子。
我通过对前一个数据集进行子集来为此示例创建一个数据集:
ts_data_2 <- ts_data %>%
filter(B == "B3")
再次估计单独的 ARIMA 模型、聚合和预测:
fcsts_2 <- ts_data_2 %>%
# Specify hierarchy
aggregate_key(M / B, value = sum(value)) %>%
# Fit models
model(arima = ARIMA(value)) %>%
# Set up reconciliation
mutate(mint = min_trace(arima)) %>%
# Produce the forecasts
forecast(h = 6)
结果如下:
> fcsts_2
# A fable: 6 x 6 [1M]
# Key: M, B, .model [6]
M B .model month value .distribution
<chr> <chr> <chr> <mth> <dbl> <dist>
1 M2 B3 arima 2021 Jan 24.9 N(25, 0.63)
2 M2 <aggregated> arima 2021 Jan 24.9 N(25, 0.63)
3 <aggregated> <aggregated> arima 2021 Jan 24.9 N(25, 0.63)
4 M2 B3 mint 2021 Jan 24.9 N(25, 0.21)
5 M2 <aggregated> mint 2021 Jan 24.9 N(25, 0.21)
6 <aggregated> <aggregated> mint 2021 Jan 24.9 N(25, 0.21)
方差从原始 ARIMA 模型中的 0.63 减小到 0.21,即使没有实际聚合。当然,这是一个示例,根本不应该使用对帐,但是这里方差减小的事实让我担心在现实示例中对帐无法正常工作。
有没有办法在实际示例中指定模型以避免从 B3 聚合到 M2?(我尝试在 B 列中使用 NA 而不是级别“B3”,但这不起作用。)