Add survey_design support to WooldridgeDiD (Phase 10f)#280
Add survey_design support to WooldridgeDiD (Phase 10f)#280
Conversation
Add survey design support to WooldridgeDiD for all three estimation paths (OLS, logit, Poisson), completing Phase 10f of the survey roadmap. OLS uses survey-weighted within-transformation + WLS + TSL vcov. Logit and Poisson use survey-weighted IRLS + X_tilde linearization trick to reuse compute_survey_vcov() for correct QMLE sandwich. Replicate-weight designs raise NotImplementedError; bootstrap + survey is rejected. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Overall Assessment Executive Summary
Methodology Cross-checking against the cited Wooldridge nonlinear ETWFE framing and the Binder/Lumley survey-linearization references, the core modeling choice here is defensible. The remaining problems are not with
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
- P1: Propagate cluster into survey variance via _resolve_effective_cluster and _inject_cluster_as_psu. Extract shared _resolve_survey_for_wooldridge() helper (also fixes P3 copy-paste across 3 sub-fitters). - P1: Revert nonlinear gt_weights to cell counts (matching documented jwdid_estat contract). Survey weights affect per-cell ATTs and SEs but not aggregation weights. - P2: Fix choosing_estimator.rst contradictions — update stale prose and change WooldridgeDiD bootstrap column to unsupported. - P3: Add regression tests for weights-only+cluster injection and survey gt_weights being cell counts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment
Executive Summary
MethodologyThe core survey construction itself is plausible: Wooldridge (2023) frames nonlinear DiD through ASF/QMLE, and Binder/Lumley-style Taylor linearization is the standard design-based route for asymptotically normal estimators under complex survey designs. The blockers below are therefore implementation-contract issues in this PR, not the
Code Quality
PerformanceNo findings. MaintainabilityNo separate findings beyond the correctness issues above. Tech DebtNo mitigating SecurityNo findings. Documentation/Tests
Path to Approval
|
- P1: Only inject cluster as PSU when user explicitly sets cluster=; weights-only surveys without cluster= now keep implicit per-obs PSUs, preserving documented df_survey = n_obs - 1 contract. - P1: Add pweight-only guard in _resolve_survey_for_wooldridge() — fweight/aweight now raise ValueError matching other pweight-only estimators (ImputationDiD, TwoStageDiD). - P1: Add zero-weight safeguards to solve_poisson(weights=...) mirroring solve_logit's positive-weight validation (rank check on effective sample, sample-size identification). Skip zero-weight ASF cells in Poisson survey path. - P2: Add regression tests for implicit PSU contract, fweight rejection, and zero-weight Poisson cell handling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment
Executive Summary
Methodology No unmitigated P0/P1 paper mismatch stood out in the new nonlinear survey construction itself. The Binder-style
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Static review only: I could not run Path to Approval
|
- P1: Compute survey TSL vcov on kept columns only when solve_ols drops rank-deficient columns; expand back with NaN. Prevents singular bread matrix on all-eventually-treated ETWFE designs. - P1: Guard against zero-weight unit/time groups before within_transform; raise targeted ValueError instead of letting NaN propagate. - P2: Add weight validation (shape, NaN, Inf, non-negative, positive sum) to solve_poisson(weights=...) matching solve_logit pattern. - P2: Add regression tests for rank-deficient survey OLS and zero-weight unit rejection. - P3: Add pweight-only note to REGISTRY.md and survey-roadmap.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment
Executive Summary
Methodology
Code Quality
Performance No findings. Maintainability No findings beyond the two code-quality blockers above. Tech Debt No new blocking tech-debt findings. The pre-existing Wooldridge aggregation-weight and QMLE-adjustment limitations are already tracked in TODO.md:L72 and TODO.md:L73, so they do not affect this assessment. Security No findings. Documentation/Tests
Path to Approval
Static review only: I could not run |
- P1: Add zero-weight cell skip to logit ASF loop, mirroring Poisson - P1: Reset sample index in _fit_ols for index-safe zero-weight guard - P2: Add regression tests for logit zero-weight cell and non-RangeIndex OLS survey guard Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
Path to Approval
|
- P1: Replace pandas-2.2-only groupby.apply(include_groups=False) with pandas-1.3-compatible pd.Series.groupby().sum() in OLS zero-weight guard - P2: Add test for survey aggregate() with df_survey inference and summary() survey block display Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
/ai-review |
|
🔁 AI review rerun (requested by @igerber) Head SHA: Overall Assessment ✅ Looks good Executive Summary
Methodology
Code Quality
Performance
Maintainability
Tech Debt
Security
Documentation/Tests
|
Summary
survey_designparameter toWooldridgeDiD.fit()for all three estimation paths (OLS, logit, Poisson)weightsparameter tosolve_poisson()in linalg.py, mirroring existingsolve_logit()patterncompute_survey_vcov()survey_metadataand_df_surveytoWooldridgeDiDResultswith summary display and t-distribution inference inaggregate()dfparameter to_compute_weighted_agg()for survey degrees of freedomNotImplementedError) and bootstrap + survey (ValueError)Methodology references (required if estimator / math changes)
X_tilde = X * sqrt(V),r_tilde = resids / sqrt(V)reuses existingcompute_survey_vcov()without modification)Validation
tests/test_wooldridge.py— 8 new tests inTestWooldridgeSurvey(OLS/logit/Poisson smoke, SE divergence, bootstrap rejection, weights-only, metadata, replicate rejection)Security / privacy
Generated with Claude Code