Skip to content

Commit b07b68d

Browse files
feat(registry): wire v0.9.16 breadth-expansion modules into sp.help / sp.list_functions
Adds Sprint 1-6 new public APIs to sp.__all__ so auto-registration picks them up, plus 11 hand-written FunctionSpec entries carrying parameter schemas, tags, and canonical references: target_trial_protocol — Hernan-Robins / JAMA 2022 TTE framework clone_censor_weight — CCW for sustained-treatment strategies ipcw — Robins-Finkelstein censoring weights identify — Shpitser-Pearl ID algorithm on DAGs swig — Richardson-Robins SWIG construction icp — Peters-Bühlmann-Meinshausen invariant CP transport_weights_fn — Stuart / Dahabreh density-ratio transport identify_transport — Bareinboim-Pearl s-admissibility cevae — Louizos et al. latent-confounder VAE gformula_ice_fn — Bang-Robins iterative conditional expect. OPEResult — umbrella container for sp.ope.* estimators sp.search_functions("target trial") → 5 hits, "invariance" → icp, "transport" → 5 hits. Verified against existing test_agent, test_article_aliases, test_smart_workflow suites (90 + 73 passed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 012e4de commit b07b68d

2 files changed

Lines changed: 260 additions & 1 deletion

File tree

src/statspai/__init__.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,8 @@
153153
from .bayes import (
154154
bayes_did, bayes_rd, bayes_iv, bayes_fuzzy_rd, bayes_hte_iv,
155155
bayes_mte,
156-
BayesianCausalResult, BayesianHTEIVResult, BayesianMTEResult,
156+
BayesianCausalResult, BayesianDIDResult, BayesianHTEIVResult,
157+
BayesianIVResult, BayesianMTEResult,
157158
policy_weight_ate, policy_weight_subsidy,
158159
policy_weight_prte, policy_weight_marginal,
159160
policy_weight_observed_prte,
@@ -192,6 +193,8 @@
192193
# === Transportability (Pearl-Bareinboim + Dahabreh-Stuart) ===
193194
from . import transport
194195
from .transport import (
196+
weights as transport_weights_fn,
197+
generalize as transport_generalize,
195198
TransportWeightResult,
196199
identify_transport, TransportIdentificationResult,
197200
)
@@ -683,7 +686,9 @@
683686
"bayes_hte_iv",
684687
"bayes_mte",
685688
"BayesianCausalResult",
689+
"BayesianDIDResult",
686690
"BayesianHTEIVResult",
691+
"BayesianIVResult",
687692
"BayesianMTEResult",
688693
"policy_weight_ate",
689694
"policy_weight_subsidy",
@@ -961,6 +966,20 @@
961966
"causal_discovery",
962967
"mediation",
963968
"evalue_rr",
969+
# === v0.9.16 breadth-expansion API (Sprint 1-6) ===
970+
"ipcw", "IPCWResult",
971+
"icp", "nonlinear_icp", "ICPResult",
972+
"identify", "IdentificationResult",
973+
"do_rule1", "do_rule2", "do_rule3", "do_calculus_apply", "RuleCheck",
974+
"swig", "SWIGGraph", "SCM",
975+
"cevae", "CEVAE", "CEVAEResult",
976+
"TargetTrialProtocol", "TargetTrialResult", "CloneCensorWeightResult",
977+
"target_trial_protocol", "target_trial_emulate",
978+
"clone_censor_weight", "immortal_time_check",
979+
"TransportWeightResult", "TransportIdentificationResult",
980+
"transport_generalize", "transport_weights_fn", "identify_transport",
981+
"OPEResult",
982+
"gformula_ice_fn", "ICEResult",
964983
]
965984

966985

src/statspai/registry.py

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,246 @@ def _build_registry():
884884
reference="Frangakis & Rubin (2002); Zhang & Rubin (2003); Ding & Lu (2017)",
885885
))
886886

887+
# -- v0.9.16 breadth-expansion: Target Trial Emulation ----------- #
888+
register(FunctionSpec(
889+
name="target_trial_protocol",
890+
category="target_trial",
891+
description=(
892+
"Create a 7-component target trial protocol (Hernan-Robins / "
893+
"JAMA 2022 framework). Formalizes eligibility, treatment "
894+
"strategies, time zero, follow-up, outcome, causal contrast, "
895+
"and analysis plan before any estimation."
896+
),
897+
params=[
898+
ParamSpec("eligibility", "str | list | callable", True),
899+
ParamSpec("treatment_strategies", "list", True),
900+
ParamSpec("assignment", "str", True,
901+
description="'randomization' or 'observational emulation'"),
902+
ParamSpec("time_zero", "str", True),
903+
ParamSpec("followup_end", "str", True),
904+
ParamSpec("outcome", "str", True),
905+
ParamSpec("causal_contrast", "str", False, "ITT",
906+
enum=["ITT", "per-protocol", "as-treated", "observational-analogue"]),
907+
ParamSpec("analysis_plan", "str", False),
908+
ParamSpec("baseline_covariates", "list", False),
909+
ParamSpec("time_varying_covariates", "list", False),
910+
],
911+
returns="TargetTrialProtocol",
912+
example='proto = sp.target_trial_protocol(eligibility="age >= 50", ...)',
913+
tags=["target_trial", "epidemiology", "observational", "JAMA"],
914+
reference="Hernan & Robins (2016); JAMA (2022)",
915+
))
916+
register(FunctionSpec(
917+
name="clone_censor_weight",
918+
category="target_trial",
919+
description=(
920+
"Clone-Censor-Weight (CCW) for sustained-treatment target "
921+
"trials. Clones each subject per strategy, artificially "
922+
"censors on deviation, and re-weights via IPCW."
923+
),
924+
params=[
925+
ParamSpec("data", "DataFrame", True),
926+
ParamSpec("id_col", "str", True),
927+
ParamSpec("time_col", "str", True),
928+
ParamSpec("treatment_col", "str", True),
929+
ParamSpec("strategies", "dict[str, callable]", True),
930+
ParamSpec("censor_covariates", "list", False),
931+
ParamSpec("stabilize", "bool", False, True),
932+
],
933+
returns="CloneCensorWeightResult",
934+
tags=["target_trial", "ccw", "longitudinal", "dynamic_strategy"],
935+
reference="Cain et al. 2010; Hernan et al. 2016",
936+
))
937+
register(FunctionSpec(
938+
name="ipcw",
939+
category="censoring",
940+
description=(
941+
"Inverse Probability of Censoring Weights -- corrects for "
942+
"informative censoring under conditional independent "
943+
"censoring given covariates."
944+
),
945+
params=[
946+
ParamSpec("data", "DataFrame", True),
947+
ParamSpec("time", "str", True),
948+
ParamSpec("event", "str", True),
949+
ParamSpec("censor_covariates", "list", True),
950+
ParamSpec("treatment_covariates", "list", False),
951+
ParamSpec("stabilize", "bool", False, True),
952+
ParamSpec("method", "str", False, "pooled_logistic",
953+
enum=["pooled_logistic", "cox_ph"]),
954+
ParamSpec("truncate", "tuple", False, (0.01, 0.99)),
955+
],
956+
returns="IPCWResult",
957+
tags=["censoring", "weighting", "survival", "What If"],
958+
reference="Robins & Finkelstein (2000); Cole & Hernan (2008)",
959+
))
960+
961+
# -- v0.9.16 breadth-expansion: DAG / SCM -------------------------- #
962+
register(FunctionSpec(
963+
name="identify",
964+
category="dag",
965+
description=(
966+
"Shpitser-Pearl ID algorithm: decide if P(Y | do(X)) is "
967+
"non-parametrically identifiable on a semi-Markovian DAG, "
968+
"return the do-free estimand or a witness hedge."
969+
),
970+
params=[
971+
ParamSpec("dag", "DAG", True),
972+
ParamSpec("treatment", "str | set", True),
973+
ParamSpec("outcome", "str | set", True),
974+
],
975+
returns="IdentificationResult",
976+
example='sp.identify(sp.dag("Z->X;Z->Y;X->Y"), treatment="X", outcome="Y")',
977+
tags=["dag", "identification", "scm", "pearl"],
978+
reference="Shpitser & Pearl (2006); Tian & Pearl (2002)",
979+
))
980+
register(FunctionSpec(
981+
name="swig",
982+
category="dag",
983+
description=(
984+
"Build a Single-World Intervention Graph (SWIG) by "
985+
"node-splitting intervened variables. Bridges Pearl's SCM "
986+
"and Hernan-Robins potential-outcome languages."
987+
),
988+
params=[
989+
ParamSpec("dag", "DAG", True),
990+
ParamSpec("intervention", "dict | list", True),
991+
],
992+
returns="SWIGGraph",
993+
tags=["dag", "swig", "counterfactual"],
994+
reference="Richardson & Robins (2013)",
995+
))
996+
997+
# -- v0.9.16 breadth-expansion: Causal Discovery (ICP) ----------- #
998+
register(FunctionSpec(
999+
name="icp",
1000+
category="causal_discovery",
1001+
description=(
1002+
"Invariant Causal Prediction: infer direct parents of Y by "
1003+
"testing invariance of P(Y | X_S) across environments."
1004+
),
1005+
params=[
1006+
ParamSpec("X", "DataFrame", True),
1007+
ParamSpec("y", "ndarray", True),
1008+
ParamSpec("environment", "ndarray", True),
1009+
ParamSpec("alpha", "float", False, 0.05),
1010+
ParamSpec("method", "str", False, "linear",
1011+
enum=["linear", "nonlinear"]),
1012+
ParamSpec("max_subset_size", "int", False),
1013+
],
1014+
returns="ICPResult",
1015+
tags=["causal_discovery", "invariance", "icp"],
1016+
reference="Peters, Bühlmann & Meinshausen (2016)",
1017+
))
1018+
1019+
# -- v0.9.16 breadth-expansion: Transportability ------------------ #
1020+
register(FunctionSpec(
1021+
name="transport_weights_fn",
1022+
category="transport",
1023+
description=(
1024+
"Density-ratio (inverse odds of sampling) weighting to "
1025+
"transport an effect estimated in the source population to "
1026+
"a named target population."
1027+
),
1028+
params=[
1029+
ParamSpec("source", "DataFrame", True),
1030+
ParamSpec("target", "DataFrame", True),
1031+
ParamSpec("features", "list", True),
1032+
ParamSpec("treatment", "str", True),
1033+
ParamSpec("outcome", "str", True),
1034+
ParamSpec("truncate", "tuple", False, (0.01, 0.99)),
1035+
],
1036+
returns="TransportWeightResult",
1037+
tags=["transport", "external_validity", "weighting"],
1038+
reference="Stuart et al. (2011); Dahabreh et al. (2020)",
1039+
))
1040+
register(FunctionSpec(
1041+
name="identify_transport",
1042+
category="transport",
1043+
description=(
1044+
"Pearl-Bareinboim transportability: enumerate s-admissible "
1045+
"adjustment sets on a selection diagram; returns the "
1046+
"transport formula or NOT identifiable."
1047+
),
1048+
params=[
1049+
ParamSpec("dag", "DAG", True),
1050+
ParamSpec("treatment", "str | set", True),
1051+
ParamSpec("outcome", "str | set", True),
1052+
ParamSpec("selection_nodes", "set", True),
1053+
],
1054+
returns="TransportIdentificationResult",
1055+
tags=["transport", "selection_diagram", "bareinboim"],
1056+
reference="Bareinboim & Pearl (2013)",
1057+
))
1058+
1059+
# -- v0.9.16 breadth-expansion: Off-Policy Evaluation ------------- #
1060+
register(FunctionSpec(
1061+
name="OPEResult",
1062+
category="ope",
1063+
description=(
1064+
"Container returned by sp.ope.* estimators (IPS, SNIPS, DR, "
1065+
"Switch-DR, DM). Reports value, SE, CI, importance-ratio "
1066+
"diagnostics."
1067+
),
1068+
params=[],
1069+
returns="OPEResult",
1070+
tags=["ope", "contextual_bandits", "rl"],
1071+
reference="Dudik, Langford & Li (2011); Swaminathan & Joachims (2015)",
1072+
))
1073+
1074+
# -- v0.9.16 breadth-expansion: CEVAE ---------------------------- #
1075+
register(FunctionSpec(
1076+
name="cevae",
1077+
category="neural_causal",
1078+
description=(
1079+
"Causal Effect Variational Auto-Encoder: infer a latent "
1080+
"confounder Z from noisy proxies X, then estimate ITE via "
1081+
"counterfactual decoding. Uses PyTorch when available, "
1082+
"else a numpy linear-variational fallback."
1083+
),
1084+
params=[
1085+
ParamSpec("X", "ndarray", True),
1086+
ParamSpec("treatment", "ndarray", True),
1087+
ParamSpec("outcome", "ndarray", True),
1088+
ParamSpec("z_dim", "int", False, 4),
1089+
ParamSpec("hidden", "int", False, 32),
1090+
ParamSpec("lr", "float", False, 1e-2),
1091+
ParamSpec("n_epochs", "int", False, 200),
1092+
ParamSpec("seed", "int", False, 0),
1093+
],
1094+
returns="CEVAEResult",
1095+
tags=["neural_causal", "vae", "latent_confounder"],
1096+
reference="Louizos et al. (2017)",
1097+
))
1098+
1099+
# -- v0.9.16 breadth-expansion: Parametric g-formula ------------- #
1100+
register(FunctionSpec(
1101+
name="gformula_ice_fn",
1102+
category="g-formula",
1103+
description=(
1104+
"Parametric g-formula via Iterative Conditional Expectation "
1105+
"(ICE) -- sequential regression of the outcome on treatment "
1106+
"and time-varying confounders, with recursive plug-in of "
1107+
"the target strategy. Consistent under correctly-specified "
1108+
"nuisance models; handles time-varying confounding that "
1109+
"vanilla adjustment cannot."
1110+
),
1111+
params=[
1112+
ParamSpec("data", "DataFrame", True),
1113+
ParamSpec("id_col", "str", True),
1114+
ParamSpec("time_col", "str", True),
1115+
ParamSpec("treatment_cols", "list", True),
1116+
ParamSpec("confounder_cols", "list | list[list]", True),
1117+
ParamSpec("outcome_col", "str", True),
1118+
ParamSpec("treatment_strategy", "list | callable", True),
1119+
ParamSpec("bootstrap", "int", False, 0),
1120+
],
1121+
returns="ICEResult",
1122+
tags=["g-formula", "longitudinal", "time_varying_confounding",
1123+
"What If", "bang_robins"],
1124+
reference="Robins (1986); Bang & Robins (2005)",
1125+
))
1126+
8871127

8881128
# ====================================================================== #
8891129
# Auto-registration from statspai.__all__

0 commit comments

Comments
 (0)