Skip to main content

comprisk

PyPI version CI docs DOI

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 crforest in 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 evaluationscore_cr (IPCW time-dependent AUC/Brier + bootstrap CIs) and calibration_cr, replacing the CR-mode riskRegression::Score() block; concordance_index_ci gives a closed-form (no-bootstrap) CI for the Uno C-index and a paired model-comparison concordance_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 →
  • Reproducibleequivalence="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.

Examples

Runnable notebooks in examples/ (rendered on GitHub; open in Colab to run):

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

comprisk-0.7.0.tar.gz (322.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

comprisk-0.7.0-py3-none-any.whl (147.3 kB view details)

Uploaded Python 3

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

Hashes for comprisk-0.7.0.tar.gz
Algorithm Hash digest
SHA256 95d40b913ade87f32da273703c8b118b27f457a0e11d8bb89b2bc7c8c5c70709
MD5 ad8799dc2fd40305912032cf619b5221
BLAKE2b-256 ae0555906f8f7459f4e3a3c108a9296abb6c2384f9d7a88278d0c8d040bbe3b1

See more details on using hashes here.

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

Hashes for comprisk-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cc616c8591b762a80bc3becd89c38e42a46f0fb42a133efdb06a83efb3fd15d3
MD5 d974d9c36b8ef9c5d2b8a3cf82812352
BLAKE2b-256 9e77a2cba01fc8525fa7e24ed005b8fa7129a8a472ec8a6e2ccde0a49fb6829d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page