Time-Varying Parameters
AMMM3 supports time-varying intercept and media effects through
SoftPlusHSGP, a Hilbert Space Gaussian Process approximation.
Two ways to enable time variation
For both time_varying_intercept and time_varying_media, you can pass:
Trueto use the config-driven default path- a custom
HSGPBaseinstance such asSoftPlusHSGP(...)
Boolean mode
The simplest entry point is a boolean flag:
mmm = PanelMMM(
date_column="date",
target_column="sales",
channel_columns=["tv", "search"],
adstock=GeometricAdstock(l_max=8),
saturation=LogisticSaturation(),
time_varying_intercept=True,
time_varying_media=True,
)
When you do this, AMMM3 builds a SoftPlusHSGP internally from:
model_config["intercept_tvp_config"]model_config["media_tvp_config"]
The default config keys are HSGPKwargs with:
m=200L=Noneeta_lam=1ls_mu=5ls_sigma=10cov_func=None
What the boolean defaults mean
With boolean mode:
time_varying_intercept=Truecreatesintercept_latent_processover("date", *dims)time_varying_media=Truecreatesmedia_temporal_latent_multiplierover("date", *dims)
That second point matters:
boolean
time_varying_media=Truegives you one shared temporal multiplier per panel slice, not a different time-varying multiplier per channel
If you want channel-specific time variation, pass a custom HSGP with channel
in its dims.
Custom SoftPlusHSGP
Use a custom HSGP instance when you need precise control over dims, covariance, or priors.
Example: channel-specific time-varying media in a simple timeseries model.
import numpy as np
from abacus.mmm import SoftPlusHSGP
n_dates = X["date"].nunique()
media_hsgp = SoftPlusHSGP.parameterize_from_data(
X=np.arange(n_dates),
dims=("date", "channel"),
cov_func="matern32",
)
mmm = PanelMMM(
date_column="date",
target_column="sales",
channel_columns=["tv", "search"],
adstock=GeometricAdstock(l_max=8),
saturation=LogisticSaturation(),
time_varying_media=media_hsgp,
)
For a panel model with dims=("geo",), valid media HSGP dims include:
("date", "geo")("date", "geo", "channel")
For the intercept, the custom dims should align with the target axes, typically
("date",) or ("date", *dims).
Supported covariance choices
For SoftPlusHSGP.parameterize_from_data(...), the supported covariance
keywords are:
"expquad""matern32""matern52"
Config formats for boolean mode
The *_tvp_config entries in model_config support two formats.
HSGPKwargs style
from abacus.hsgp_kwargs import HSGPKwargs
model_config = {
"intercept_tvp_config": HSGPKwargs(
m=50,
L=None,
eta_lam=1.0,
ls_mu=5.0,
ls_sigma=10.0,
cov_func=None,
)
}
Equivalent dict form is also accepted.
parameterize_from_data style
You can also pass a dict that is forwarded to
SoftPlusHSGP.parameterize_from_data(...):
model_config = {
"intercept_tvp_config": {
"ls_lower": 1.0,
"ls_upper": 10.0,
}
}
AMMM3 preserves that dict and uses it when constructing the HSGP.
How the latent process enters the model
Time-varying intercept
AMMM3 creates:
intercept_contribution = intercept_baseline * intercept_latent_process
Time-varying media
AMMM3 first creates a baseline transformed media contribution, then multiplies it by the temporal latent process:
channel_contribution =
baseline_channel_contribution * media_temporal_latent_multiplier
If the custom media HSGP dims include channel, the multiplier can vary by
channel. Otherwise it is broadcast across channels.
Save and load
Custom SoftPlusHSGP instances round-trip through PanelMMM.save(...) and
PanelMMM.load(...).
That includes custom dims such as:
("date",)("date", "channel")("date", "geo")("date", "geo", "channel")
Common pitfalls
- Expecting
time_varying_media=Trueto create channel-specific media multipliers - Using custom HSGP dims that do not align with the model dims
- Forgetting that boolean mode uses
model_config["intercept_tvp_config"]andmodel_config["media_tvp_config"]
Next steps
- Read Seasonality and Trends for additive trend and seasonal components.
- Read Priors and Configuration for the TVP config keys.