DelayedSaturatedMMM#

class pymc_marketing.mmm.delayed_saturated_mmm.DelayedSaturatedMMM(date_column, channel_columns, adstock_max_lag, model_config=None, sampler_config=None, validate_data=True, control_columns=None, yearly_seasonality=None, **kwargs)[source]#

Media Mix Model with delayed adstock and logistic saturation class (see [1]).

Given a time series target variable \(y_{t}\) (e.g. sales on conversions), media variables \(x_{m, t}\) (e.g. impressions, clicks or costs) and a set of control covariates \(z_{c, t}\) (e.g. holidays, special events) we consider a Bayesian linear model of the form:

\[y_{t} = \alpha + \sum_{m=1}^{M}\beta_{m}f(x_{m, t}) + \sum_{c=1}^{C}\gamma_{c}z_{c, t} + \varepsilon_{t},\]

where \(\alpha\) is the intercept, \(f\) is a media transformation function and \(\varepsilon_{t}\) is the error therm which we assume is normally distributed. The function \(f\) encodes the contribution of media on the target variable. Typically we consider two types of transformation: adstock (carry-over) and saturation effects.

Notes

Here are some important notes about the model:

1. Before fitting the model, we scale the target variable and the media channels using the maximum absolute value of each variable. This enable us to have a more stable model and better convergence. If control variables are present, we do not scale them! If needed please do it before passing the data to the model.

2. We allow to add yearly seasonality controls as Fourier modes. You can use the yearly_seasonality parameter to specify the number of Fourier modes to include.

  1. This class also allow us to calibrate the model using:

    • Custom priors for the parameters via the model_config parameter. You can also set the likelihood distribution.

    • Adding lift tests to the likelihood function via the add_lift_test_measurements method.

For details on a vanilla implementation in PyMC, see [2].

Examples

Here is an example of how to instantiate the model with the default configuration:

import numpy as np
import pandas as pd

from pymc_marketing.mmm import DelayedSaturatedMMM

data_url = "https://raw.githubusercontent.com/pymc-labs/pymc-marketing/main/data/mmm_example.csv"
data = pd.read_csv(data_url, parse_dates=["date_week"])

mmm = DelayedSaturatedMMM(
    date_column="date_week",
    channel_columns=["x1", "x2"],
    control_columns=[
        "event_1",
        "event_2",
        "t",
    ],
    adstock_max_lag=8,
    yearly_seasonality=2,
)

Now we can fit the model with the data:

# Set features and target
X = data.drop("y", axis=1)
y = data["y"]

# Fit the model
idata = mmm.fit(X, y)

We can also define custom priors for the model:

my_model_config = {
    "beta_channel": {
        "dist": "LogNormal",
        "kwargs": {"mu": np.array([2, 1]), "sigma": 1},
    },
    "likelihood": {
        "dist": "Normal",
        "kwargs": {"sigma": {"dist": "HalfNormal", "kwargs": {"sigma": 2}}},
    },
}

mmm = DelayedSaturatedMMM(
    model_config=my_model_config,
    date_column="date_week",
    channel_columns=["x1", "x2"],
    control_columns=[
        "event_1",
        "event_2",
        "t",
    ],
    adstock_max_lag=8,
    yearly_seasonality=2,
)

As you can see, we can configure all prior and likelihood distributions via the model_config.

The fit method accepts keyword arguments that are passed to the PyMC sampling method. For example, to change the number of samples and chains, and using a JAX implementation of NUTS we can do:

sampler_kwargs = {
    "draws": 2_000,
    "target_accept": 0.9,
    "chains": 5,
    "random_seed": 42,
}

idata = mmm.fit(X, y, nuts_sampler="numpyro", **sampler_kwargs)

References

Methods

DelayedSaturatedMMM.__init__(date_column, ...)

Constructor method.

DelayedSaturatedMMM.add_lift_test_measurements(...)

Add lift tests to the model.

DelayedSaturatedMMM.build_model(X, y, **kwargs)

Builds a probabilistic model using PyMC for marketing mix modeling.

DelayedSaturatedMMM.channel_contributions_forward_pass(...)

Evaluate the channel contribution for a given channel data and a fitted model, ie.

DelayedSaturatedMMM.compute_channel_contribution_original_scale()

rtype:

DataArray

DelayedSaturatedMMM.compute_channel_curve_optimization_parameters_original_scale([...])

Experimental: Estimate the parameters for the saturating function of each channel's contribution.

DelayedSaturatedMMM.compute_mean_contributions_over_time([...])

Get the contributions of each channel over time.

DelayedSaturatedMMM.fit(X[, y, progressbar, ...])

Fit a model using the data passed as a parameter.

DelayedSaturatedMMM.get_channel_contributions_forward_pass_grid(...)

Generate a grid of scaled channel contributions for a given grid of shared values.

DelayedSaturatedMMM.get_params([deep])

Get all the model parameters needed to instantiate a copy of the model, not including training data.

DelayedSaturatedMMM.get_target_transformer()

rtype:

Pipeline

DelayedSaturatedMMM.graphviz(**kwargs)

DelayedSaturatedMMM.load(fname)

Creates a DelayedSaturatedMMM instance from a file, instantiating the model with the saved original input parameters.

DelayedSaturatedMMM.max_abs_scale_channel_data(data)

rtype:

DataFrame

DelayedSaturatedMMM.max_abs_scale_target_data(data)

rtype:

ndarray | Series

DelayedSaturatedMMM.new_spend_contributions([...])

Return the upcoming contributions for a given spend.

DelayedSaturatedMMM.optimize_channel_budget_for_maximum_contribution(...)

Experimental: Optimize the allocation of a given total budget across multiple channels to maximize the expected contribution.

DelayedSaturatedMMM.plot_budget_scenearios(*, ...)

Experimental: Plots the budget and contribution bars side by side for multiple scenarios.

DelayedSaturatedMMM.plot_channel_contribution_share_hdi([...])

rtype:

Figure

DelayedSaturatedMMM.plot_channel_contributions_grid(...)

Plots a grid of scaled channel contributions for a given grid of share values.

DelayedSaturatedMMM.plot_channel_parameter(...)

rtype:

Figure

DelayedSaturatedMMM.plot_components_contributions(...)

rtype:

Figure

DelayedSaturatedMMM.plot_direct_contribution_curves([...])

Plots the direct contribution curves for each marketing channel.

DelayedSaturatedMMM.plot_grouped_contribution_breakdown_over_time([...])

Plot a time series area chart for all channel contributions.

DelayedSaturatedMMM.plot_new_spend_contributions(...)

Plot the upcoming sales for a given spend amount.

DelayedSaturatedMMM.plot_posterior_predictive([...])

rtype:

Figure

DelayedSaturatedMMM.plot_prior_predictive([...])

rtype:

Figure

DelayedSaturatedMMM.plot_waterfall_components_decomposition([...])

This function creates a waterfall plot.

DelayedSaturatedMMM.predict(X_pred[, ...])

Uses model to predict on unseen data and return point prediction of all the samples.

DelayedSaturatedMMM.predict_posterior(X_pred)

Generate posterior predictive samples on unseen data.

DelayedSaturatedMMM.predict_proba(X_pred[, ...])

Alias for predict_posterior, for consistency with scikit-learn probabilistic estimators.

DelayedSaturatedMMM.preprocess(target, data)

Preprocess the provided data according to the specified target.

DelayedSaturatedMMM.sample_posterior_predictive(X_pred)

Sample from the model's posterior predictive distribution.

DelayedSaturatedMMM.sample_prior_predictive(X_pred)

Sample from the model's prior predictive distribution.

DelayedSaturatedMMM.save(fname)

Save the model's inference data to a file.

DelayedSaturatedMMM.set_idata_attrs([idata])

Set attributes on an InferenceData object.

DelayedSaturatedMMM.set_params(**params)

Set all the model parameters needed to instantiate the model, not including training data.

DelayedSaturatedMMM.validate(target, data)

Validates the input data based on the specified target type.

DelayedSaturatedMMM.validate_channel_columns(data)

rtype:

None

DelayedSaturatedMMM.validate_control_columns(data)

rtype:

None

DelayedSaturatedMMM.validate_date_col(data)

rtype:

None

DelayedSaturatedMMM.validate_target(data)

rtype:

None

Attributes

X

default_model_config

Returns a class default config dict for model builder if no model_config is provided on class initialization Useful for understanding structure of required model_config to allow its customization by users .

default_sampler_config

Returns a class default sampler dict for model builder if no sampler_config is provided on class initialization Useful for understanding structure of required sampler_config to allow its customization by users .

fit_result

id

Generate a unique hash value for the model.

methods

output_var

Defines target variable for the model

posterior_predictive

preprocessing_methods

A property that provides preprocessing methods for features ("X") and the target variable ("y").

prior

prior_predictive

validation_methods

A property that provides validation methods for features ("X") and the target variable ("y").

version

y

target_transformer

channel_columns

control_columns

model

date_column