src.driver.opt¶
Provides functions for marketing budget optimisation and scenario planning.
This module includes utilities for calculating budget bounds, total budget, and functions to orchestrate the optimisation process and scenario planning using a fitted MMM model.
Module Contents¶
- src.driver.opt.get_lower_and_upper_bounds(media: pandas.DataFrame, n_time_periods: int, lower_pct: numpy.ndarray, upper_pct: numpy.ndarray) Tuple[numpy.ndarray, numpy.ndarray]¶
Calculates lower and upper bounds based on historical media spend.
- Parameters:
media – DataFrame with historical media spending data (channels as columns).
n_time_periods – Number of future periods to optimise for (e.g., weeks, months).
lower_pct – Array of percentages to decrease from the mean for lower bounds.
upper_pct – Array of percentages to increase from the mean for upper bounds.
- Returns:
A tuple containing lower_bounds and upper_bounds.
- src.driver.opt.calculate_total_budget(mean_costs: numpy.ndarray | pandas.Series, n_time_periods: int) float¶
Calculates the total budget based on mean media costs and number of time periods.
- Parameters:
mean_costs – Array or Series of mean costs for each media channel.
n_time_periods – Number of time periods to optimise for.
- Returns:
Total budget as a scalar.
- src.driver.opt.optimize_marketing_budget(model: src.core.base.BaseMMM, data: pandas.DataFrame, config: Dict[str, Any], results_dir: str, total_budget: float | None = None, frequency: str = 'M', n_time_periods: int = 1, run_scenarios: bool = True, scenario_percentages: List[int] = [-20, -15, -10, -5, 0, 5, 10, 15, 20], multiperiod_mode: bool = False, use_seasonality: bool = False, start_date: str | None = None) None¶
Loads spending data and optimises the marketing budget.
Sets dynamic budget bounds based on actual historical spending and optimises the marketing budget. Saves a plot of the budget optimisation and a CSV file with numerical results.
- Parameters:
model – The fitted MMM model.
data – DataFrame with historical data, including a ‘date’ column and media spend columns.
config – Configuration dictionary containing media channel definitions (e.g., spend column names).
results_dir – Directory to save output plot and CSV file.
total_budget – Total marketing budget. If None, it’s calculated from mean historical spend. Defaults to None.
frequency – Aggregation frequency for historical data (‘W’ for weekly, ‘M’ for monthly, ‘Q’ for quarterly). Defaults to ‘M’.
n_time_periods – Number of future time periods to optimise for. Defaults to 1.
run_scenarios – Whether to run multiple budget scenarios. Defaults to True.
scenario_percentages – Percentage changes for scenarios. Defaults to [-20, -15, -10, -5, 0, 5, 10, 15, 20].
multiperiod_mode – Whether to run multi-period optimization. Defaults to False.
use_seasonality – Whether to apply seasonal adjustments (only for multiperiod_mode). Defaults to False.
start_date – Planning start date for multi-period mode (YYYY-MM-DD). Defaults to None (uses today).
- src.driver.opt.scenario_budget_planning(model: src.core.base.BaseMMM, data: pandas.DataFrame, config: Dict[str, Any], results_dir: str, scenario_percentages: List[int] = [-20, -15, -10, -5, 0, 5, 10, 15, 20], frequency: str = 'M', n_time_periods: int = 1) pandas.DataFrame¶
Run multiple budget scenarios with different percentage constraints.
Creates and compares multiple budget allocation scenarios with different total budget levels. Each scenario optimizes channel allocation within the given total budget constraint. Results are saved as CSV and visualized with comparison charts.
- Parameters:
model – The fitted MMM model.
data – DataFrame with historical data, including a ‘date’ column and media spend columns.
config – Configuration dictionary containing media channel definitions (e.g., spend column names).
results_dir – Directory to save output plots and CSV file.
scenario_percentages – List of percentage changes to run as scenarios. Defaults to [-20, -15, -10, -5, 0, 5, 10, 15, 20].
frequency – Aggregation frequency for historical data (‘W’ for weekly, ‘M’ for monthly, ‘Q’ for quarterly). Defaults to ‘M’.
n_time_periods – Number of future time periods to optimise for. Defaults to 1.
- Returns:
DataFrame with all scenario results
- src.driver.opt.extract_channel_seasonality(model: src.core.base.BaseMMM, start_date: pandas.Timestamp, n_periods: int, frequency: str = 'W', baseline_effectiveness: float = 1.0, results_dir: str | None = None, media_channels: List[str] | None = None) Dict[int, Dict[str, float]]¶
Extract seasonal effectiveness patterns from fitted MMM model.
Uses Prophet’s seasonal decomposition to estimate how channel effectiveness varies over time. Returns multipliers where 1.0 = baseline, >1.0 = more effective, <1.0 = less effective.
- Parameters:
model – Fitted MMM model with Prophet seasonality components.
start_date – Start date for planning horizon.
n_periods – Number of periods to extract seasonality for.
frequency – Time frequency (‘W’ for weekly, ‘M’ for monthly). Defaults to ‘W’.
baseline_effectiveness – Base effectiveness when no seasonality data available. Defaults to 1.0.
results_dir – Directory containing saved Prophet model. Defaults to None.
- Returns:
Dictionary mapping period index to channel effectiveness multipliers. Format: {period_idx: {channel: effectiveness_multiplier}}.
Example
>>> start = pd.Timestamp('2025-01-01') >>> seasonal_effects = extract_channel_seasonality( ... model=fitted_model, ... start_date=start, ... n_periods=13, ... frequency='W', ... results_dir='results' ... ) >>> seasonal_effects[0]['google'] # Week 0 effectiveness for Google 0.95
- src.driver.opt.optimize_multiperiod_budget(model: src.core.base.BaseMMM, data: pandas.DataFrame, config: Dict[str, Any], results_dir: str, n_periods: int = 13, total_budget: float | None = None, use_seasonality: bool = True, frequency: str = 'W', start_date: str | None = None, lower_bound_pct: float = 0.2, upper_bound_pct: float = 0.2, period_budget_limits: Tuple[float, float] | None = None) pandas.DataFrame¶
Optimize budget allocation across multiple time periods.
This function orchestrates multi-period budget optimization by: 1. Extracting seasonality patterns from the model 2. Setting up budget constraints 3. Running optimization across all periods 4. Formatting and saving results
- Parameters:
model – Fitted MMM model.
data – Historical data DataFrame.
config – Configuration dictionary with media channel definitions.
results_dir – Directory to save output files.
n_periods – Number of periods to optimize over. Defaults to 13 (weeks).
total_budget – Total budget across all periods. If None, calculated from historical data. Defaults to None.
use_seasonality – Whether to apply seasonal adjustments. Defaults to True.
frequency – Time frequency (‘W’, ‘M’, ‘D’). Defaults to ‘W’.
start_date – Planning start date (YYYY-MM-DD). If None, uses today. Defaults to None.
lower_bound_pct – Percentage below mean for lower bounds. Defaults to 0.20.
upper_bound_pct – Percentage above mean for upper bounds. Defaults to 0.20.
period_budget_limits – Optional (min, max) budget per period. Defaults to None.
- Returns:
DataFrame with multi-period optimization results.
Example
>>> results = optimize_multiperiod_budget( ... model=fitted_model, ... data=historical_data, ... config=model_config, ... results_dir='results', ... n_periods=13, ... total_budget=12_500_000 ... )
- src.driver.opt.plot_multiperiod_results(results_df: pandas.DataFrame, n_periods: int, results_dir: str) None¶
Create visualizations for multi-period optimization results.
- Parameters:
results_df – DataFrame with multi-period optimization results
n_periods – Number of periods optimized
results_dir – Directory to save plots
- src.driver.opt.plot_scenario_comparison(results_df: pandas.DataFrame, model: src.core.base.BaseMMM, results_dir: str) None¶
Create visualizations comparing the different budget scenarios.
- Parameters:
results_df – DataFrame with all scenario results
model – The fitted MMM model
results_dir – Directory to save plots