Analysis¶
Counterfactual and marginal analysis over fitted models.
Analysis utilities for BayesianMMM.
This module provides helper classes for analyzing fitted Bayesian Marketing Mix Models, including counterfactual analysis, marginal contributions, and what-if scenarios.
- class mmm_framework.analysis.MarginalAnalysisResult(channel, current_spend, spend_increase, spend_increase_pct, marginal_contribution, marginal_roas, marginal_contribution_hdi_low=None, marginal_contribution_hdi_high=None, marginal_roas_hdi_low=None, marginal_roas_hdi_high=None, hdi_prob=None)[source]¶
Bases:
objectResult of marginal contribution analysis.
Attributes¶
- channelstr
Channel name.
- current_spendfloat
Current total spend in the period.
- spend_increasefloat
Absolute spend increase.
- spend_increase_pctfloat
Percentage spend increase.
- marginal_contributionfloat
Additional outcome from the spend increase (posterior mean).
- marginal_roasfloat
Return on additional spend (posterior mean).
- marginal_contribution_hdi_low, marginal_contribution_hdi_highfloat | None
Credible-interval bounds on the marginal contribution, propagated from the posterior.
Nonewhen uncertainty was not computed.- marginal_roas_hdi_low, marginal_roas_hdi_highfloat | None
Credible-interval bounds on the marginal ROAS.
Nonewhen uncertainty was not computed. The headline efficiency number should always be read with this interval – a marginal ROAS point estimate with no uncertainty is the §3.9 problem the framework set out to fix.- hdi_probfloat | None
Probability mass of the reported HDI (e.g. 0.94).
- __init__(channel, current_spend, spend_increase, spend_increase_pct, marginal_contribution, marginal_roas, marginal_contribution_hdi_low=None, marginal_contribution_hdi_high=None, marginal_roas_hdi_low=None, marginal_roas_hdi_high=None, hdi_prob=None)¶
- class mmm_framework.analysis.ScenarioResult(baseline_outcome, scenario_outcome, outcome_change, outcome_change_pct, spend_changes, baseline_prediction, scenario_prediction)[source]¶
Bases:
objectResult of a what-if scenario analysis.
Attributes¶
- baseline_outcomefloat
Total outcome under baseline scenario.
- scenario_outcomefloat
Total outcome under modified scenario.
- outcome_changefloat
Absolute change in outcome.
- outcome_change_pctfloat
Percentage change in outcome.
- spend_changesdict[str, dict]
Spend change details by channel.
- baseline_predictionNDArray
Full baseline prediction array.
- scenario_predictionNDArray
Full scenario prediction array.
- baseline_outcome: float¶
- scenario_outcome: float¶
- outcome_change: float¶
- outcome_change_pct: float¶
- spend_changes: dict[str, dict]¶
- baseline_prediction: NDArray¶
- scenario_prediction: NDArray¶
- __init__(baseline_outcome, scenario_outcome, outcome_change, outcome_change_pct, spend_changes, baseline_prediction, scenario_prediction)¶
- class mmm_framework.analysis.MMMAnalyzer(model)[source]¶
Bases:
objectAnalyzer for fitted BayesianMMM models.
Provides methods for: - Counterfactual contribution analysis - Marginal contribution analysis - What-if scenario modeling
Parameters¶
- modelBayesianMMM
A fitted BayesianMMM model.
Examples¶
>>> from mmm_framework.analysis import MMMAnalyzer >>> analyzer = MMMAnalyzer(fitted_model) >>> contributions = analyzer.compute_counterfactual_contributions() >>> print(contributions.summary())
>>> marginal = analyzer.compute_marginal_contributions(spend_increase_pct=10) >>> print(marginal)
- get_time_mask(time_period)[source]¶
Get time mask for filtering observations.
Parameters¶
- time_periodtuple[int, int] | None
(start_idx, end_idx) inclusive, or None for all.
Returns¶
- NDArray[np.bool_]
Boolean mask array.
- compute_counterfactual_contributions(time_period=None, channels=None, compute_uncertainty=True, hdi_prob=0.94, random_seed=None)[source]¶
Compute channel contributions using counterfactual analysis.
This is a convenience wrapper around the model’s method.
- Return type:
Parameters¶
- time_periodtuple[int, int], optional
Time period (start_idx, end_idx) for calculation.
- channelslist[str], optional
Channels to analyze. If None, uses all.
- compute_uncertaintybool
Whether to compute HDI for contributions.
- hdi_probfloat
HDI probability mass.
- random_seedint, optional
Random seed for reproducibility.
Returns¶
- ContributionResults
Contribution results container.
- compute_marginal_contributions(spend_increase_pct=10.0, time_period=None, channels=None, compute_uncertainty=True, hdi_prob=0.94, random_seed=None)[source]¶
Compute marginal contributions for a given spend increase.
This is a convenience wrapper around the model’s method.
- Return type:
Parameters¶
- spend_increase_pctfloat
Percentage increase in spend to simulate.
- time_periodtuple[int, int], optional
Time period for calculation.
- channelslist[str], optional
Channels to analyze. If None, uses all.
- compute_uncertaintybool
If True (default), propagate posterior uncertainty and include HDI bounds on marginal contribution and marginal ROAS.
- hdi_probfloat
Probability mass for the HDI.
- random_seedint, optional
Random seed for reproducibility.
Returns¶
- pd.DataFrame
Marginal contribution analysis (with HDI columns when
compute_uncertaintyis True).
- what_if_scenario(spend_changes, time_period=None, random_seed=None)[source]¶
Run a what-if scenario with custom spend changes.
This is a convenience wrapper around the model’s method.
- Return type:
Parameters¶
- spend_changesdict[str, float]
Mapping of channel names to spend multipliers.
- time_periodtuple[int, int], optional
Time period for calculation.
- random_seedint, optional
Random seed for reproducibility.
Returns¶
- dict
Scenario analysis results.
- compute_channel_roi(time_period=None, random_seed=None)[source]¶
Compute return on investment for each channel.
ROI = Total Contribution / Total Spend
- Return type:
Parameters¶
- time_periodtuple[int, int], optional
Time period for calculation.
- random_seedint, optional
Random seed for reproducibility.
Returns¶
- pd.DataFrame
ROI analysis by channel.
- compute_saturation_curves(channel, spend_range=None, n_points=50, random_seed=None)[source]¶
Compute saturation curve for a channel.
Shows how outcome changes across different spend levels.
- Return type:
Parameters¶
- channelstr
Channel to analyze.
- spend_rangetuple[float, float], optional
(min, max) spend range. If None, uses 0 to 2x current max.
- n_pointsint
Number of points on the curve.
- random_seedint, optional
Random seed.
Returns¶
- pd.DataFrame
Saturation curve data.
- mmm_framework.analysis.compute_contribution_summary(contributions)[source]¶
Create a summary DataFrame from contribution results.
- Return type:
Parameters¶
- contributionsContributionResults
Contribution analysis results.
Returns¶
- pd.DataFrame
Summary table.
- mmm_framework.analysis.compute_period_contributions(contributions, periods, period_names=None)[source]¶
Compute contributions for multiple time periods.
- Return type:
Parameters¶
- contributionsContributionResults
Base contribution results.
- periodslist[tuple[int, int]]
List of (start, end) period tuples.
- period_nameslist[str], optional
Names for each period.
Returns¶
- pd.DataFrame
Contributions by period.