Hierarchical Forecasting in R with fable
How to build coherent hierarchical forecasts using fable and
reconciliation methods — from store-level to national-level, all adding up correctly.
The Coherence Problem
Imagine you forecast sales for 50 stores individually. You also forecast total national sales. Do the 50 store forecasts add up to the national forecast? Almost never. That's the coherence problem, and it's everywhere — retail, finance, supply chain.
Hierarchical forecasting solves this by forecasting at every level of the hierarchy and then reconciling the forecasts so they're consistent.
Setting Up the Hierarchy
R's fable ecosystem makes this elegant. You define your hierarchy using
tsibble aggregation keys:
library(fable)
library(tsibble)
library(tidyverse)
sales_tsbl <- sales_data %>%
as_tsibble(key = c(region, store), index = month)
# Aggregate to create the hierarchy
sales_hierarchy <- sales_tsbl %>%
aggregate_key(region / store, sales = sum(sales))
This creates a tsibble with three levels: total (national), region, and store.
The / operator defines the nesting.
Forecasting at Every Level
Fit models to every series in the hierarchy simultaneously:
fit <- sales_hierarchy %>%
model(
ets = ETS(sales),
arima = ARIMA(sales)
)
fc <- fit %>%
forecast(h = 12)
Reconciliation
The magic happens here. reconcile() adjusts the forecasts so they add up:
fc_reconciled <- fit %>%
reconcile(
ets_bu = bottom_up(ets),
ets_mint = min_trace(ets, method = "mint_shrink"),
arima_bu = bottom_up(arima)
) %>%
forecast(h = 12)
The main reconciliation approaches:
- Bottom-up — forecast at the lowest level, sum up. Simple but ignores top-level patterns.
- Top-down — forecast at the top, distribute down using proportions.
- MinT (minimum trace) — the gold standard. Uses the covariance structure of forecast errors to find the optimal reconciliation. Use
mint_shrinkfor high-dimensional hierarchies.
Real-World Results
In our retail case study, MinT reconciliation improved forecast accuracy by 8–15% at the store level compared to independent forecasts. The national-level forecasts barely changed — but the store-level ones got dramatically better because they borrowed strength from the aggregate.
Takeaway
If you're forecasting at multiple levels of granularity, you need reconciliation.
The fable ecosystem makes it a few lines of code. Start with MinT shrinkage —
it's the best default for most real-world hierarchies.