deepcausalmmm.postprocess.optimization_utils

Utility functions for budget optimization with DeepCausalMMM.

This module provides helper functions to prepare data from DeepCausalMMM model outputs for budget optimization, including data formatting, curve parameter extraction, and integration with ResponseCurveFit.

Functions

compare_current_vs_optimal(...[, metric_name])

Compare current budget allocation vs optimized allocation.

create_optimizer_from_model_output(...[, ...])

End-to-end: Create optimizer from DeepCausalMMM model outputs.

fit_response_curves_batch(data[, channels, ...])

Fit response curves for multiple channels in batch.

generate_optimization_report(result, curves_df)

Generate a comprehensive text report of optimization results.

prepare_optimization_data(contributions_df, ...)

Prepare data from DeepCausalMMM outputs for response curve fitting and optimization.

deepcausalmmm.postprocess.optimization_utils.prepare_optimization_data(contributions_df: DataFrame, media_data: DataFrame, *, date_col: str = 'week_monday', channel_col: str = 'channel', contribution_col: str = 'predicted', spend_col: str = 'spend', impressions_col: str = 'impressions') DataFrame[source]

Prepare data from DeepCausalMMM outputs for response curve fitting and optimization.

This function merges model contribution predictions with media spend/impression data to create the required format for ResponseCurveFit.

Parameters:
  • contributions_df (pd.DataFrame) – Model contributions output with columns: date, channel, predicted

  • media_data (pd.DataFrame) – Media data with columns: date, channel, spend, impressions

  • date_col (str, default='week_monday') – Name of the date column

  • channel_col (str, default='channel') – Name of the channel column

  • contribution_col (str, default='predicted') – Name of the contribution/prediction column

  • spend_col (str, default='spend') – Name of the spend column

  • impressions_col (str, default='impressions') – Name of the impressions column

Returns:

Merged data ready for ResponseCurveFit with columns: week_monday, channel, spend, impressions, predicted

Return type:

pd.DataFrame

Examples

>>> # After training DeepCausalMMM model
>>> contributions = model.get_contributions()  # Your model output
>>> media_df = pd.read_csv('media_data.csv')
>>>
>>> optimization_data = prepare_optimization_data(
...     contributions_df=contributions,
...     media_data=media_df
... )
deepcausalmmm.postprocess.optimization_utils.fit_response_curves_batch(data: DataFrame, channels: List[str] | None = None, *, bottom_param: bool = False, model_level: str = 'Overall', date_col: str = 'week_monday', generate_figures: bool = False, save_figures: bool = False, output_dir: str | None = None) Tuple[Dict[str, Dict], DataFrame][source]

Fit response curves for multiple channels in batch.

This is a convenience wrapper around ResponseCurveFit that processes multiple channels and returns both dictionary and DataFrame formats.

Parameters:
  • data (pd.DataFrame) – Data prepared by prepare_optimization_data() with columns: week_monday, channel, spend, impressions, predicted

  • channels (List[str], optional) – List of channels to fit. If None, fits all channels in data

  • bottom_param (bool, default=False) – Whether to fit non-zero intercept

  • model_level (str, default='Overall') – Aggregation level: ‘Overall’ or ‘DMA’

  • date_col (str, default='week_monday') – Name of date column

  • generate_figures (bool, default=False) – Whether to generate plots

  • save_figures (bool, default=False) – Whether to save plots to files

  • output_dir (str, optional) – Directory to save plots (required if save_figures=True)

Returns:

  • curves_dict (Dict[str, Dict]) – Response curve parameters by channel

  • curves_df (pd.DataFrame) – Response curve parameters as DataFrame

Examples

>>> # After preparing data
>>> curves_dict, curves_df = fit_response_curves_batch(
...     data=optimization_data,
...     channels=['TV', 'Search', 'Social'],
...     generate_figures=True,
...     save_figures=True,
...     output_dir='./response_curves/'
... )
>>> print(curves_df)
deepcausalmmm.postprocess.optimization_utils.create_optimizer_from_model_output(contributions_df: DataFrame, media_data: DataFrame, budget: float, *, channels: List[str] | None = None, num_weeks: int = 52, constraints: Dict[str, Dict[str, float]] | None = None, method: str = 'trust-constr', generate_figures: bool = False, save_figures: bool = False, output_dir: str | None = None) Tuple[BudgetOptimizer, DataFrame][source]

End-to-end: Create optimizer from DeepCausalMMM model outputs.

This function handles the complete workflow: 1. Prepare data from model outputs 2. Fit response curves for all channels 3. Create and configure BudgetOptimizer

Parameters:
  • contributions_df (pd.DataFrame) – Model contribution predictions

  • media_data (pd.DataFrame) – Media spend and impression data

  • budget (float) – Total budget to optimize

  • channels (List[str], optional) – Channels to include. If None, uses all channels

  • num_weeks (int, default=52) – Planning horizon in weeks

  • constraints (Dict[str, Dict[str, float]], optional) – Channel spend constraints

  • method (str, default='trust-constr') – Optimization method

  • generate_figures (bool, default=False) – Whether to generate response curve plots

  • save_figures (bool, default=False) – Whether to save plots

  • output_dir (str, optional) – Directory for plots

Returns:

  • optimizer (BudgetOptimizer) – Configured optimizer ready to run

  • curves_df (pd.DataFrame) – Response curve parameters

Examples

>>> # Complete workflow from model outputs to optimizer
>>> optimizer, curves = create_optimizer_from_model_output(
...     contributions_df=model_contributions,
...     media_data=media_df,
...     budget=1000000,
...     constraints={'TV': {'lower': 100000, 'upper': 600000}},
...     generate_figures=True,
...     save_figures=True,
...     output_dir='./optimization_results/'
... )
>>>
>>> # Run optimization
>>> result = optimizer.optimize()
>>> print(result.allocation)
deepcausalmmm.postprocess.optimization_utils.compare_current_vs_optimal(current_allocation: Dict[str, float], optimal_result: OptimizationResult, *, metric_name: str = 'Response') DataFrame[source]

Compare current budget allocation vs optimized allocation.

Parameters:
  • current_allocation (Dict[str, float]) – Current spend by channel

  • optimal_result (OptimizationResult) – Result from optimizer.optimize()

  • metric_name (str, default='Response') – Name of the metric being optimized

Returns:

Comparison table with current, optimal, and deltas

Return type:

pd.DataFrame

Examples

>>> current = {'TV': 400000, 'Search': 350000, 'Social': 250000}
>>> result = optimizer.optimize()
>>>
>>> comparison = compare_current_vs_optimal(current, result)
>>> print(comparison)
deepcausalmmm.postprocess.optimization_utils.generate_optimization_report(result: OptimizationResult, curves_df: DataFrame, current_allocation: Dict[str, float] | None = None, *, output_path: str | None = None) str[source]

Generate a comprehensive text report of optimization results.

Parameters:
  • result (OptimizationResult) – Optimization result

  • curves_df (pd.DataFrame) – Response curve parameters

  • current_allocation (Dict[str, float], optional) – Current allocation for comparison

  • output_path (str, optional) – Path to save report (if not provided, returns as string)

Returns:

Formatted report text

Return type:

str

Examples

>>> report = generate_optimization_report(
...     result=result,
...     curves_df=curves,
...     current_allocation={'TV': 400000, 'Search': 350000, 'Social': 250000},
...     output_path='optimization_report.txt'
... )
>>> print(report)