Commit 5e66491
Add Tutorial 20: HAD for National Brand Campaign with Regional Spend Intensity
Practitioner walkthrough for HeterogeneousAdoptionDiD on the
no-untreated-controls case: every market got the campaign at varying
intensity and there is no clean comparison group. Fills the structural
gap T14 (ContinuousDiD) cannot address.
Notebook scope (23 cells, 13 markdown / 10 code, mirrors T19's
structure):
- Sections 1-3: framing the no-untreated-controls measurement problem,
setup imports, synthetic 60-DMA / 8-week panel with Uniform[$5K, $50K]
regional add-on spend (every DMA participates, no DMA at $0). DGP
is internally consistent: outcomes are generated from the dose
values HAD then sees, no post-hoc relabeling.
- Section 4: overall WAS_d_lower fit on a 2-period (pre/post mean)
collapse - HAD's overall mode requires exactly 2 periods
(had.py:952-959). Locked headline: per-$1K marginal effect of 100
weekly visits per DMA above the boundary spend (95% CI [98.6,
101.4]) with design auto-detection landing on
`continuous_near_d_lower` (Design 1) and target `WAS_d_lower`.
Surfaces the Assumption 5/6 advisory the library fires for Design 1
and explains why it holds in this DGP (linear by construction).
- Section 5: multi-week event-study fit on the 8-week panel,
per-week WAS_d_lower for e=0..3 (~100 each, CIs cover truth) and
pre-launch placebos at e=-2..-4 sitting on zero.
- Section 6: stakeholder communication template (T18/T19 markdown
blockquote pattern), per-DMA dollar-lift interpretation
`(actual_dose - d_lower) * WAS_d_lower`, Assumption 6 caveat.
- Section 7: extensions (population-weighted/survey path, composite
pretest workflow described accurately as QUG support-infimum test
+ linearity tests, mass-point design path), related-tutorials
cross-links (T01, T02, T14, T17, T18, T19), summary checklist.
Drift detection: companion tests/test_t20_had_brand_campaign_drift.py
(13 tests, 0.06s, mirrors T19's test-file-only pattern - T19's
notebook itself has zero in-notebook asserts). Pins panel composition
including sample median, design auto-detection / target / d_lower,
overall WAS_d_lower / SE / CI endpoints to one-decimal display, dose
mean, n_units, full event-study horizon presence (e=-4..-2, 0..3),
per-week post-launch coverage of TRUE_SLOPE=100 and zero coverage at
every placebo horizon (|placebo_att| < 0.1). Tight `round(_, 1) == X.X`
pins throughout - HAD's analytical SE path is bit-identical regardless
of backend env (no Rust kernel involved). Locked DGP seed: MAIN_SEED=87.
Documentation integration:
- docs/tutorials/README.md: new T20 entry following T18/T19's
5-bullet pattern.
- docs/doc-deps.yaml: T20 added to the existing diff_diff/had.py
entry; cross-link to docs/practitioner_decision_tree.rst added.
- docs/practitioner_decision_tree.rst: `.. tip::` block at the end
of `section-no-untreated` (Universal Rollout - landed on main via
PR #389) cross-links to T20 for the full walkthrough.
- CHANGELOG.md: new ### Added bullet under [Unreleased].
Out of scope (queued in project_had_followups.md memory):
- _handle_had in practitioner.py:_HANDLERS map.
- HAD entries in llms-full.txt / choosing_estimator.rst.
- Pretest workflow tutorial, weighted/survey HAD tutorial,
mass-point design demo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent 199268b commit 5e66491
6 files changed
Lines changed: 737 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
10 | 13 | | |
11 | 14 | | |
12 | 15 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
371 | 371 | | |
372 | 372 | | |
373 | 373 | | |
| 374 | + | |
| 375 | + | |
374 | 376 | | |
375 | 377 | | |
376 | 378 | | |
| |||
379 | 381 | | |
380 | 382 | | |
381 | 383 | | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
382 | 388 | | |
383 | 389 | | |
384 | 390 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
310 | 310 | | |
311 | 311 | | |
312 | 312 | | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
313 | 320 | | |
314 | 321 | | |
315 | 322 | | |
| |||
0 commit comments