Causal Inference 07: Many Experiments
Evidence composes — and a portfolio needs bookkeeping.
Notebook 06 repaired one
channel with one experiment. A real measurement program accumulates a
portfolio: readouts of different channels, windows, designs and vintages —
plus the occasional inherited "study" of dubious provenance. This page mirrors
nbs/causal/causal_07_many_experiments.ipynb: three very different pieces
of evidence folded into Veranda Home's realistic seven-channel model,
each one graded against the sealed key. Three lessons: experiments compose; a test on
one twin of a collinear pair resolves the split but not the sum; and
the portfolio's most dangerous member is the confident wrong one.
1 — The baseline and its honest ignorance
The realistic seven-channel world's causal fit, reloaded from cache. The ridge: Radio and Print flighted in lockstep (spend correlation ≈ 0.996), so the data pins their combined effect while each channel's own interval stays enormous — 90% interval widths of 3,871 (Radio) and 4,034 (Print) KPI units, against true contributions of 3,301 and 2,097. Points: Radio −36%, Print −16%, both covered by their wide intervals. And a detail that matters later: the pair-sum itself is under-read — combined estimate 3,853 vs true 5,398, −29%. The observational data got the total wrong, not just the split.
2 — Experiment 1: the Radio go-dark
Ten dark weeks for Radio (window 2022-09-26 → 2022-11-28), read with notebook 05's discipline: window ROAS 0.94 ± 0.10 (the world's true window ROAS: 0.94 — a well-run test). Folded in via the likelihood route and re-graded:
Measured — nbs/artifacts/causal_07_portfolio.json. The
tested channel is repaired: Radio lands at −10% (from −36%) and its
interval collapses by 74%. The twin moves too — Print's interval
shrinks 43%, because resolving Radio resolves the split of
the pinned pair-sum. But the honest part most case studies omit: Print's
point estimate got worse, −16% → −56%. The data had pinned the pair-sum ~30%
low; the experiment fixed Radio's share of it, so the whole sum deficit now lands on
Print — with more confidence.
⚠️ One test resolves a collinear pair's SPLIT, not its SUM
The pair-sum stays whatever the observational data said it was — here, ~30% under-read. The untested twin just became the program's top re-test priority. Budget the second test, or design one that moves both channels (notebook 08).
3 — Experiment 2: off-panel Display
The Display holdout ran after the modeling window closed — spring
2024, while the panel ends in late 2023. Classic grounds for "sorry, the test doesn't
overlap the data, we can't use it." With off-panel calibration you can: declare the
test's spend level (eval_spend, per period), duration
(eval_periods), and adstock regime (cold_start — the channel
ramps from zero in the test markets), and the likelihood attaches to the channel's
global response curve evaluated at that spend. No training rows involved, so
window overlap is unnecessary.
from mmm_framework.calibration import ExperimentEstimand, ExperimentMeasurement
radio_dark = ExperimentMeasurement(
channel="Radio", test_period=("2022-09-26", "2022-11-28"),
value=0.94, se=0.10,
estimand=ExperimentEstimand.ROAS, distribution="normal",
name="radio_dark_2022",
)
display_offpanel = ExperimentMeasurement(
channel="Display", test_period=("2024-03-04", "2024-04-22"),
value=0.59, se=0.08,
estimand=ExperimentEstimand.ROAS, distribution="normal",
eval_spend=45.0, eval_periods=8, eval_units=1, # $45k/week, 8 weeks, 1 cell
adstock_state="cold_start", # ramps from zero in test markets
name="display_offpanel_2024",
)
model.add_experiment_calibration([radio_dark, display_offpanel])
results = model.fit(draws=1000, tune=1000)
Measured: at $45k/week (cold start) the world's true off-panel ROAS is 0.56; the simulated readout comes in at 0.59 ± 0.08. After the merge, Display's interval width drops 4,113 → 1,898 (−54%) and its point estimate doesn't degrade (+19% → +16%). The assumption you buy it with, stated out loud: structural stationarity — the response curve (saturation, carryover, effectiveness) is the same in spring 2024 as in the fitted window. Time-varying worlds break this; pricing evidence decay is notebook 09's job.
4 — Experiment 3: the confident wrong certificate
An inherited deck claims Search ROAS 0.95 ± 0.10 ("agency lift study, 2021"). Before merging anything, run the tension check — compare the claimed value against the current posterior for the same estimand, combining both uncertainties:
\[ z \;=\; \frac{v_{\text{claim}} - \mu_{\text{model}}} {\sqrt{\text{SE}_{\text{claim}}^2 + \sigma_{\text{model}}^2}} \;=\; \frac{0.95 - 0.55}{\sqrt{0.10^2 + 0.11^2}} \;\approx\; 2.8 \]
A >2σ gap before merging. Policy: investigate provenance — was the estimand matched? the estimator calibrated? the market representative? Park it in the ledger as disputed. The notebook merges it anyway, as narrator, to price the mistake:
Measured — the bad certificate drags a healthy estimate away from truth: Search relative error +8% → +26%, truth pushed outside the interval — and the interval tightens while it happens (width 2,752 → 1,741). Confidently wrong, by injection. A likelihood commits — including to lies.
5 — The portfolio ledger
Every readout, its vintage, estimand, SE, and what it did to the posterior — the bookkeeping a planning engine consumes. The legacy study is excluded from the final model; it stays in the ledger as disputed.
| name | channel | estimand | vintage | value ± SE | status | origin |
|---|---|---|---|---|---|---|
radio_dark_2022 |
Radio | avg ROAS (window) | 2022-11 | 0.94 ± 0.10 | merged | pre-registered geo holdout (nb05 discipline) |
display_offpanel_2024 |
Display | avg ROAS (off-panel, cold start) | 2024-04 | 0.59 ± 0.08 | merged | post-window national holdout |
legacy_search_2021 |
Search | avg ROAS (claimed) | 2021-08 | 0.95 ± 0.10 | disputed (tension z = 2.8) | inherited agency deck |
Measured — what each honest piece of evidence bought, as 90% interval width reduction: Radio −74% (its own go-dark), Print −43% (spillover — resolving the twin resolves the split), Display −54% (the off-panel holdout). Each merged readout repaired its target and tightened its neighborhood.
6 — Portfolio discipline
- Evidence composes through the likelihood — each honest readout repaired its target and tightened its neighborhood.
- Collinear pairs need two answers. A test on one twin resolves the split; the pair-sum stays whatever the observational data said it was. Budget the second test, or design one that moves both.
- Tension-check before merging. A >2σ gap between a claim and the current posterior is a provenance investigation, not a data point.
- Vintage matters. The 2021 study wouldn't be trustworthy even if honest — evidence decays as the world drifts. Pricing that decay is notebook 09's job.
Check your understanding
Commit to an answer before opening each one.
The Radio test was honest and accurate (readout 0.94, truth 0.94). Why did Print's point estimate get worse after merging it?
Because the observational data had pinned two things: the Radio+Print sum (about 30% below truth) and almost nothing about the split. The experiment nailed Radio's share, so the posterior kept its beliefs about the sum and reassigned the entire deficit to the untested twin: Print went −16% → −56%, with a tighter interval. Nothing malfunctioned — the model combined its evidence correctly; the observational component of that evidence was simply wrong about the sum, and no Radio test can fix a Print bias. That is why the untested twin becomes the top re-test priority.
What exactly does off-panel calibration attach the likelihood to, and what assumption does that purchase run on?
Not to any training row — the test window doesn't overlap the panel. The
likelihood evaluates the channel's global response curve (the fitted
saturation and adstock machinery) at the declared spend level
(eval_spend) over the declared duration
(eval_periods), under the declared adstock regime
(cold_start). The purchase price is structural stationarity: the
curve must be the same in spring 2024 as in the fitted window. State it,
and revisit it when the world drifts — evidence-decay pricing is
notebook 09.
The legacy study made the Search interval tighter. Why is that the alarming part?
Because width is the model's own statement of confidence. An honest merge buys narrower intervals around a better point; a poisoned merge buys narrower intervals around a worse one — Search moved +8% → +26% while its width fell 2,752 → 1,741, so the model became more sure of a more wrong number, and the truth left the interval. A likelihood commits, including to lies. The z = 2.8 tension check was the smoke detector: fired before the merge, it routes the claim to provenance review instead of the graph.
💡 Run it yourself
This page mirrors
nbs/causal/causal_07_many_experiments.ipynb
— notebook 7 of 11 in the Causal Inference in Practice series (brand:
Veranda Home; synthetic worlds with sealed answer keys; every claim graded by an
assert). All numbers from nbs/artifacts/causal_07_portfolio.json,
produced by nbs/causal/causal_07_many_experiments.ipynb.
Previous: 06 · Calibrating the
Model. Next:
08 · Designing the Next
Experiment — stop reading tests and start choosing them:
model-anchored power, the short-term cost of learning, and a Pareto frontier of
designs. Source:
github.com/redam94/mmm-framework.