StatsPAI 0.9.16 — v1.0 breadth expansion + Bayesian family polish
The largest release since the v1.0 breadth pass. Maps StatsPAI onto
the full Mixtape + What If + Elements of Causal Inference curriculum:
Hernan-Robins target-trial emulation, Pearl-Bareinboim SCM machinery,
modern off-policy / neural-causal estimators, plus three additions
that close long-standing gaps in the Bayesian family, plus a CI
scaffold for the Rust HDFE spike.
Added (0.9.16) — v1.0 breadth expansion (27+ new modules)
Target trial emulation & censoring (sp.target_trial, sp.ipcw)
target_trial_protocol,target_trial_emulate,clone_censor_weight,
immortal_time_check— JAMA 2022 7-component TTE framework with
explicit eligibility / time-zero / per-protocol contrast support.ipcw— Robins-Finkelstein inverse probability of censoring weights
(pooled-logistic or Cox hazard) with stabilization + truncation.
SCM / DAG machinery (sp.dag extended)
identify— Shpitser-Pearl ID algorithm; returns do-free estimand
when identifiable, witness hedge(F, F')otherwise.do_rule1 / do_rule2 / do_rule3,do_calculus_apply— mechanized
do-calculus with d-separation on mutilated graphsG_{bar X},
G_{underline Z}, andG_{bar Z(W)}.swig— Richardson-Robins Single-World Intervention Graphs via
node-splitting of intervened variables.SCM— abduction-action-prediction counterfactual runner with
rejection sampling fallback for non-Gaussian structural equations.llm_dag— LLM-backed DAG extraction from free-form descriptions.
Causal discovery with latents (sp.causal_discovery)
fci— FCI for PAGs with unobserved confounders (Zhang 2008):
skeleton + v-structures + FCI rules R1-R4.icp,nonlinear_icp— Peters-Bühlmann-Meinshausen invariant
causal prediction; linear F-test / K-S nonlinear invariance.
Transportability (sp.transport)
transport_weights_fn/transport_generalize— Stuart / Dahabreh
density-ratio transport with inverse odds of sampling weighting.identify_transport— Bareinboim-Pearl s-admissibility; enumerates
adjustment sets on selection diagrams, returns transport formula.
Off-policy evaluation (sp.ope)
ips,snips,doubly_robust,switch_dr,direct_method,
evaluate— Dudik-Langford-Li DR family plus Swaminathan-Joachims
SNIPS and Wang-Agarwal-Dudík Switch-DR for bandits / RL.
Deep causal & latent-confounder models (sp.neural_causal)
cevae— Louizos et al. CEVAE with PyTorch path + numpy
variational fallback so import never fails.
Longitudinal / G-methods (sp.gformula, sp.tmle, sp.dtr)
gformula_ice_fn— Bang-Robins iterative conditional expectation
parametric g-formula; sequential backward regression with recursive
strategy plug-in. Supports static / scalar / callable strategies.ltmle— van der Laan-Gruber longitudinal TMLE.q_learning,a_learning,snmm— dynamic treatment regime
estimators.
Additional estimators across the stack
- Causal forests:
multi_arm_forest,iv_forest,
survival/causal_forest(Cui-Kosorok 2023). - Proximal:
negative_controls,pci_regression(Miao-Shi-Tchetgen). - Interference:
network_exposure(Aronow-Samii 2017),peer_effects. - Dose-response:
vcnet+scigan(Nie-Brunskill-Wager 2021). - Matching:
genmatch(Diamond-Sekhon 2013). - Sensitivity:
rosenbaum_bounds. - Spatial:
spatial_did,spatial_iv(Kelejian-Prucha 1998). - Time series:
its(interrupted time series). - Bounds:
balke_pearl. - Mediation:
four_way_decomposition(VanderWeele 2014).
Registry / agent surface
- 11 hand-written
FunctionSpecentries for the new flagship APIs,
each with parameter schemas, tags, and canonical references. sp.list_functions()now reports 664 entries.sp.search_functions("target trial")/"invariance"/
"transport"all resolve correctly.
Added (0.9.16) — Bayesian family gap-closing
-
bayes_mte(mte_method='bivariate_normal')— full textbook
Heckman-Vytlacil trivariate-normal model(U_0, U_1, V) ~ N(0, Σ)
withD = 1{Z'π > V}. Identifies the structural gap
β_D = μ_1 - μ_0and the two selection covariancesσ_0V, σ_1V
via inverse-Mills-ratio corrections in the structural equation, so
MTE(v) = β_D + (σ_1V - σ_0V)·vis closed-form linear on V scale.
Requiresselection='normal'andfirst_stage='joint';poly_u
is overridden to 1 with aUserWarningif the user set something
else. Exposesb_mteas a 2-vector Deterministic
[β_D, σ_1V - σ_0V]so every downstream code path
(mte_curve, ATT/ATU integrator,policy_effect) works unchanged.
This is the last missing piece of the Heckman-Vytlacil pipeline
thatselection='uniform'/'normal'+mte_method='polynomial'/
'hv_latent'started. -
bayes_did(cohort=...)+BayesianDIDResult— when the user
supplies acohortcolumn (typically first-treatment period in a
staggered design), the scalartauis replaced with a vector
tau_cohortof lengthn_cohortsunder the same
Normal(prior_ate)prior. The result carries
cohort_summaries: Dict[str, dict]andcohort_labels; the
top-level pooled ATT is the treated-size-weighted mean of the
per-cohort τ posteriors.result.tidy(terms='per_cohort')
returns one row per cohort withterm='cohort:<label>'; explicit
terms=['att', 'cohort:2019', ...]selection is supported for
modelsummary / gt pipelines. Back-compat: calling without
cohort=...returns aBayesianDIDResultthat behaves byte-
identically to the v0.9.15BayesianCausalResult. -
bayes_iv(per_instrument=True)+BayesianIVResult— on a
multi-instrument fit, additionally runs one just-identified
Bayesian IV sub-fit perZ_jand stores per-instrument posteriors
asinstrument_summaries: Dict[str, dict]. Surface mirrors the
DID extension:tidy(terms='per_instrument')emits one row per
Zwithterm='instrument:<name>'. The top-level pooled LATE
remains the joint over-identified fit; per-instrument rows are an
add-on diagnostic. Sub-fit priors and sampler controls mirror the
pooled fit, so runtime scales roughly(K+1)×. -
.github/workflows/build-wheels.yml— Rust Phase-2
cibuildwheel matrix workflow (macOS arm64 + x86_64,
manylinux_2_17 x86_64 + aarch64, musllinux_1_2 x86_64, Windows
x86_64) with acheck_rust_presentguard job that makes the
workflow a no-op whenrust/statspai_hdfe/Cargo.tomlis absent
(the state onmain). The workflow activates automatically on
feat/rust-hdfe/feat/rust-phase2and on PRs touching
rust/**, so the Rust spike's CI lights up the moment the
branch is ready — no second PR for CI scaffolding.
Tests (0.9.16)
tests/test_bayes_mte_bivariate_normal.py— 7 tests covering
API validation (selection + first_stage gates, poly_u override),
structural-param presence in posterior, method label contents,
and slope recovery on a genuine trivariate-normal DGP at n=800.tests/test_bayes_did_cohort.py— 9 tests covering back-compat
(no cohort → single-row tidy identical to v0.9.15), cohort fit
populates summaries, multi-row tidy viaper_cohort+ explicit
list, unknown-term raises, τ ordering recovered on a two-cohort
staggered DGP with heterogeneous true ATTs (2.0 vs 0.5), and
cohort weights recorded in model_info.tests/test_bayes_iv_per_instrument.py— 8 tests covering
back-compat, per-instrument summary population,per_instrument
tidy, explicit-list tidy, unknown-term raises, error path when
asking forper_instrumenttidy without the sub-fit, and each
sub-fit's HDI covers the true LATE on a two-Z DGP.
Not in this release
- Round-trip testing of the cibuildwheel matrix on real runner
hardware — this must happen onfeat/rust-hdfe, where the
crate lives. The workflow onmainis inert by design.