adding hierarchical its#833
Conversation
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
|
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #833 +/- ##
==========================================
+ Coverage 95.51% 95.55% +0.03%
==========================================
Files 98 100 +2
Lines 15870 16870 +1000
Branches 931 1037 +106
==========================================
+ Hits 15159 16120 +961
- Misses 504 523 +19
- Partials 207 227 +20 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Documentation build overview
594 files changed ·
|
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
|
I think this is good for a review. |
|
Some things to consider when reviewing.
|
Code review (claude-opus-4-4-xhigh)Reviewing the code in this PR only — I have not reviewed A genuinely useful addition — staggered-launch panels with hierarchical pooling and event-study/placebo parameterizations are a real gap in CausalPy, and the PyMC model is well-structured (non-centered everywhere, sensible data-adaptive priors, optional Fourier/AR machinery). The 32 tests pass locally. Below is a critical-but-constructive pass focused on correctness, repo consistency, and test coverage. Critical issues (correctness)1. Silent data-corruption bug in AR(1)
|
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
drbenvincent
left a comment
There was a problem hiding this comment.
Thanks — this is a solid start on #830 and the hierarchical ITS / event-study direction looks right.
Before merge, two blockers on current main:
- Please rebase onto
main— the branch is well behind and merge status is blocked. - Add an explicit keyword-only
plot()that forwards to_render_plot(). Tests callresult.plot(), andgenerate_report()callsexperiment.plot(); currentmainno longer inheritsplot()fromBaseExperiment(#886), so this raisesAttributeErrorafter rebase.
Non-blocking for this round (follow-ups or a quick fix if easy):
- Document placebo-mode counterfactual semantics: when
effect_on=False, pre-launch bins stay active and only post-launch bins are zeroed, which affectsimpactandplot_unit(). Worth a short docstring/note so users interpret those plots correctly. - Consider follow-up issues for
get_plot_data_bayesian(), wiring covariate pooling priors (mu_beta/sigma_beta) through the priors API, and an optional flag to disable the hierarchical time trend.
I have not done a thorough manual pass on the new docs notebook yet — I will try to review the RTD page in the next few days, so there may be some presentational feedback to follow.
|
@NathanielF just a ping on this - whenever you get time, there are some change requests |
|
Oh sorry. Completely forgot about this. Will look at the weekend |
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
Review of the latest changes (branch @
|
| # | Requested change | Status |
|---|---|---|
| 1 | AR within_unit_tidx corrupts on unsorted panels |
Fixed. _prepare_data sorts by (unit_col, time_col) and derives the index via groupby().cumcount(). Regression test test_ar_residuals_unsorted_panel. |
| 2 | Placebo counterfactual zeroed pre-launch leads | Fixed. _aux copies D and zeroes only D[:, n_pre_bins:] for placebo. Test test_placebo_counterfactual_keeps_pre_bins. |
| 3 | treatment_time_col not validated for constancy |
Fixed. groupby-nunique check. Test test_inconsistent_treatment_time_per_unit. |
| 4 | print_coefficients() crashed (wrong dims) |
Fixed. Overridden in the experiment; prints mu_beta/sigma_beta plus per-effect-type params. Tests per effect type. |
| 5 | _algorithm naming holdout |
Renamed to algorithm(), matching the other 9 experiments. |
| 6 | effect_summary ignored 7 of 8 args |
Handled. direction drives prob_positive/prob_negative/two-sided; genuinely-unsupported args (window, cumulative, min_effect, period) emit warnings.warn. |
| 7 | Triple posterior-predictive sampling | Fixed via new score_from_prediction(), reusing observed_pred. |
| 8 | __init__ swallowed unknown kwargs |
**kwargs removed. |
| 9 | pytensor scan deprecation |
return_updates=False at pymc_models.py:3030. |
| 10 | Standardization not surfaced | print_coefficients prints an "original scale" block dividing back through _x_std, and it's documented. |
| 11 | Fourier labels + seasonality footguns | Labels now f_sin_k/f_cos_k; added validation for missing keys, non-positive period, K<1. |
| June-1 | Rebase onto main |
Done (merge d17b76f). |
| June-2 | Explicit keyword-only plot() forwarding to _render_plot() |
Added, with ci_prob validation and a full docstring. |
Extra validation beyond the asks: bin_edges/placebo_edges length checks, placebo/bin overlap detection, and an empty-bin guard (D.sum() == 0 raises). Test count went from 32 to 61.
Two items explicitly deferred to follow-ups remain open (fine per the original note): get_plot_data_bayesian() is not implemented (falls through to the base-class NotImplementedError, not tested for a clean raise), and there's no flag to disable the hierarchical time trend. Suggest a one-line test asserting get_plot_data() raises cleanly, or a tracking issue.
(b) Module functionality
Scope is now four effect parameterizations. The new saturation type models the post-launch effect as a per-unit Hill curve (ceiling L, half-saturation time k, exponent s, all hierarchical on the log scale) — a real addition over instant/event-study/placebo, not just a review fix. It's wired through consistently: _aux feeds tau_since = clip(tau, 0, None), and summary/print_coefficients/predictive_for_new_unit/plot all branch on it. test_recovers_saturation_parameters fits (non-mocked) and checks recovery, matching the recovery-test pattern the review asked for.
The AR-cancels-in-the-difference argument holds up given the counterfactual now shares the same AR draws; the placebo fix is what makes the impact trace trustworthy in the pre-period. Standardization is internal and now disclosed at print time, so downstream beta interpretation is no longer silently misleading.
Verification
pytest causalpy/tests/test_hierarchical_its.py: 61 passed in ~3.5 min (the coverage-gate "fail" is just the project-wide 80% threshold tripping when running a single file). Codecov reports 96% patch coverage.
Read: the blockers are resolved with a regression test behind each, and functionality expanded cleanly. Ready for a re-review. Only nudge before merge is a clean-raise test (or issue) for get_plot_data_bayesian, the one base-class method left implicit.
🤖 Posted on behalf of @NathanielF via Claude Code.
Automated triageRecommendation: Why:
Review focus:
Confidence: high |
Signed-off-by: Nathaniel <NathanielF@users.noreply.github.com>
|
This is no longer DIRTY @daimon-pymclabs , @drbenvincent and should be good |
Working on this ticket: #830