Add synthetic control tutorial + generate_synthetic_control_data generator#540
Conversation
|
Overall Assessment ✅ Looks good. No unmitigated P0/P1 findings. Executive Summary
Methodology Finding: Observed convex-hull guarantee is overstated Code Quality No findings. The new generator is scoped, exported consistently through Performance No findings. The new drift test is relatively heavy, but it uses a module fixture and appears intentionally scoped to the tutorial’s quoted numerics. Maintainability No findings. The docs dependency map adds the tutorial to the affected SyntheticControl/conformal surfaces, which helps future drift tracking. Tech Debt No findings requiring TODO tracking. The only issue above is a documentation/contract precision issue, not silent statistical output. Security No findings. I did not see secrets or sensitive material introduced in the changed surfaces. Documentation/Tests Finding: Tests do not pin the exact-hull wording |
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good. No unmitigated P0/P1 findings. Executive Summary
Methodology No P0/P1 findings. Finding: Residual shorthand in LLM guide omits the noiseless qualifier Code Quality No findings. The generator is scoped and validates key dimensional/timing arguments at Performance No findings. The tutorial drift test is intentionally heavier but uses a module-scoped fixture to avoid repeated full SCM/conformal runs: Maintainability No findings. The drift test pins notebook kwargs and quoted values, reducing prose/numeric drift risk: Tech Debt No findings requiring TODO tracking. Existing SCM deferred work remains in Security No findings. I did not see secrets or sensitive material introduced in the changed surfaces. Documentation/Tests No blocking findings. The prior test gap is addressed by Verification limitation: |
Add a public single-treated-unit factor-model data generator (generate_synthetic_control_data in prep_dgp.py, exported from diff_diff) and a capstone SyntheticControl tutorial (docs/tutorials/25_synthetic_control_policy.ipynb) showcasing the full estimator surface and the two inference philosophies (cross-unit permutation vs CWZ over-time conformal), with the per-period conformal band as the climax. The generator builds a treated unit whose latent loadings/baseline are an exact convex combination of donors, so its NOISELESS trajectory lies in the donor convex hull (the observed fit is approximate under added transitory/ predictor noise). Includes TestGenerateSyntheticControlData + test_noiseless_outcome_path_in_hull unit tests, a t25 drift guard re-deriving every quoted number from the generator, and doc surfaces (api/prep.rst, index toctree, doc-deps.yaml, CHANGELOG, llms-full). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
3b18921 to
2477a6b
Compare
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good. No unmitigated P0/P1 findings. Executive Summary
Methodology Finding: None Finding: None Code Quality Finding: None Performance Finding: None Maintainability Finding: None Tech Debt Finding: None Security Finding: None Documentation/Tests Finding: None |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good. No unmitigated P0/P1 findings. Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
|
Summary
generate_synthetic_control_data()— a public single-treated-unit factor-model data generator indiff_diff/prep_dgp.py(exported fromdiff_diff). One treated unit whose factor loadings + baseline are an exact convex combination of a few donors (so it lies inside the donor convex hull — a good synthetic control provably exists), persistent AR(1) factors, predictor covariates that each proxy a distinct factor, a common time effect, and a known"ramp"/"constant"effect emitted astrue_effect.docs/tutorials/25_synthetic_control_policy.ipynbwalking the fullSyntheticControlsurface end-to-end on a policy-evaluation story (one state adopts a clean-energy standard), structured around two inference philosophies: cross-unit permutation (in_space_placebo+ Firpo–Possebomconfidence_set, withleave_one_out/in_time_placeborobustness) vs over-time conformal (CWZconformal_test/conformal_confidence_intervals/conformal_average_effect), with the per-period conformal band as the climax.TestGenerateSyntheticControlDataunit tests, atest_t25_*_drift.pyguard that re-derives every quoted number from the generator,prep.rstautofunction + example,index.rsttoctree,doc-deps.yamltutorial entries, CHANGELOG, and the llms-full generator catalog.Methodology references
SyntheticControlestimator + its inference layers; the new code is a synthetic data generator (a factor-model DGP for demos/tests), not a new estimator or a change to any estimator's math.docs/references.rst.Validation
tests/test_prep.py(TestGenerateSyntheticControlData, 8 tests),tests/test_t25_synthetic_control_policy_drift.py(14 tests re-deriving every notebook number).DIFF_DIFF_BACKEND=python pytest --nbmakein ~58s (well under the 600s CI budget) with 6 figures; recovers the injected effect (ATT 6.79 vs true mean 7.0), placebo p=0.048, CWZ pointwise band brackets the truth 5/5, average-effect CI [6.5, 7.5].Security / privacy
Generated with Claude Code