Skip to content

Lock overlap IPW to the overlap population - #1207

Merged
drbenvincent merged 3 commits into
pymc6_and_pymcmarketing1_migrationfrom
feat/ipw-overlap-population
Sep 26, 2026
Merged

drbenvincent merged 3 commits into
pymc6_and_pymcmarketing1_migrationfrom
feat/ipw-overlap-population

Conversation

@drbenvincent

Copy link
Copy Markdown
Collaborator

Closes #1200

Summary

  • Add a numerical regression test that overlap IPW matches the Hajek overlap contrast on a two-stratum design.
  • Assert that this contrast is not the full-sample average of the unit-level treatment effects.
  • Leave the estimator unchanged.

Test plan

  • pytest causalpy/tests/test_ipw_overlap_identity.py --no-cov
  • ruff on the new test

Made with Cursor

The overlap scheme is not the full-sample average treatment effect, and no numerical test asserted that.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions github-actions Bot added the bug Something isn't working label Sep 26, 2026

@drbenvincent drbenvincent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: PR 1207 vs issue #1200

Verdict: APPROVE (posted as --comment because GitHub disallows approving your own pull request).

Definition of done (issue 1200)

Add a regression test that _compute_ate_overlap matches the Hajek overlap contrast and does not match the full-sample average of the unit-level treatment effects. Do not change the estimator.

Overall assessment

The PR meets the definition of done.

  • Only change is a new regression test (causalpy/tests/test_ipw_overlap_identity.py); the estimator is untouched.
  • The two-stratum probe from the issue is reproduced (propensity 0.5 / effect 10 vs propensity 0.95 / effect 0).
  • The test independently recomputes the Hajek overlap contrast sum(w y | t) / sum(w | t) − sum(w y | c) / sum(w | c) with w = 1−e (treated) and w = e (control), and asserts agreement with _compute_ate_overlap (including the treated/control means) at atol=1e-12.
  • It also asserts the contrast differs from the full-sample mean of unit-level effects (|ate − mean(y1−y0)| > 1), so a future change that silently switched to the full-sample ATE would fail.
  • This closes the gap called out in the issue: test_ipw_get_ate.py only checked ate == trt − ntrt.

I ran the new test against the current estimator; it passed.

Findings

None. No correctness bugs, contract violations, or remaining DoD gaps.

Notes (non-blocking)

  • Using __new__ to stub an unfitted IPW instance matches existing patterns in the suite (test_sdid_helpers.py, test_piecewise_its.py, etc.) and keeps the test free of MCMC.
  • Propensity values 0.5 / 0.95 sit safely inside _prepare_ps’s clip interval, so the manual Hajek mirror is not distorted by clipping.

@drbenvincent
drbenvincent marked this pull request as ready for review September 26, 2026 14:21
@codecov

codecov Bot commented Sep 26, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.15%. Comparing base (a931037) to head (4c0c6b0).

Additional details and impacted files
@@                         Coverage Diff                         @@
##           pymc6_and_pymcmarketing1_migration    #1207   +/-   ##
===================================================================
  Coverage                               97.14%   97.15%           
===================================================================
  Files                                     130      131    +1     
  Lines                                   24033    24065   +32     
  Branches                                 1349     1349           
===================================================================
+ Hits                                    23348    23380   +32     
  Misses                                    477      477           
  Partials                                  208      208           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@drbenvincent drbenvincent added tests Add or strengthen tests for behavior that is already correct and removed bug Something isn't working labels Sep 26, 2026
@daimon-pymclabs
daimon-pymclabs changed the base branch from main to pymc6_and_pymcmarketing1_migration September 26, 2026 16:01
…ap-population

Bring the branch up to date after #1214 synced main into the migration branch.
@read-the-docs-community

Copy link
Copy Markdown

Documentation build overview

📚 causalpy | 🛠️ Build #34779046 | 📁 Comparing 4c0c6b0 against latest (89f18de)

  🔍 Preview build  

397 files changed · + 126 added · ± 251 modified · - 20 deleted

+ Added

± Modified

- Deleted

@drbenvincent
drbenvincent merged commit 65e9202 into pymc6_and_pymcmarketing1_migration Sep 26, 2026
16 checks passed
@drbenvincent
drbenvincent deleted the feat/ipw-overlap-population branch September 26, 2026 21:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Add or strengthen tests for behavior that is already correct

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lock overlap IPW to the overlap population, not the full-sample ATE

1 participant