feat(synthetic_control): split cv-infeasible from failed in placebo/LOO diagnostics#598
Conversation
Overall Assessment✅ Looks good — no unmitigated P0/P1 findings. Executive Summary
MethodologyFinding: P3-informational — documented diagnostic-accounting refinement Code QualityNo findings. PerformanceNo findings. The change threads status from existing refits; it does not introduce additional solver runs. MaintainabilityFinding: P3 — confidence-set error reason map does not know the new no-reference statuses Tech DebtNo findings. SecurityNo findings. Documentation/TestsFinding: P3 — LOO return docstring omits |
…OO diagnostics
Under v_method="cv", an excluded in_space_placebo() / leave_one_out() refit whose
(pseudo-treated / reduced) donor pool is indistinguishable in a re-aggregated CV
window is now tallied as a structural "infeasible" exclusion, distinct from a solver
"failed" non-convergence -- mirroring the split in_time_placebo already reports.
- _outer_solve_V_cv returns a 6th structural-infeasible flag; _placebo_fit_unit
returns a (result, status) tuple with status in {ran, infeasible, failed}.
- in_space adds a public n_infeasible field; leave_one_out adds _loo_n_infeasible.
Statuses gain all_placebos_infeasible / all_placebos_unusable (resp. all_refits_*);
the per-row status column carries "infeasible"; DiagnosticReport surfaces reason_code
+ n_failed / n_infeasible for both surfaces.
- placebo_p_value / n_placebos are unchanged (both causes excluded from the rank /
ATT range identically) -- only the diagnostic attribution is refined.
- __setstate__ backfills the new counters to 0 on legacy unpickle so summary() /
to_dict() never AttributeError on a result pickled by an older version.
REGISTRY + CHANGELOG document the split; the TODO row is resolved.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
83a7a3d to
dcbde46
Compare
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment✅ Looks good — no unmitigated P0/P1 findings. Executive Summary
MethodologyFinding: P3-informational — documented diagnostic-accounting refinement Code QualityNo findings. PerformanceNo findings. The change threads status from existing refits and does not add extra solver runs. MaintainabilityNo findings. Previous reason-map gap is addressed at Tech DebtNo findings. The prior TODO item for this exact split was removed from SecurityNo findings. Documentation/TestsNo findings. The previous LOO docstring gap is addressed at Verification not run: |
Summary
v_method="cv", an excludedin_space_placebo()/leave_one_out()refit whose (pseudo-treated / reduced) donor pool is indistinguishable in a re-aggregated CV window is now tallied as a structural"infeasible"exclusion — distinct from a solver"failed"non-convergence — mirroring the splitin_time_placeboalready reports._outer_solve_V_cvreturns a structural-infeasible flag;_placebo_fit_unitreturns a(result, status)tuple (status ∈ {ran, infeasible, failed}).in_space_placebogains a publicn_infeasiblefield;leave_one_outgains_loo_n_infeasible. Statuses gainall_placebos_infeasible/all_placebos_unusable(resp.all_refits_*); the per-rowstatuscolumn carries"infeasible";DiagnosticReportsurfaces a machine-readablereason_code+n_failed/n_infeasiblefor both surfaces.placebo_p_value/n_placebosare unchanged (both causes are excluded from the rank / ATT range identically) — only the diagnostic attribution is refined.n_infeasibleis 0 for the non-cvv_methods.SyntheticControlResults.__setstate__backfills the new counters to 0 on legacy unpickle, sosummary()/to_dict()neverAttributeErroron a result pickled by an older version.Methodology references (required if estimator / math changes)
docs/methodology/REGISTRY.md(§SyntheticControl, "in-space / leave-one-out infeasible vs failed split").Validation
tests/test_methodology_synthetic_control.py— realv_method="cv"structural-infeasible discriminators for in-space (test_cv_in_space_placebo_excludes_donor_flat_refits, refined) and leave-one-out (test_cv_leave_one_out_flat_reduced_pool_infeasible, new real-DGP), the newall_*_infeasible/all_*_unusablestatus codes, a legacy-unpickle backfill test, and an extended pickle round-trip. Existing_placebo_fit_unitmonkeypatch stubs updated to the new(result, status)contract.Security / privacy
Generated with Claude Code