Guide: Performing Budget Optimisation¶
This guide explains how to use the budget optimisation features within the Abacus library.
Overview¶
Budget optimisation aims to find the allocation of a total marketing budget across different channels that is predicted to maximise the overall contribution (e.g., sales, conversions), based on the fitted MMM and the estimated response curves for each channel.
Prerequisites¶
Fitted Model: You need a fitted
DelayedSaturatedMMMmodel instance (usually obtained after running the main driver script). The model fitting process estimates the necessary response curve parameters.Results: The optimisation typically uses results stored in the
idataobject and potentially decomposed contributions.
Running the Optimisation¶
The optimisation process is typically executed automatically as part of the main driver script (e.g., demo/runme.py) after the model fitting is complete. The abacus.driver.opt.OptimisationDriver class likely orchestrates this process, calling methods on the fitted model instance.
Standard Workflow (using Driver):
Configuration: Ensure your
config.yamlis set up correctly (see Configuration Guide). There isn’t usually a specific flag to enable optimisation; it’s often run by default. Configuration might influence budget constraints or the number of optimisation steps, although specific parameters for this are not detailed in the basic configuration guide.Execution: Run the main driver script (e.g.,
python -m demo.runme). The driver fits the model and then proceeds to the optimisation step.Output: Check the
results/directory for optimisation outputs, typically including:budget_optimisation.png: A plot comparing initial vs. optimised budgets and contributions.optimization_results.csv: A CSV file detailing the initial budget, optimal budget, initial contribution, and optimised contribution for each channel.
Underlying Mechanism (Conceptual):
While typically handled by the driver, the core optimisation logic involves methods within the fitted model class (e.g., DelayedSaturatedMMM):
# --- Conceptual Example ---
# Assuming 'model' is a fitted DelayedSaturatedMMM instance
# Assuming 'total_budget' is defined
# Assuming 'response_curve_method' is 'sigmoid' or 'michaelis-menten' (as supported by the model)
# 1. Estimate response curve parameters for the chosen method
# (This uses the fitted model's contributions)
parameters = model.compute_channel_curve_optimization_parameters_original_scale(
method=response_curve_method
)
# 2. Define optional budget bounds per channel (if needed)
# bounds = {'channel1': (min_spend, max_spend), ...}
budget_bounds = None # Example: no specific bounds beyond non-negativity
# 3. Run the budget allocator using the model's method
optimised_results_df = model.optimize_channel_budget_for_maximum_contribution(
method=response_curve_method,
total_budget=total_budget,
budget_bounds=budget_bounds,
parameters=parameters # Pass the estimated parameters
)
# 4. Analyse the optimised_results_df
print(optimised_results_df)
# 5. Plotting (Conceptual - the driver typically handles plotting using model methods)
# The driver likely calls model.plot_budget_scenarios or similar internally.
# --- End Conceptual Example ---
(Note: While these core methods exist, direct manual calls bypass the standard driver workflow and require deeper understanding of the library’s internal data structures and parameter formats. Using the OptimisationDriver or the main driver script is the standard approach.)
Interpreting the Results¶
budget_optimisation.png: Visually compare the height of the bars for the “Initial” vs. “Scenario 1” (Optimised) budget and contribution. This shows where the optimiser suggests shifting spend and the expected impact on contribution.optimization_results.csv:initial_budget: The budget allocation before optimisation (often based on historical spend).optimal_budget: The suggested budget allocation after optimisation. Compare this to the initial budget to see recommended shifts.initial_contribution: The estimated contribution based on the initial budget.optimal_contribution: The estimated contribution based on the optimal budget. The difference represents the potential lift from optimisation.Look for channels where
optimal_budgetis significantly higher or lower thaninitial_budget. This indicates where the model sees opportunities for better ROI by reallocating funds.
Key Considerations¶
Response Curve Choice: The optimisation relies heavily on the accuracy of the fitted response curves (typically Michaelis-Menten or Sigmoid). Poorly estimated curves will lead to unreliable optimisation results. Review response curve plots (
response_curves.png) if available.Total Budget: The optimisation allocates a fixed total budget. It suggests how to best spend that same amount, not whether to increase or decrease the total budget.
Constraints: If budget bounds are set (either via config or potentially driver parameters), the optimiser will respect them, which might result in a sub-optimal solution compared to having no bounds.
Model Accuracy: The optimisation is only as good as the underlying MMM fit. Ensure your main model diagnostics (convergence, R-hat, posterior predictive checks) are satisfactory.
Static vs. Dynamic: This optimisation assumes the response curves remain static. In reality, market conditions change. Re-run the model and optimisation periodically with updated data.