Quickstart: Python API

This page shows the fastest direct path from a pandas dataset to a fitted PanelMMM.

If you have not prepared your dataset yet, read Data Preparation first.

Load a dataset

The repository includes bundled demo datasets under data/demo/. The timeseries bundle is the simplest starting point because it has no extra panel dimensions.

import pandas as pd

dataset = pd.read_csv("data/demo/timeseries/dataset.csv")
dataset["date"] = pd.to_datetime(dataset["date"])

X = dataset.drop(columns=["revenue"])
y = dataset["revenue"].rename("revenue")

Construct PanelMMM

from abacus.mmm import GeometricAdstock, LogisticSaturation
from abacus.mmm.panel import PanelMMM

mmm = PanelMMM(
    date_column="date",
    target_column="revenue",
    channel_columns=[
        "channel_1",
        "channel_2",
        "channel_3",
        "channel_4",
        "channel_5",
        "channel_6",
    ],
    yearly_seasonality=2,
    adstock=GeometricAdstock(l_max=4),
    saturation=LogisticSaturation(),
)

This example uses a plain timeseries. If your dataset has panel dimensions such as geo or brand, add them with dims=(...) and keep those columns in X.

Fit the model

You can call fit() directly. If the model graph has not been built yet, Abacus builds it for you.

idata = mmm.fit(
    X,
    y,
    draws=200,
    tune=200,
    chains=2,
    cores=2,
    progressbar=False,
    compute_convergence_checks=False,
    random_seed=42,
)

fit() returns an arviz.InferenceData object and also stores it on the model instance as mmm.idata.

Prior and posterior predictive checks

You can sample prior predictive draws before fitting:

prior = mmm.sample_prior_predictive(
    X=X,
    y=y,
    samples=50,
    random_seed=42,
)

After fitting, you can sample posterior predictive draws:

post = mmm.sample_posterior_predictive(
    X=X,
    progressbar=False,
    random_seed=42,
)

By default, this also stores posterior predictive draws on mmm.idata.

When to call build_model()

Call build_model(X, y) explicitly when you want to inspect or modify the PyMC graph before sampling.

For example, you might build first so that you can add stored original-scale deterministics:

mmm.build_model(X, y)
mmm.add_original_scale_contribution_variable(
    var=["channel_contribution", "y"]
)

After that, fit the already-built model:

idata = mmm.fit(
    X,
    y,
    draws=200,
    tune=200,
    chains=2,
    cores=2,
    progressbar=False,
    compute_convergence_checks=False,
    random_seed=42,
)

Basic outputs

After fitting, common next steps are:

mmm.save("mmm.nc")
fig, axes = mmm.plot.posterior_predictive()

You can also inspect:

  • mmm.posterior
  • mmm.posterior_predictive
  • mmm.summary
  • mmm.diagnostics

Next steps