Fixed-effects MMM
Use FixedEffectsMMM when shared media and control slopes should be estimated
from temporal variation within observed units, with time-invariant unit levels
removed from the fitting likelihood. Ordinary MMM(dims=("geo",)) does not
implement this likelihood.
from ammm.mmm import GeometricAdstock, LogisticSaturation
from ammm.mmm.fixed_effects import FixedEffectsMMM
model = FixedEffectsMMM(
unit="geo", date_column="date", target_column="revenue",
channel_columns=["tv", "social"],
adstock=GeometricAdstock(l_max=4), saturation=LogisticSaturation(),
)
Supply a balanced unit-date panel with unique, complete cells. The estimator uses orthonormal within-unit Helmert contrasts. Shared media parameters and control slopes are learned without sampling unit intercepts in that likelihood; level prediction reconstructs unit effects from factual training residuals. The target scale is derived from within-unit contrasts and is not configurable.
Adstock, saturation and control prior dimensions must express shared slopes. The design screens reject absent transformed within-unit variation and deficient joint slope rank at the reference design. Passing them does not establish nonlinear identification or freedom from time-varying confounding.
Prediction requires every fitted unit and rejects missing or unseen units.
The current contract excludes log link, time-varying parameters, annual
seasonality, custom mean effects, holidays, calibration, causal-graph options,
cost-per-unit configuration and fixed-budget optimisation. The
geo_fe demo shows the supported graph
configuration. The retained runner plots prior predictions against observed
within-unit contrasts, labels the axis accordingly and retains one panel per
unit; posterior predictive plots use reconstructed outcome levels
(src/ammm/mmm/plotting/diagnostics.py:206, working tree after 7cb7f20).
A reduced-draw geo_fe run and its bundled retained scenarios completed on
1 October 2026. That run failed diagnostic gates, so this check establishes
workflow execution only. Inspect diagnostics before interpreting a fitted model.
Unit effects do not absorb common time shocks. A regressor shared across units but varying by date survives the within transformation; its causal interpretation still needs an adjustment or design argument. Do not describe this estimator as two-way fixed effects.
The previously cited historical PC-FE-01 posterior parity result has not been
verified against a retrievable report in this documentation review. Do not use
that statement as qualification evidence without the retained report, frozen
profile, data and source commit. The implementation tests include deterministic
oracles (tests/mmm/test_fixed_effects.py:98); these do not reproduce a
cross-library posterior qualification study. Review diagnostics on every fit.
Implementation reference at 7cb7f20: src/ammm/mmm/fixed_effects.py:79.