Skip to content

Don't flatten decomposition models in model arithmetic - #443

Open
robjhyndman wants to merge 1 commit into
mainfrom
fix-decomposition-combination
Open

robjhyndman wants to merge 1 commit into
mainfrom
fix-decomposition-combination

Conversation

@robjhyndman

Copy link
Copy Markdown
Member

Reported in https://github.com/orgs/OTexts/discussions/164.

Problem

Combining models with arithmetic gave forecasts on the wrong scale when one of the models was a transformed decomposition_model(), while mean() gave the right answer:

STLF <- decomposition_model(
  STL(log(Turnover) ~ season(window = Inf)),
  ETS(season_adjust ~ season("N"))
)
train |>
  model(ets = ETS(Turnover), stlf = STLF, arima = ARIMA(log(Turnover))) |>
  mutate(
    combination1 = (ets + stlf + arima) / 3,   # ~860, far too low
    combination2 = mean(ets, stlf, arima)      # ~1299, correct
  )

Cause

.cj_parts() unpacks any fit that inherits from model_combination into its components. A decomposition_model fit also inherits from model_combination, so + split STLF into ETS on season_adjust plus SNAIVE on season_year. Those components add up to log(Turnover), and the back-transformation is stored on the outer STLF model, which was dropped. combination1 ended up with four weights of 1/3 and averaged forecasts in dollars with forecasts in log-dollars. Without a transformation the split is harmless, which is why this went unnoticed.

Fix

.cj_parts() no longer unpacks decomposition models; each one is kept as a single component. Added a regression test and a NEWS entry.

Testing

  • The example above now gives identical forecasts for combination1 and combination2.
  • The new test in test-combination.R fails without the fix and passes with it.
  • The combination and decomposition tests pass.

🤖 Generated with Claude Code

`.cj_parts()` unpacked any fit inheriting from `model_combination`, which
includes `decomposition_model`. For a transformed decomposition (e.g.
`STL(log(y))`) the components sum to the transformed response, and the
back-transformation on the outer model was dropped, so combinations such
as `(ets + stlf + arima)/3` gave forecasts on the wrong scale while
`mean(ets, stlf, arima)` was correct.

See https://github.com/orgs/OTexts/discussions/164

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant