Adapters Reference¶
mmm_eval.adapters
¶
Adapters for different MMM frameworks.
Classes¶
MeridianAdapter(config: MeridianConfig)
¶
Bases: BaseAdapter
Adapter for Google Meridian MMM framework.
Initialize the Meridian adapter.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config | MeridianConfig | MeridianConfig object | required |
Source code in mmm_eval/adapters/meridian.py
Attributes¶
media_channels: list[str]
property
¶
Return the channel names used by this adapter.
For Meridian, this returns the human-readable channel names from the config.
Returns List of channel names
primary_media_regressor_columns: list[str]
property
¶
Return the primary media regressor columns that should be perturbed in tests.
For Meridian, this depends on the configuration: - If channel_reach_columns is provided: returns empty list (not supported in perturbation tests) - If channel_impressions_columns is provided: returns channel_impressions_columns - Otherwise: returns channel_spend_columns
Returns List of column names that are used as primary media regressors in the model
primary_media_regressor_type: PrimaryMediaRegressor
property
¶
Return the type of primary media regressors used by the model.
For Meridian, this is determined by the configuration: - If channel_reach_columns is provided: returns PrimaryMediaRegressor.REACH_AND_FREQUENCY - If channel_impressions_columns is provided: returns PrimaryMediaRegressor.IMPRESSIONS - Otherwise: returns PrimaryMediaRegressor.SPEND
Returns PrimaryMediaRegressor enum value
Functions¶
fit(data: pd.DataFrame, max_train_date: pd.Timestamp | None = None) -> None
¶
Fit the Meridian model to data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | Training data | required |
max_train_date | Timestamp | None | Optional maximum training date for holdout validation | None |
Source code in mmm_eval/adapters/meridian.py
fit_and_predict(train: pd.DataFrame, test: pd.DataFrame) -> np.ndarray
¶
Fit the Meridian model and make predictions given new input data.
The full dataset must be passed to fit()
, since making out-of-sample predictions is only possible by way of specifying a holdout mask when sampling from the posterior.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
train | DataFrame | Training data | required |
test | DataFrame | Test data | required |
Returns:
Type | Description |
---|---|
ndarray | Predicted values for the test period |
Source code in mmm_eval/adapters/meridian.py
get_channel_names() -> list[str]
¶
Get the channel names that would be used as the index in get_channel_roi results.
For Meridian, this returns the media_channels which are the human-readable channel names used in the ROI results.
Returns List of channel names
Source code in mmm_eval/adapters/meridian.py
get_channel_roi(start_date: pd.Timestamp | None = None, end_date: pd.Timestamp | None = None) -> pd.Series
¶
Get channel ROI estimates.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_date | Timestamp | None | Optional start date for ROI calculation | None |
end_date | Timestamp | None | Optional end date for ROI calculation | None |
Returns:
Type | Description |
---|---|
Series | Series containing ROI estimates for each channel |
Source code in mmm_eval/adapters/meridian.py
predict(data: pd.DataFrame | None = None) -> np.ndarray
¶
Make predictions using the fitted model.
This returns predictions for the entirety of the dataset passed to fit() unless max_train_date
is specified when calling fit(); in that case it only returns predictions for the time periods indicated by the holdout mask.
Note: Meridian doesn't require input data for prediction - it uses the fitted model state, so the data
argument will be ignored if passed.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | None | Ignored - Meridian uses the fitted model state for predictions. | None |
Returns:
Type | Description |
---|---|
ndarray | Predicted values |
Raises:
Type | Description |
---|---|
RuntimeError | If model is not fitted |
Source code in mmm_eval/adapters/meridian.py
PyMCAdapter(config: PyMCConfig)
¶
Bases: BaseAdapter
Initialize the PyMCAdapter.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config | PyMCConfig | PyMCConfig object | required |
Source code in mmm_eval/adapters/pymc.py
Attributes¶
media_channels: list[str]
property
¶
Return the channel names used by this adapter.
For PyMC, this returns the channel_spend_columns which are used as the channel names in ROI results.
Returns List of channel names
primary_media_regressor_columns: list[str]
property
¶
Return the primary media regressor columns that should be perturbed in tests.
For PyMC, this is always the channel_spend_columns
since the PyMC adapter uses spend as the primary regressor in the model.
Returns List of channel spend column names
primary_media_regressor_type: PrimaryMediaRegressor
property
¶
Return the type of primary media regressors used by this adapter.
For PyMC, this is always SPEND since the PyMC adapter uses spend as the primary regressor.
Returns PrimaryMediaRegressor.SPEND
Functions¶
fit(data: pd.DataFrame) -> None
¶
Fit the model and compute ROIs.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | DataFrame containing the training data adhering to the PyMCInputDataSchema. | required |
Source code in mmm_eval/adapters/pymc.py
fit_and_predict(train: pd.DataFrame, test: pd.DataFrame) -> np.ndarray
¶
Fit on training data and make predictions on test data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
train | DataFrame | training dataset | required |
test | DataFrame | test dataset | required |
Returns:
Type | Description |
---|---|
ndarray | model predictions. |
Source code in mmm_eval/adapters/pymc.py
get_channel_names() -> list[str]
¶
Get the channel names that would be used as the index in get_channel_roi results.
For PyMC, this returns the channel_spend_columns
which are used as the index in the ROI results.
Returns List of channel names
Source code in mmm_eval/adapters/pymc.py
get_channel_roi(start_date: pd.Timestamp | None = None, end_date: pd.Timestamp | None = None) -> pd.Series
¶
Return the ROIs for each channel, optionally within a given date range.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_date | Timestamp | None | Optional start date for ROI calculation | None |
end_date | Timestamp | None | Optional end date for ROI calculation | None |
Returns:
Type | Description |
---|---|
Series | Series containing ROI estimates for each channel |
Source code in mmm_eval/adapters/pymc.py
predict(data: pd.DataFrame | None = None) -> np.ndarray
¶
Predict the response variable for new data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | None | Input data for prediction. This parameter is required for PyMC predictions and cannot be None. | None |
Returns:
Type | Description |
---|---|
ndarray | Predicted values |
Raises:
Type | Description |
---|---|
RuntimeError | If model is not fitted |
ValueError | If data is None (PyMC requires data for prediction) |
Source code in mmm_eval/adapters/pymc.py
Functions¶
get_adapter(framework: str, config: PyMCConfig | MeridianConfig)
¶
Get an adapter instance for the specified framework.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
framework | str | Name of the MMM framework | required |
config | PyMCConfig | MeridianConfig | Framework-specific configuration | required |
Returns:
Type | Description |
---|---|
Adapter instance |
Raises:
Type | Description |
---|---|
ValueError | If framework is not supported |
Source code in mmm_eval/adapters/__init__.py
Modules¶
base
¶
Base adapter class for MMM frameworks.
Classes¶
BaseAdapter(config: dict[str, Any] | None = None)
¶
Bases: ABC
Base class for MMM framework adapters.
Initialize the base adapter.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config | dict[str, Any] | None | Configuration dictionary | None |
Source code in mmm_eval/adapters/base.py
media_channels: list[str]
abstractmethod
property
¶Return the channel names used by this adapter.
This property provides a consistent way to get channel names across different adapters. For most frameworks, this will be human-readable channel names, but for PyMC it may be the column names themselves.
Returns List of channel names used by this adapter
primary_media_regressor_columns: list[str]
abstractmethod
property
¶Return the primary media regressor columns that should be perturbed in tests.
This property returns the columns that are actually used as regressors in the model. For most frameworks, this will be the spend columns, but for e.g. Meridian it could be impressions or reach/frequency columns depending on the configuration.
Returns List of column names that are used as primary media regressors in the model
primary_media_regressor_type: PrimaryMediaRegressor
abstractmethod
property
¶Return the type of primary media regressors used by this adapter.
This property indicates what type of regressors are used as primary inputs to the model, which determines what should be perturbed in tests.
Returns PrimaryMediaRegressor enum value indicating the type of primary media regressors
fit(data: pd.DataFrame) -> None
abstractmethod
¶fit_and_predict(train: pd.DataFrame, test: pd.DataFrame) -> np.ndarray
abstractmethod
¶Fit on training data and make predictions on test data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
train | DataFrame | dataset to train model on | required |
test | DataFrame | dataset to make predictions using | required |
Returns:
Type | Description |
---|---|
ndarray | Predicted values. |
Source code in mmm_eval/adapters/base.py
get_channel_names() -> list[str]
abstractmethod
¶Get the channel names that would be used as the index in channel ROI results.
This method provides a consistent way to get channel names across different adapters without needing to call get_channel_roi() (which requires the model to be fitted).
Returns List of channel names that would be used as the index in get_channel_roi results
Source code in mmm_eval/adapters/base.py
get_channel_roi(start_date: pd.Timestamp | None = None, end_date: pd.Timestamp | None = None) -> pd.Series
abstractmethod
¶Get channel ROI estimates.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_date | Timestamp | None | Optional start date for ROI calculation | None |
end_date | Timestamp | None | Optional end date for ROI calculation | None |
Returns:
Type | Description |
---|---|
Series | Series containing ROI estimates for each channel |
Source code in mmm_eval/adapters/base.py
predict(data: pd.DataFrame | None = None) -> np.ndarray
abstractmethod
¶Make predictions on new data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | None | Input data for prediction. Behavior varies by adapter: - Some adapters (e.g., PyMC) require this parameter and will raise an error if None is passed - Other adapters (e.g., Meridian) ignore this parameter and use the fitted model state instead | None |
Returns:
Type | Description |
---|---|
ndarray | Predicted values |
Source code in mmm_eval/adapters/base.py
PrimaryMediaRegressor
¶
Bases: StrEnum
Enum for primary media regressor types used in MMM frameworks.
meridian
¶
Google Meridian adapter for MMM evaluation.
Classes¶
MeridianAdapter(config: MeridianConfig)
¶
Bases: BaseAdapter
Adapter for Google Meridian MMM framework.
Initialize the Meridian adapter.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config | MeridianConfig | MeridianConfig object | required |
Source code in mmm_eval/adapters/meridian.py
media_channels: list[str]
property
¶Return the channel names used by this adapter.
For Meridian, this returns the human-readable channel names from the config.
Returns List of channel names
primary_media_regressor_columns: list[str]
property
¶Return the primary media regressor columns that should be perturbed in tests.
For Meridian, this depends on the configuration: - If channel_reach_columns is provided: returns empty list (not supported in perturbation tests) - If channel_impressions_columns is provided: returns channel_impressions_columns - Otherwise: returns channel_spend_columns
Returns List of column names that are used as primary media regressors in the model
primary_media_regressor_type: PrimaryMediaRegressor
property
¶Return the type of primary media regressors used by the model.
For Meridian, this is determined by the configuration: - If channel_reach_columns is provided: returns PrimaryMediaRegressor.REACH_AND_FREQUENCY - If channel_impressions_columns is provided: returns PrimaryMediaRegressor.IMPRESSIONS - Otherwise: returns PrimaryMediaRegressor.SPEND
Returns PrimaryMediaRegressor enum value
fit(data: pd.DataFrame, max_train_date: pd.Timestamp | None = None) -> None
¶Fit the Meridian model to data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | Training data | required |
max_train_date | Timestamp | None | Optional maximum training date for holdout validation | None |
Source code in mmm_eval/adapters/meridian.py
fit_and_predict(train: pd.DataFrame, test: pd.DataFrame) -> np.ndarray
¶Fit the Meridian model and make predictions given new input data.
The full dataset must be passed to fit()
, since making out-of-sample predictions is only possible by way of specifying a holdout mask when sampling from the posterior.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
train | DataFrame | Training data | required |
test | DataFrame | Test data | required |
Returns:
Type | Description |
---|---|
ndarray | Predicted values for the test period |
Source code in mmm_eval/adapters/meridian.py
get_channel_names() -> list[str]
¶Get the channel names that would be used as the index in get_channel_roi results.
For Meridian, this returns the media_channels which are the human-readable channel names used in the ROI results.
Returns List of channel names
Source code in mmm_eval/adapters/meridian.py
get_channel_roi(start_date: pd.Timestamp | None = None, end_date: pd.Timestamp | None = None) -> pd.Series
¶Get channel ROI estimates.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_date | Timestamp | None | Optional start date for ROI calculation | None |
end_date | Timestamp | None | Optional end date for ROI calculation | None |
Returns:
Type | Description |
---|---|
Series | Series containing ROI estimates for each channel |
Source code in mmm_eval/adapters/meridian.py
predict(data: pd.DataFrame | None = None) -> np.ndarray
¶Make predictions using the fitted model.
This returns predictions for the entirety of the dataset passed to fit() unless max_train_date
is specified when calling fit(); in that case it only returns predictions for the time periods indicated by the holdout mask.
Note: Meridian doesn't require input data for prediction - it uses the fitted model state, so the data
argument will be ignored if passed.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | None | Ignored - Meridian uses the fitted model state for predictions. | None |
Returns:
Type | Description |
---|---|
ndarray | Predicted values |
Raises:
Type | Description |
---|---|
RuntimeError | If model is not fitted |
Source code in mmm_eval/adapters/meridian.py
Functions¶
construct_holdout_mask(max_train_date: pd.Timestamp, time_index: np.ndarray) -> np.ndarray
¶
Construct a boolean mask for holdout period identification.
This function creates a boolean mask that identifies which time periods fall into the holdout/test period (after the maximum training date). The mask can be used to separate training and test data or to filter predictions to only the holdout period.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
max_train_date | Timestamp | The maximum date to be considered part of the training period. All dates after this will be marked as holdout/test data. | required |
time_index | ndarray | Array-like object containing the time index to be masked. Can be any format that pandas.to_datetime can convert. | required |
Returns:
Type | Description |
---|---|
ndarray | A boolean array of the same length as time_index, where True indicates |
ndarray | the time period is in the holdout/test set (after max_train_date). |
Example
time_index = pd.date_range('2023-01-01', '2023-12-31', freq='D') max_train_date = pd.Timestamp('2023-06-30') mask = construct_holdout_mask(max_train_date, time_index)
mask will be True for dates from 2023-07-01 onwards¶
Source code in mmm_eval/adapters/meridian.py
construct_meridian_data_object(df: pd.DataFrame, config: MeridianConfig) -> pd.DataFrame
¶
Construct a Meridian data object from a pandas DataFrame.
This function transforms a standard DataFrame into the format required by the Meridian framework. It handles the conversion of revenue to revenue_per_kpi, and configures the data builder with various components including KPI, population, controls, media channels (with different types: reach/frequency, impressions, or spend-only), organic media, and non-media treatments.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
df | DataFrame | Input DataFrame containing the raw data with columns for dates, response, revenue, media spend, and other variables as specified in the config. | required |
config | MeridianConfig | MeridianConfig object containing the configuration for data transformation including column mappings and feature specifications. | required |
Returns:
Type | Description |
---|---|
DataFrame | A Meridian data object built from the input DataFrame according to the config. |
Note
The function modifies the input DataFrame by: - Converting revenue to revenue_per_kpi (revenue / response) - Dropping the original revenue column - Adding various media and control components based on config - Validating that media channels have sufficient variation (non-zero spend)
Raises:
Type | Description |
---|---|
ValueError | If a media channel has zero spend across all time periods and geos, as this would cause Meridian to fail or produce unreliable results. |
Source code in mmm_eval/adapters/meridian.py
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
|
pymc
¶
PyMC MMM framework adapter.
N.B. we expect control variables to be scaled to [-1, 1] using maxabs scaling BEFORE being passed to the PyMCAdapter.
Classes¶
PyMCAdapter(config: PyMCConfig)
¶
Bases: BaseAdapter
Initialize the PyMCAdapter.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
config | PyMCConfig | PyMCConfig object | required |
Source code in mmm_eval/adapters/pymc.py
media_channels: list[str]
property
¶Return the channel names used by this adapter.
For PyMC, this returns the channel_spend_columns which are used as the channel names in ROI results.
Returns List of channel names
primary_media_regressor_columns: list[str]
property
¶Return the primary media regressor columns that should be perturbed in tests.
For PyMC, this is always the channel_spend_columns
since the PyMC adapter uses spend as the primary regressor in the model.
Returns List of channel spend column names
primary_media_regressor_type: PrimaryMediaRegressor
property
¶Return the type of primary media regressors used by this adapter.
For PyMC, this is always SPEND since the PyMC adapter uses spend as the primary regressor.
Returns PrimaryMediaRegressor.SPEND
fit(data: pd.DataFrame) -> None
¶Fit the model and compute ROIs.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | DataFrame containing the training data adhering to the PyMCInputDataSchema. | required |
Source code in mmm_eval/adapters/pymc.py
fit_and_predict(train: pd.DataFrame, test: pd.DataFrame) -> np.ndarray
¶Fit on training data and make predictions on test data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
train | DataFrame | training dataset | required |
test | DataFrame | test dataset | required |
Returns:
Type | Description |
---|---|
ndarray | model predictions. |
Source code in mmm_eval/adapters/pymc.py
get_channel_names() -> list[str]
¶Get the channel names that would be used as the index in get_channel_roi results.
For PyMC, this returns the channel_spend_columns
which are used as the index in the ROI results.
Returns List of channel names
Source code in mmm_eval/adapters/pymc.py
get_channel_roi(start_date: pd.Timestamp | None = None, end_date: pd.Timestamp | None = None) -> pd.Series
¶Return the ROIs for each channel, optionally within a given date range.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
start_date | Timestamp | None | Optional start date for ROI calculation | None |
end_date | Timestamp | None | Optional end date for ROI calculation | None |
Returns:
Type | Description |
---|---|
Series | Series containing ROI estimates for each channel |
Source code in mmm_eval/adapters/pymc.py
predict(data: pd.DataFrame | None = None) -> np.ndarray
¶Predict the response variable for new data.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
data | DataFrame | None | Input data for prediction. This parameter is required for PyMC predictions and cannot be None. | None |
Returns:
Type | Description |
---|---|
ndarray | Predicted values |
Raises:
Type | Description |
---|---|
RuntimeError | If model is not fitted |
ValueError | If data is None (PyMC requires data for prediction) |
Source code in mmm_eval/adapters/pymc.py
schemas
¶
Classes¶
MeridianInputDataBuilderSchema
¶
Bases: BaseModel
Schema for Meridian input data builder configuration.
These arguments are passed to the DataFrameInputDataBuilder class for constructing a data object to be fed into the Meridian model.
See here for how to determine whether to consider a particular feature a non-media treatment or a control: https://developers.google.com/meridian/docs/advanced-modeling/organic-and-non-media-variables?hl=en
validate_media_channels(v)
¶Validate media columns are not empty.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v | Media columns value | required |
Returns:
Type | Description |
---|---|
Validated value |
Raises:
Type | Description |
---|---|
ValueError | If media columns is empty |
Source code in mmm_eval/adapters/schemas.py
validate_organic_media_fields(v, info)
¶Validate that exactly zero or two of organic_media_columns and organic_media_channels are provided.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v | The value being validated | required | |
info | Validation info containing the field name | required |
Returns:
Type | Description |
---|---|
Validated value |
Raises:
Type | Description |
---|---|
ValueError | If exactly zero or two of the fields are not provided |
Source code in mmm_eval/adapters/schemas.py
validate_reach_frequency_columns(v, info)
¶Validate that exactly zero or two of channel_reach_columns and channel_frequency_columns are provided.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v | The value being validated | required | |
info | Validation info containing the field name | required |
Returns:
Type | Description |
---|---|
Validated value |
Raises:
Type | Description |
---|---|
ValueError | If exactly zero or two of the fields are not provided |
Source code in mmm_eval/adapters/schemas.py
validate_reach_impressions_mutual_exclusion()
¶Validate that channel_reach_columns and channel_impressions_columns are not both provided.
Returns Self
Raises ValueError: If both fields are provided
Source code in mmm_eval/adapters/schemas.py
MeridianModelSpecSchema
¶
Bases: BaseModel
Schema for Meridian ModelSpec configuration.
MeridianSamplePosteriorSchema
¶
MeridianStringConfigSchema
¶
Bases: BaseModel
Schema for Meridian evaluation config dictionary.
PyMCFitSchema
¶
Bases: BaseModel
Schema for PyMC Fit Configuration.
Defaults are all set to None so that the user can provide only the values they want to change. If a user does not provide a value, we will let the latest PYMC defaults be used in model instantiation.
PyMCModelSchema
¶
Bases: BaseModel
Schema for PyMC Config Dictionary.
validate_adstock(v)
¶Validate adstock component.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v | Adstock value | required |
Returns:
Type | Description |
---|---|
Validated value |
Raises:
Type | Description |
---|---|
ValueError | If adstock is not a valid type |
Source code in mmm_eval/adapters/schemas.py
validate_channel_columns(v)
¶Validate channel columns are not empty.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v | Channel columns value | required |
Returns:
Type | Description |
---|---|
Validated value |
Raises:
Type | Description |
---|---|
ValueError | If channel columns is empty |
Source code in mmm_eval/adapters/schemas.py
validate_saturation(v)
¶Validate saturation component.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
v | Saturation value | required |
Returns:
Type | Description |
---|---|
Validated value |
Raises:
Type | Description |
---|---|
ValueError | If saturation is not a valid type |
Source code in mmm_eval/adapters/schemas.py
PyMCStringConfigSchema
¶
Bases: BaseModel
Schema for PyMC Evaluation Config Dictionary.