Skip to content

Explanation: Optimisation Concepts

This page explains how AMMM converts posterior model outputs into budget allocation decisions under constraints.

Optimisation is a late-stage decision layer. It should be interpreted only after pre-diagnostics, convergence, calibration, and model assessment are acceptable.

See Workflow Stages for stage dependencies.

Response-Curve Approximation Used for Optimisation

Section titled “Response-Curve Approximation Used for Optimisation”

AMMM builds channel-level spend-to-contribution functions from fitted model outputs. In practice:

  1. Fit the Bayesian MMM and derive channel contribution series.
  2. Fit smooth saturating response curves to spend–contribution pairs.
  3. Optimise allocations under constraints using those response curves.

Implementation uses curve_fit-based parameter estimation in core.utils.estimate_sigmoid_parameters and core.utils.estimate_menten_parameters.

For single-period optimisation, the objective is to maximise total expected contribution:

$$ \max_{S_1,\dots,S_n} \sum_{i=1}^{n} C_i(S_i) $$

subject to budget and bound constraints.

With fixed total budget, maximising contribution is equivalent to maximising return efficiency under that budget envelope.

AMMM supports the following constraint families:

  1. Total budget:

$$ \sum_{i=1}^{n} S_i = B $$

  1. Channel bounds:

$$ S_i^{\min} \le S_i \le S_i^{\max} $$

  1. Ramp constraints (multi-period): period-to-period change limits by channel, with both:
  • absolute ramps, and
  • percentage ramps.

Ramp constraints are parsed and validated by parse_and_validate_ramp_constraints.

  • Solver: scipy.optimize.minimize with SLSQP.

AMMM supports two operational modes:

  • Simultaneous optimisation across all periods (default numerical method is SLSQP, with trust-constr used for larger problems).
  • Sequential optimisation (greedy period-by-period), which is often more numerically robust for difficult constrained cases.

An adstock-aware multi-period objective is implemented (objective_multiperiod_with_adstock) for advanced use cases. It increases non-linearity and should be treated as an advanced option.

Uncertainty: What Is and Is Not Propagated

Section titled “Uncertainty: What Is and Is Not Propagated”

Current V2 behaviour is pragmatic:

  • Optimisation typically runs on fitted response-curve parameters (often posterior-mean based summaries).
  • This is not a full posterior expected-utility optimiser by default.
  • Uncertainty is still available for decision context via posterior diagnostics, decomposition intervals, and response-curve analysis artefacts.

So optimisation outputs should be read as policy recommendations under model-estimated response surfaces, not certainty-equivalent truths.

Risk-aware utility formulations (for example explicit quantile utility or penalty-based robust utility) are conceptually useful but are not exposed as distinct first-class objective modes in current V2 APIs.

Primary outputs are written to 70_optimisation/:

  • optimization_results.csv
  • budget_scenario_results.csv
  • multiperiod_optimization_results.csv
  • budget_optimisation.png
  • scenario and multi-period visual diagnostics

These should be interpreted together with diagnostic artefacts in 50_diagnostics/.

  1. Treat optimisation as conditional on model adequacy.
  2. Validate recommendations against bounds and ramp feasibility.
  3. Compare scenario outputs rather than relying on a single point allocation.
  4. Communicate uncertainty and assumptions explicitly.

Optimisation quality depends on model structure and assumptions. Even when diagnostics pass, results are associational decision support unless stronger identification evidence is available.