Learning how to create models with yml files#

The following notebook will teach you to create pymc-marketing models from yml files, allowing you to easily recreate your models in production environments without several lines of code.

Setup#

import warnings

import arviz as az
import matplotlib.pyplot as plt
import pandas as pd

from pymc_marketing.mmm.builders.yaml import build_mmm_from_yaml
from pymc_marketing.paths import data_dir

warnings.filterwarnings("ignore")

az.style.use("arviz-darkgrid")
plt.rcParams["figure.figsize"] = [12, 7]
plt.rcParams["figure.dpi"] = 100

%load_ext autoreload
%autoreload 2
%config InlineBackend.figure_format = "retina"
X = pd.read_csv(data_dir / "processed" / "X.csv")
y = pd.read_csv(data_dir / "processed" / "y.csv")
X.head(3)
date market channel_1 channel_2
0 2023-01-01 US 70.171496 20.945956
1 2023-01-02 US 90.243918 45.828916
2 2023-01-03 US 9.178717 26.322735
y.head(3)
y
0 45.453806
1 42.516346
2 54.250939

Multidimensional model#

mmm = build_mmm_from_yaml(
    X=X, y=y, config_path=data_dir / "config_files" / "multi_dimensional_model.yml"
)
mmm.model.to_graphviz()
../../_images/b9fa6964b1d4d04456b3053c6deb2dedf585ee9ca7a0af2279d4dae294e5653d.svg
prior_predictive = mmm.sample_prior_predictive(X=X, y=y, samples=1_000)
Sampling: [adstock_alpha, intercept_contribution, saturation_alpha, saturation_lam, y, y_sigma]
prior_predictive
<xarray.Dataset> Size: 2MB
Dimensions:  (date: 100, market: 2, sample: 1000)
Coordinates:
  * date     (date) datetime64[ns] 800B 2023-01-01 2023-01-02 ... 2023-04-10
  * market   (market) <U2 16B 'EU' 'US'
  * sample   (sample) object 8kB MultiIndex
  * chain    (sample) int64 8kB 0 0 0 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0 0 0 0
  * draw     (sample) int64 8kB 0 1 2 3 4 5 6 7 ... 993 994 995 996 997 998 999
Data variables:
    y        (date, market, sample) float64 2MB -1.2 3.347 ... 4.432 1.758
mmm.fit(
    X=X,
    y=y.y,
    random_seed=42,
)

mmm.sample_posterior_predictive(
    X=X,
    extend_idata=True,
    combined=True,
    random_seed=42,
)
NUTS[nutpie]: [adstock_alpha, saturation_lam, saturation_alpha, y_sigma, intercept_contribution]


Sampling: [y]

<xarray.Dataset> Size: 3MB
Dimensions:  (date: 100, market: 2, sample: 1600)
Coordinates:
  * date     (date) datetime64[ns] 800B 2023-01-01 2023-01-02 ... 2023-04-10
  * market   (market) <U2 16B 'EU' 'US'
  * sample   (sample) object 13kB MultiIndex
  * chain    (sample) int64 13kB 0 0 0 0 0 0 0 0 0 0 0 ... 7 7 7 7 7 7 7 7 7 7 7
  * draw     (sample) int64 13kB 0 1 2 3 4 5 6 7 ... 193 194 195 196 197 198 199
Data variables:
    y        (date, market, sample) float64 3MB 0.5957 0.4552 ... 0.6261 0.5574
Attributes:
    created_at:                 2026-06-30T12:48:42.051554+00:00
    creation_library:           ArviZ
    creation_library_version:   1.2.0
    creation_library_language:  Python
    inference_library:          pymc
    inference_library_version:  6.0.1
    sample_dims:                ['sample']

How the config works?#

# Let's look at the content of the basic model configuration file
with open(data_dir / "config_files" / "basic_model.yml") as f:
    basic_config = f.read()

print(basic_config)
model:
  class: pymc_marketing.mmm.mmm.MMM
  kwargs:
    date_column: "date"
    channel_columns:                                     # explicit for reproducibility
      - channel_1
      - channel_2
      # …
    target_column: "y"

    # --- media transformations ---------------------------------------
    adstock:
      class: pymc_marketing.mmm.GeometricAdstock
      kwargs: {l_max: 12}        # any other hyper-parameters here

    saturation:
      class: pymc_marketing.mmm.MichaelisMentenSaturation
      kwargs: {}                 # default α, λ priors inside the class

# ----------------------------------------------------------------------
# (optional) sampler options you plan to forward to pm.sample():
    sampler_config:
      tune: 1000
      draws: 200
      chains: 8
      random_seed: 42
      target_accept: 0.90

# ----------------------------------------------------------------------
# (optional) idata from a previous sample
# idata_path: "data/idata.nc"

# ----------------------------------------------------------------------
# (optional) Data paths
# data:
#   X_path: "data/X.csv"
#   y_path: "data/y.csv"

The configuration file uses a structured YAML format with several key sections:

  1. schema_version: Version identifier for the configuration schema

  2. model: The main model configuration

    • class: The Python class to instantiate (fully qualified name)

    • kwargs: Arguments passed to the model constructor

      • Including data columns, transformations (adstock, saturation)

  3. sample_kwargs: Optional parameters for the sampling process

  4. data: Optional paths to data files

The build_mmm_from_yaml function:

  • Parses this YAML configuration

  • Uses the ‘build’ function to instantiate objects recursively

  • Handles special cases like priors and distributions

  • Returns a fully configured MMM model ready for sampling

  • If idata_path is provided then the idata from a previous class is used in the model in the idata property.

Basic model#

mmm2 = build_mmm_from_yaml(
    X=X, y=y, config_path=data_dir / "config_files" / "basic_model.yml"
)
mmm2.model.to_graphviz()
../../_images/17cce7b1c2c1128ae4de371cf46bc1476f90344755058506bf6d16ad475adc3d.svg
prior_predictive = mmm2.sample_prior_predictive(X=X, y=y, samples=1_000)
Sampling: [adstock_alpha, intercept_contribution, saturation_alpha, saturation_lam, y, y_sigma]

Multidimensional Hierarchical Model#

mmm3 = build_mmm_from_yaml(
    X=X,
    y=y,
    config_path=data_dir / "config_files" / "multi_dimensional_hierarchical_model.yml",
)
mmm3.model.to_graphviz()
../../_images/175e978547f423c33c5f9e7c6e5c833d8153fabcaa36ba31d30758069ef54e2a.svg
prior_predictive = mmm3.sample_prior_predictive(X=X, y=y, samples=1_000)
Sampling: [adstock_alpha, intercept_contribution, intercept_contribution_beta, saturation_beta, saturation_lam, saturation_lam_alpha, y, y_sigma]

Multidimensional Hierarchical with arbitrary effects and calibration#

data_dir / "config_files" / "multi_dimensional_hierarchical_with_arbitrary_effects_model.yml"
PosixPath('/Users/juanitorduz/Documents/pymc-marketing/data/config_files/multi_dimensional_hierarchical_with_arbitrary_effects_model.yml')
mmm4 = build_mmm_from_yaml(
    X=X,
    y=y,
    config_path=data_dir
    / "config_files"
    / "multi_dimensional_hierarchical_with_arbitrary_effects_model.yml",
)
mmm4.model.to_graphviz()
../../_images/8243e04228384c7293c5d9c3e3246be75b50294bcf3e9ab105b27a54c4e32d01.svg
prior_predictive = mmm4.sample_prior_predictive(X=X, y=y, samples=1_000)
Sampling: [adstock_alpha, delta, delta_mu, example_cpt, example_lift_tests, intercept_contribution, intercept_contribution_beta, saturation_beta, saturation_lam, saturation_lam_alpha, weekly_fourier_beta, weekly_fourier_beta_mu, y, y_sigma]
%load_ext watermark
%watermark -n -u -v -iv -w -p pymc_marketing,pytensor
Last updated: Tue, 30 Jun 2026

Python implementation: CPython
Python version       : 3.14.2
IPython version      : 9.14.0

pymc_marketing: 1.0.0.dev0
pytensor      : 3.0.5

arviz         : 1.2.0
matplotlib    : 3.10.9
pandas        : 2.3.3
pymc_marketing: 1.0.0.dev0

Watermark: 2.6.0