Priors and Configuration
AMMM3 uses model_config to control priors on the underlying PyMC variables.
Transform priors can be configured either on the transform objects themselves or
through their prefixed variable names in model_config.
Where configuration lives
| Surface | Use it for |
|---|---|
model_config | Intercept, likelihood, controls, seasonality, Mundlak terms, time-varying config, and prefixed transform priors |
adstock=... and saturation=... | Transform choice plus direct transform-prior overrides |
control_impacts and control_sign_policy | Directional expectations for controls |
Default model_config
PanelMMM.default_model_config is built from the current model state.
For an unlabelled model using dims, the default keys are:
| Key | Default |
|---|---|
intercept | Prior("Normal", mu=0, sigma=2, dims=dims) |
likelihood | Prior("Normal", sigma=Prior("HalfNormal", sigma=2, dims=dims), dims=("date", *dims)) |
gamma_control | Prior("Normal", mu=0, sigma=2, dims=(*dims, "control")) |
gamma_fourier | Prior("Laplace", mu=0, b=1, dims=(*dims, "fourier_mode")) |
gamma_channel_mundlak | Added only when use_mundlak_cre=True |
gamma_control_mundlak | Added only when use_mundlak_cre=True |
intercept_tvp_config | Added when time_varying_intercept is enabled |
media_tvp_config | Added when time_varying_media is enabled |
AMMM3 also merges in the transform-specific config exposed by the selected adstock and saturation objects.
Named estimator defaults
Named panel presets use shared slope parameters. For FE and CRE,
gamma_control has dimension control; the likelihood scale is scalar.
Transform priors have dimension channel unless the estimator contract
specifies otherwise.
| Key or feature | FE | CRE |
|---|---|---|
intercept | Absent | Prior("Normal", mu=0, sigma=2) |
| Likelihood dimensions | ("within_contrast", *dims) | ("date", *dims) |
gamma_fourier | Absent | Absent |
unit_intercept_scale | Absent | Prior("HalfNormal", sigma=1) |
gamma_media_cre | Absent | Prior("Normal", mu=0, sigma=1, dims="channel") |
gamma_control_cre | Absent | Prior("Normal", mu=0, sigma=1, dims="cre_control") |
FE conditions out unit intercepts. CRE integrates random unit intercepts and
uses the CRE coefficients for its between-unit adjustment. These named CRE
keys differ from the optional use_mundlak_cre keys on unlabelled models.
Named RE remains gated. Read the FE and
CRE contracts before overriding
preset priors.
Configure priors in Python
Use pymc_extras.prior.Prior objects when you want explicit control:
from pymc_extras.prior import Prior
from abacus.mmm import GeometricAdstock, LogisticSaturation
from abacus.mmm.panel import PanelMMM
model_config = {
"intercept": Prior("Normal", mu=0, sigma=1, dims=("geo",)),
"likelihood": Prior(
"Normal",
sigma=Prior("HalfNormal", sigma=1.5, dims=("geo",)),
dims=("date", "geo"),
),
"gamma_control": Prior("Normal", mu=0, sigma=1, dims=("geo", "control")),
"saturation_lam": Prior("Gamma", alpha=3, beta=1, dims=("geo", "channel")),
}
mmm = PanelMMM(
date_column="date",
target_column="sales",
channel_columns=["tv", "search"],
control_columns=["price_index"],
dims=("geo",),
adstock=GeometricAdstock(l_max=8),
saturation=LogisticSaturation(),
model_config=model_config,
)
Configure priors in YAML
YAML config can express the same priors as serialised distribution mappings:
data:
date_column: date
target:
column: sales
type: revenue
dimensions:
panel: [geo]
media:
channels: [tv, search]
adstock:
type: geometric
l_max: 8
saturation:
type: logistic
priors:
intercept:
distribution: Normal
mu: 0
sigma: 1
dims: ["geo"]
likelihood:
distribution: Normal
sigma:
distribution: HalfNormal
sigma: 1.5
dims: ["geo"]
dims: ["date", "geo"]
saturation_lam:
distribution: Gamma
alpha: 3
beta: 1
dims: ["geo", "channel"]
AMMM3 parses these mappings into runtime Prior or HSGPKwargs objects.
Transform priors and prefixed names
Transform parameters appear in the model under prefixed variable names.
Examples:
- adstock
alpha->adstock_alpha - saturation
lam->saturation_lam - saturation
beta->saturation_beta
So you can override transform priors in either of these ways:
- pass
priors={...}to the transform object - override the prefixed variable in
model_config
Use one style consistently within a project if you want the configuration to be easy to read.
Directional control priors
Controls are the right place for exogenous drivers whose effect may be negative, such as competitor spend, competitor price pressure, or supply-side disruptions. By default, control coefficients remain unrestricted.
You can declare expected control directions with:
control_impactscontrol_sign_policy
Allowed impact values:
positivenegativeunrestricted
Allowed policies:
soft: bias the prior toward the expected signstrict: use a sign-constrained prior
Python example
mmm = PanelMMM(
date_column="date",
channel_columns=["tv", "search"],
control_columns=["competitor_spend", "price_index"],
control_impacts={
"competitor_spend": "negative",
"price_index": "negative",
},
control_sign_policy="strict",
adstock=GeometricAdstock(l_max=8),
saturation=LogisticSaturation(),
)
YAML note
The current public YAML schema does not expose control_impacts or
control_sign_policy. If you need directional control settings today, use the
Python API for that part of the specification.
Constraints for directional controls
When control_impacts is configured, AMMM3 expects:
gamma_controlandgamma_control_mundlakto beNormalorTruncatedNormal- scalar numeric
muandsigmavalues for those priors - the prior dims to include
"control"
If you violate those assumptions, model build fails with a validation error.
Time-varying configuration keys
When you enable a boolean time-varying effect, AMMM3 uses these model_config
keys:
intercept_tvp_configmedia_tvp_config
Those keys can be:
- an
HSGPKwargsinstance - a dict with
HSGPKwargsfields - a dict in
SoftPlusHSGP.parameterize_from_data(...)style, such as{"ls_lower": 1, "ls_upper": 10}
Important scope note
Directional control priors apply to control_columns, not channel_columns.
Media channels are modelled through the adstock and saturation path.
If you need full manual control over the control prior, override
gamma_control and gamma_control_mundlak directly in model_config.
Common pitfalls
- Putting control priors on media variables instead of using transform priors
- Forgetting the prefixed transform variable names in
model_config - Assuming
dimsautomatically create hierarchical priors - Using directional control priors with incompatible
gamma_controldistributions
Next steps
- Read Adstock and Saturation for transform choices.
- Read Panel Dimensions if your priors need panel-aware dims.