docs: Tutorial 27 - When the Average Hides the Action (distributional DiD with CiC)#696
Conversation
… DiD with CiC)
Business-framed walkthrough of ChangesInChanges/QDiD on a seed-locked
loyalty-program 2x2 (repeated cross-sections) where mean DiD reads $0.22
(p=0.90) while the known truth is a $3.01 mean effect concentrated below
the median (CiC ATT: $3.05):
- Reading the QTE profile; joint "which quantiles moved" claims via sup-t
uniform bands (excluding zero for exactly tau=0.05-0.50), including the
bands-are-silent-not-exonerating framing above the median and the
tau=0.55 pointwise blip (p=0.044) as the multiple-testing trap they
prevent.
- A live interior-range guardrail demo on a short-support control sample:
the Assumption-3.4 and interior-range warnings render in the committed
output (interior range (0.17, 0.996), NaN tail inference). The notebook
contains NO warnings filters and NO asserts - both locked structurally
by the drift test (AST-based); the machine-specific path prefix is
normalized out of committed stream text ("/Users/" drift-locked out).
- The scale-equivariance centerpiece: levels-vs-logs flips mean DiD's
verdict ($0.22 p=0.90 vs +14.0% p=0.001) and shifts QDiD's profile by
dollars (-0.24/-2.10/-5.65 at tau=0.50/0.75/0.90; a spurious -$8.48
"loss" at tau=0.90 where truth is ~0), while CiC's counterfactual
quantiles agree to floating-point precision on unconditional fits - the
concrete form of the Athey-Imbens p. 447 CiC-over-QDiD recommendation.
Public-API construction (type-1 inverted_cdf treated-post quantiles
minus reported QTE; cell size 901 coprime to the grid denominator);
drift-tested at rtol 1e-14 (libm-safe across the CI OS matrix).
- Covariate-composition confounding fixed with covariates=['tenure']:
confidently-wrong 9.38 [8.32, 10.45] -> truth-covering 6.53 [5.35,
7.70] (truth 6.0), on a design ported from the calibrated
methodology-test DGP. practitioner_next_steps() close.
Committed WITH executed outputs (nbsphinx renders them on RTD; ~65s
runtime, well under the 600s notebook-CI budget). Companion drift test
(19 tests) re-derives every prose-quoted number from the public API and
cross-checks the rendered markdown/output surfaces; the ~1-minute
covariate bootstrap re-derivation is @pytest.mark.slow (T24 precedent).
Registered in the RTD toctree (Business Applications), the tutorials
catalog (also backfilling the missing Tutorial 25 entry), doc-deps, and
a fresh CHANGELOG [Unreleased] section; the tutorial's TODO row is
removed as completed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W75ea3yFYQbjVhB2evhRiZ
Overall Assessment✅ Looks good — no unmitigated P0/P1 findings. Executive Summary
MethodologyFinding 1 — P3 informational: documented qte-parity deviations are used correctlyLocation: Finding 2 — P3 informational: deferred CiC scope is properly disclosedLocation: Code QualityNo findings. The PR does not modify production code. PerformanceNo blocking findings. The slow covariate bootstrap drift test is marked MaintainabilityNo findings. The new tutorial is registered in the docs toctree and doc dependency map at Tech DebtNo findings. The completed tutorial TODO row was removed, while remaining CiC/QDiD deferred work stays tracked in SecurityFinding 1 — P3 informational: local-path drift guard is narrowLocation: Documentation/TestsNo blocking findings. The drift test re-derives the tutorial’s reader-facing numeric claims from the public API and checks rendered markdown/output surfaces at I did not run the full tests because |
…orms /Users/ alone would miss /home/, /private/, /tmp/, and C:\Users checkout prefixes if the notebook were ever re-executed elsewhere. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W75ea3yFYQbjVhB2evhRiZ
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment✅ Looks good — no unmitigated P0/P1 findings. Executive Summary
MethodologyFinding 1 — P3 informational: documented CiC/QDiD conventions are used correctlySeverity: P3 Finding 2 — P3 informational: deferred CiC scope remains trackedSeverity: P3 Code QualityNo findings. The PR does not modify production code, and the added drift test uses the public estimator APIs rather than duplicating estimator internals. PerformanceFinding 1 — P3 informational: slow covariate bootstrap test is marked slowSeverity: P3 MaintainabilityNo findings. The tutorial is registered in the RTD toctree and dependency map at Tech DebtNo findings. The completed tutorial backlog row was removed, while remaining CiC deferred work is still tracked in SecurityNo findings. The prior local-path guard concern is resolved by checking common macOS/Linux/Windows/temp prefixes in committed notebook outputs at Documentation/TestsNo blocking findings. The new drift tests pin the tutorial’s load-bearing claims: mean-vs-CiC contrast, QTE profile, uniform bands, interior-range warning/NaN behavior, scale equivariance, covariate conditioning, rendered prose/output quotes, no warning filters/asserts, and local-path output hygiene at I did not run the suite because |
Summary
docs/tutorials/27_cic_distributional_effects.ipynb- a business-framed walkthrough ofChangesInChanges/QDiDon a seed-locked loyalty-program 2x2 (repeated cross-sections) where mean DiD reads $0.22 (p = 0.90) while the known-by-construction truth is a $3.01 mean effect concentrated below the median (CiC ATT: $3.05). Covers: reading the QTE profile; joint "which quantiles moved" claims via sup-t uniform bands (excluding zero for exactly tau = 0.05-0.50, with the bands-silent-not-exonerating framing above the median and the tau = 0.55 pointwise blip, p = 0.044, as the multiple-testing trap they prevent); a live interior-range guardrail demo on a short-support control sample (warnings render in the committed output; interior range (0.17, 0.996), NaN tail inference); the scale-equivariance centerpiece (levels-vs-logs flips mean DiD's verdict and shifts QDiD's profile by dollars while CiC's counterfactual quantiles agree to floating-point precision on unconditional fits - the concrete form of the p. 447 CiC-over-QDiD recommendation); covariate-composition confounding fixed withcovariates=['tenure'](9.38 [8.32, 10.45] truth-excluding -> 6.53 [5.35, 7.70] truth-covering); and apractitioner_next_steps()close./Users/is drift-locked out of all committed outputs.DIFF_DIFF_BACKEND=python, well within the 600s notebook-CI budget.tests/test_t27_cic_distributional_effects_drift.py(19 tests): re-derives every prose-quoted number from the public API, pins the uniform-band split/interior range/equivariance identity (rtol 1e-14, libm-safe)/QDiD scale gap/covariate CI endpoints, and cross-checks the rendered markdown + output surfaces. The ~1-minute covariate bootstrap re-derivation is@pytest.mark.slow(T24 precedent).docs/tutorials/README.mdcatalog (also backfilling the previously missing Tutorial 25 entry),docs/doc-deps.yaml, fresh CHANGELOG[Unreleased]section; the tutorial's completed TODO row is removed.Methodology references (required if estimator / math changes)
qtepackage (parity conventions: bootstrap-only inference, fixed-95% sup-t bands,xformlacovariate branch).Validation
tests/test_t27_cic_distributional_effects_drift.py(19 tests; DGP constant + AST sync guards, numeric pins for every quoted claim, warning-behavior locks, rendered-surface quote checks, no-filters/no-asserts/no-local-paths notebook contract). Executed end-to-end:pytest --nbmakegreen (57s), all 19 drift tests green including the slow covariate re-derivation.Security / privacy
Generated with Claude Code