Production-ready causal calibration tooling for heterogeneous treatment effect models, with native R and Python packages, cross-calibration support, and doubly robust calibration diagnostics.
The original paper-era implementation has been preserved on the main_deprecated branch. If you need the historical ICML 2023 code exactly as it previously lived in this repository, use that branch directly.
r/causalCalibration: R packagepython: Python packagedocs: static package website and supporting notesexamples: runnable end-to-end Python workflow materialsshared/fixtures: shared inputs and expected outputs for parity tests
dr: doubly robust/AIPW pseudo-outcome calibrationr: residualized R-loss calibration
isotonicmonotone_splinelinearhistogram
Python:
python3 -m pip install -e pythonR:
install.packages("r/causalCalibration", repos = NULL, type = "source")For method = "isotonic" in R, also install reticulate and make sure the active Python environment has lightgbm.
User-facing website:
Source examples:
- Python notebook: examples/python-workflow.ipynb
- R vignette: getting-started.Rmd
- Method notes: docs/getting-started.qmd, docs/standard-calibration.qmd, docs/cross-calibration.qmd, docs/diagnostics.qmd, docs/choosing-losses-and-methods.qmd, docs/reference.qmd
- Release checklist: RELEASE_CHECKLIST.md
method="isotonic"now uses a LightGBM monotone one-tree backend with weights andmin_child_samples.method="monotone_spline"is the package’s smooth monotone calibration method.assess_overlap()applies the package's default overlap screen, reports the tail and effective-sample-size summaries it uses, and gives a defaultloss="dr"versusloss="r"recommendation.diagnose_calibration(..., target_population = "dr" | "overlap" | "both")letsloss="r"users report calibration for the overlap-weighted target population as well as the original-population DR target.validate_crossfit_bundle()plus bundle helpers standardize pooled OOF predictions, fold matrices, fold IDs, nuisances, and weights before fitting.
Python:
from causal_calibration import (
CalibrationBundle,
assess_overlap,
diagnose_calibration,
fit_calibrator,
)
calibrator = fit_calibrator(
predictions=tau_hat,
treatment=a,
outcome=y,
mu0=mu0_hat,
mu1=mu1_hat,
propensity=e_hat,
loss="dr",
method="isotonic",
)
tau_calibrated = calibrator.predict(tau_new)
overlap = assess_overlap(treatment=a, propensity=e_hat)
diagnostics = diagnose_calibration(
predictions=tau_calibrated,
comparison_predictions=tau_hat,
treatment=a,
outcome=y,
mu0=mu0_hat,
mu1=mu1_hat,
propensity=e_hat,
target_population="both",
)R:
library(causalCalibration)
calibrator <- fit_calibrator(
predictions = tau_hat,
treatment = a,
outcome = y,
mu0 = mu0_hat,
mu1 = mu1_hat,
propensity = e_hat,
loss = "dr",
method = "isotonic"
)
tau_calibrated <- predict(calibrator, tau_new)
overlap <- assess_overlap(treatment = a, propensity = e_hat)- ICML 2023 paper: Causal Isotonic Calibration for Heterogeneous Treatment Effects
- AISTATS 2022 paper: Calibration Error for Heterogeneous Treatment Effects
- R-learner target weighting: Nie and Wager (2021)
- DR-learner theory: Kennedy (2020)