Skip to content

Add ExperimentDesigner: posterior-aware experiment design for lift tests#2356

Draft
drbenvincent wants to merge 9 commits intomainfrom
fix/2355-experiment-designer
Draft

Add ExperimentDesigner: posterior-aware experiment design for lift tests#2356
drbenvincent wants to merge 9 commits intomainfrom
fix/2355-experiment-designer

Conversation

@drbenvincent
Copy link
Contributor

@drbenvincent drbenvincent commented Mar 2, 2026

Summary

  • Adds ExperimentDesigner class that recommends which marketing experiment to run (channel, spend level, duration) based on a fitted MMM's posterior uncertainty about channel response functions
  • Implements adstock-aware lift prediction, Bayesian assurance (posterior-predictive power), weighted composite scoring across 5 dimensions, and 5 plotting methods
  • Includes fixture generator for creating realistic test posteriors, with both fast synthetic mode and full MCMC fitting

Details

Core computation: For each candidate experiment design (channel × spend change × duration), evaluates the posterior-predicted lift accounting for geometric adstock ramp-up, computes measurement noise σ = σ_residual · √T, and derives Bayesian assurance (expected power over the posterior distribution of the true effect).

Scoring dimensions: Channels are ranked by a configurable weighted sum of: posterior uncertainty, spend correlation, saturation gradient, assurance, and cost efficiency — all min-max normalised.

v1 scope: National-level experiments with LogisticSaturation + GeometricAdstock (adstock_first=True). Geo-level designs, pulse/switchback experiments, and Fisher Information are deferred to v2.

New files

  • pymc_marketing/mmm/experiment_design/designer.pyExperimentDesigner class
  • pymc_marketing/mmm/experiment_design/recommendation.pyExperimentRecommendation dataclass
  • pymc_marketing/mmm/experiment_design/functions.py — Numpy logistic_saturation
  • pymc_marketing/mmm/experiment_design/fixture.pygenerate_experiment_fixture()
  • 3 test files with 65 tests covering all components

Test plan

  • 65 new tests pass (functions, designer, fixture, plotting)
  • Pre-commit hooks pass (ruff, mypy, formatting)
  • Adstock ramp verified against analytic geometric series
  • Assurance calibrated (α for zero effects, ~1.0 for large effects)
  • NetCDF round-trip for fixtures verified
  • Integration test with fitted MMM (requires MCMC, deferred to CI)

Closes #2355

Made with Cursor


📚 Documentation preview 📚: https://pymc-marketing--2356.org.readthedocs.build/en/2356/

Implements a posterior-aware experiment designer that recommends which
marketing experiment to run based on a fitted MMM's uncertainty about
channel response functions. Computes adstock-aware lift predictions,
Bayesian assurance (posterior-predictive power), and weighted composite
scores across candidate experiments.

Includes ExperimentDesigner class with recommend() and 5 plotting
methods, ExperimentRecommendation dataclass, numpy response functions,
fixture generator, and 65 tests.

Closes #2355

Made-with: Cursor
@codecov
Copy link

codecov bot commented Mar 2, 2026

Codecov Report

❌ Patch coverage is 83.19185% with 99 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.70%. Comparing base (a9c9f90) to head (b4bf65f).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
pymc_marketing/mmm/experiment_design/designer.py 82.55% 75 Missing ⚠️
pymc_marketing/mmm/experiment_design/fixture.py 80.00% 19 Missing ⚠️
..._marketing/mmm/experiment_design/recommendation.py 91.52% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2356      +/-   ##
==========================================
- Coverage   93.15%   92.70%   -0.46%     
==========================================
  Files          79       83       +4     
  Lines       12523    13112     +589     
==========================================
+ Hits        11666    12155     +489     
- Misses        857      957     +100     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@drbenvincent drbenvincent marked this pull request as draft March 2, 2026 14:09
- Add end-to-end walkthrough notebook (docs/source/notebooks/mmm/)
- Add gallery entry under "Experiment Design" section
- Ship pre-built InferenceData fixture (simulated_3channel.nc)
- Add slow simulation-based assurance calibration tests
- Add tests for scoring weight redistribution and channel ranking
- Register 'slow' pytest marker in pyproject.toml

Made-with: Cursor
@review-notebook-app
Copy link

Check out this pull request on  ReviewNB

See visual diffs & provide feedback on Jupyter Notebooks.


Powered by ReviewNB

@github-actions github-actions bot added the docs Improvements or additions to documentation label Mar 2, 2026
…ansformer

Eliminate experiment_design/functions.py by delegating to
pymc_marketing.mmm.transformers.logistic_saturation via a new
_eval_saturation() static method that calls .eval() on the PyTensor
result.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation MMM Needs Triage tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ExperimentDesigner: Posterior-aware experiment design for lift tests

1 participant