comprisk
A Python toolkit for competing-risks survival analysis: a scalable, scikit-learn-compatible competing-risks random survival forest plus the canonical regression / non-parametric methods — Fine-Gray, Aalen-Johansen CIF, cause-specific Cox — so applied researchers can drop the Python → R round-trip.
Status: alpha — API may change before v1.0. Renamed from
crforestin 0.3.1 (pip install comprisk;from comprisk import CompetingRiskForest).
Highlights
- Four canonical CR methods, native Python — Fine-Gray (+ penalized),
cause-specific Cox, Aalen-Johansen CIF, Gray's test — each validated to
floating-point tolerance against
cmprsk/crrp/survival. - The only native-Python CR forest — composite & cause-specific CR log-rank splitting, AJ CIF, Nelson-Aalen CHF, Wolbers + Uno IPCW concordance, OOB Breiman VIMP, Ishwaran minimal depth, exact TreeSHAP.
- CR-aware evaluation —
score_cr(IPCW time-dependent AUC/Brier + bootstrap CIs) andcalibration_cr, replacing the CR-moderiskRegression::Score()block;concordance_index_cigives a closed-form (no-bootstrap) CI for the Uno C-index and a paired model-comparisonconcordance_index_delta_ci. - Fast — 10–22× vs randomForestSRC on real EHR, 16.6–544× vs scikit-survival (n = 5k → 50k), n = 10⁶ in 63 s — at matched C ≈ 0.85. Benchmarks →
- Reproducible —
equivalence="rfsrc"reproduces rfSRC's per-tree mtry/nsplit RNG stream bit-for-bit. Methodology →
Install
pip install comprisk # or: uv add comprisk
pip install "comprisk[gpu]" # CUDA 12 preview (faster only at low p today)
Python ≥ 3.10. Core deps: numpy, scipy, pandas, joblib, numba, scikit-learn.
Quickstart
from comprisk import CompetingRiskForest
# event: 0 = censored, k≥1 = cause-k event. Defaults: 100 trees, logrankCR, n_jobs=-1.
forest = CompetingRiskForest(n_estimators=200, random_state=42).fit(X, time, event)
cif = forest.predict_cif(X[:5]) # (5, n_causes, n_times) — Aalen-Johansen
print(forest.oob_score(cause=1)) # honest out-of-bag C-index (no holdout split)
shap, base = forest.shap_values(X[:10]) # exact TreeSHAP (n, p, n_times, n_causes)
Prediction shapes, scoring, cross-validation, VIMP, minimal depth, GPU, and rfSRC
migration — all with runnable code — are in the
quickstart. CompetingRiskForest is a real sklearn
estimator (cross_val_score / Pipeline work without a wrapper).
Regression & non-parametric models
from comprisk import FineGrayRegression
fg = FineGrayRegression(cause=1, robust_se=True).fit(X, time=time, event=event)
print(fg.coef_, fg.se_) # log subdistribution-HRs
| Estimator | Estimates | R parity |
|---|---|---|
FineGrayRegression |
subdistribution-hazard ratios | cmprsk::crr() (β̂ to fp noise) |
PenalizedFineGrayRegression |
LASSO / ridge / EN / MCP / SCAD path | crrp::crrp() to ~1e-6 |
CauseSpecificCox |
cause-specific hazard ratios | survival::coxph() to 1e-9 |
CumulativeIncidence |
non-parametric Aalen-Johansen CIF | cmprsk::cuminc() |
gray_test |
K-sample test for equal CIFs | cmprsk::cuminc()$Tests to 1e-14 |
Worked code for every row is in
examples/02_regression_models.ipynb.
comprisk vs alternatives
| comprisk | randomForestSRC | scikit-survival | |
|---|---|---|---|
| Language | Python | R | Python |
| Native competing risks | ✓ | ✓ | ✗ (single-event) |
| Aalen–Johansen CIF output | ✓ | ✓ | n/a |
| Cumulative hazard at scale | ✓ | ✓ | ✗ (low-memory only) |
| OOB permutation VIMP | ✓ | ✓ | ✗ |
| Bit-identical reproducibility mode | ✓ (equivalence="rfsrc") |
— | n/a |
| Scales to n = 10⁶ | ✓ (63 s on i7) | memory-bound | ✗ / OOM |
| GPU preview | ✓ (CUDA 12) | ✗ | ✗ |
scikit-survival's CHF/survival outputs and scaling caveats are detailed in the benchmarks.
Benchmarks
Matched-pair, real EHR data (full tables + methodology in docs/benchmarks.md):
| Cohort | n × p | comprisk | rfSRC (OMP-on) | Speedup |
|---|---|---|---|---|
| CHF (cardio) | 75k × 58 | 5.6–9.4 s | 84.8–207.3 s | 14–22× |
| SEER breast | 238k × 17 | 7.0 s | 81.6 s | 11.6× |
Both fit similarly well (C ≈ 0.85); the band tracks feature count. Also 16.6–544× vs scikit-survival (n = 5k → 50k) and n = 10⁶ in 63 s on a consumer i7.
Roadmap
comprisk is intentionally CR-focused — for non-CR survival (general Cox, AFT, deep-survival), use lifelines or scikit-survival.
- Shipped (v0.3–0.6): CR forest, Fine-Gray (+ penalized), cause-specific Cox,
Aalen-Johansen CIF, Gray's test,
score_cr/calibration_cr. - v1.0 (planned): API freeze + JMLR MLOSS submission.
- v1.1 (planned): full GPU rewrite.
Documentation
📖 Full documentation site — searchable, autogenerated API reference.
- Quickstart — common tasks with runnable code
- API reference — full parameter lists
- Benchmarks — full tables, methodology, reproduction scripts
- Equivalence vs rfSRC — cross-library validation
- References — algorithmic provenance
Examples
Runnable notebooks in examples/ (rendered on GitHub; open in Colab to run):
01_forest_quickstart.ipynb— fit → CIF → OOB scoring → VIMP → minimal-depth selection02_regression_models.ipynb— Fine-Gray, cause-specific Cox, AJ by group, Gray's test, penalized FGshap_explain.py— interactive marimo TreeSHAP app
Development
Requires uv.
uv venv && uv pip install -e ".[dev]"
uv run pre-commit install
uv run pytest && uv run ruff check .
License & citation
Apache-2.0 (LICENSE, NOTICE). Cite via the DOI below (concept-level,
resolves to latest) or GitHub's "Cite this repository" button (CITATION.cff):
@software{yang_comprisk_2026,
author = {Yang, Sunny and Zhao, Wanqi},
title = {{comprisk: a Python toolkit for competing risks}},
year = {2026},
publisher = {Zenodo},
doi = {10.5281/zenodo.19876282},
url = {https://doi.org/10.5281/zenodo.19876282},
}
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file comprisk-0.7.0.tar.gz.
File metadata
- Download URL: comprisk-0.7.0.tar.gz
- Upload date:
- Size: 322.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95d40b913ade87f32da273703c8b118b27f457a0e11d8bb89b2bc7c8c5c70709
|
|
| MD5 |
ad8799dc2fd40305912032cf619b5221
|
|
| BLAKE2b-256 |
ae0555906f8f7459f4e3a3c108a9296abb6c2384f9d7a88278d0c8d040bbe3b1
|
File details
Details for the file comprisk-0.7.0-py3-none-any.whl.
File metadata
- Download URL: comprisk-0.7.0-py3-none-any.whl
- Upload date:
- Size: 147.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc616c8591b762a80bc3becd89c38e42a46f0fb42a133efdb06a83efb3fd15d3
|
|
| MD5 |
d974d9c36b8ef9c5d2b8a3cf82812352
|
|
| BLAKE2b-256 |
9e77a2cba01fc8525fa7e24ed005b8fa7129a8a472ec8a6e2ccde0a49fb6829d
|