Skip to main content

probcal

PyPI License: MIT Python

Universal post-hoc probability calibration for binary classifiers: methods, metrics, diagnostics, and auditable offsetting — numpy-only.

probcal unifies the binary calibration literature (Platt, temperature, beta, isotonic, centered isotonic, histogram binning, scaling-binning, BBQ, ENIR, Venn–Abers, spline calibration), an extensive catalog of calibration evaluation metrics and statistical tests, calibration visualization on both probability and logit scales, an auditable logit-offset (central tendency) adjustment, automatic method selection under nested validation, and two data flows (prefit and cross-validation). Primary application domain: credit-risk PD models; the package is fully general.

Status: released on PyPI, beta. The API is stable enough to build on; breaking changes bump the minor version until 1.0.

Installation

pip install probcal            # runtime: numpy only
pip install "probcal[viz]"     # + matplotlib for probcal.plots

Development setup (tests, lint, type-check):

git clone https://github.com/wlazlod/probcal && cd probcal
uv sync --extra dev

Quickstart

from probcal import BetaCalibrator, make_pd_portfolio
from probcal.metrics import calibration_guardrails

port = make_pd_portfolio(n=8000, random_state=42)   # synthetic 3% PD portfolio

g_before = calibration_guardrails(port.y, port.scores)
print(f"before: slope={g_before.slope:.3f}  intercept={g_before.intercept:+.3f}  ok={g_before.all_ok}")

cal = BetaCalibrator().fit(port.scores, port.y)
p = cal.predict_proba(port.scores)

g_after = calibration_guardrails(port.y, p)
print(f"after:  slope={g_after.slope:.3f}  intercept={g_after.intercept:+.3f}  ok={g_after.all_ok}")
print()
print(cal.interpret())

Output:

before: slope=0.968  intercept=-0.765  ok=False
after:  slope=1.000  intercept=+0.000  ok=True

Interpretation[BetaCalibrator]
parameter  value
---------  --------
a          0.875054
b          1.58922
c          -1.15227
- a = 0.875: sensitivity near s -> 0; a < 1 raises the smallest probabilities (model was overconfident in the low tail), a > 1 deepens them
- b = 1.589: sensitivity near s -> 1; the mirrored reading for the high tail
- c = -1.152: base-rate shift of -1.152 log-odds, odds factor 0.316
- identity map corresponds to (a, b, c) = (1, 1, 0)
- a != b (gap -0.714): asymmetric tail distortion that no symmetric (Platt/temperature) map could express

Automatic selection, model wrapping, offsetting, and threshold translation:

from probcal import CalibratedModel, CalibratorSelector, PlattCalibrator

sel = CalibratorSelector().fit(s_cal, y_cal)             # nested CV, log-loss criterion
wrapped = CalibratedModel(model, PlattCalibrator(), flow="prefit").fit(X_cal, y_cal)
wrapped.offset_to(target_mean=0.031)                     # auditable central-tendency stage
lo_z, hi_z = wrapped.interval_inverse(0.0, 0.02, space="logit")   # "PD <= 2%" in raw margins

Why probcal

Capability probcal scikit-learn netcal probcal (R)² single-method packages¹
Calibration methods 11 2 many 5 binary³ 1 each
Runtime dependencies numpy scipy stack torch stack native R varies
Logit-scale diagnostics (low-PD readable) yes
First-class auditable offset (central tendency) yes
Automatic selection under nested validation yes
Venn–Abers intervals yes venn-abers
Metric catalog with selection-suitability guidance yes partial partial partial
Per-grade regulatory backtests (binomial, Jeffreys) yes
Kernel calibration error and test (SKCE, Widmann et al.) yes yes
Calibrated→raw threshold translation (interval_inverse) yes
SHAP additivity repair on the calibrated scale yes
Parameter interpretation (interpret()) on every method yes partial

¹ betacal, venn-abers, ml-insights. ² prdm0/probcal (P. R. Diniz Marinho), unaffiliated — see the FAQ. Verified against v0.2.0, 2026-08-08. ³ Platt, temperature, beta, isotonic, histogram binning; its multiclass methods (Dirichlet, vector scaling, one-vs-rest) are out of probcal's binary scope.

Performance note: the PAVA family and special functions are hand-rolled numpy/stdlib; profiling on real workloads has not shown them to be a bottleneck. Rust acceleration is deliberately out of scope unless benchmarks on production-sized portfolios say otherwise.

Documentation

Built with mkdocs-material; run locally with uv run mkdocs serve. Start with Getting started, then the Concepts chapters — the package's theoretical foundation — and the executed PD calibration walkthrough notebook. The Visualization chapter is a gallery of every plot, regenerated deterministically by docs/scripts/generate_figures.py.

License

MIT. See LICENSE and docs/LICENSING.md for the conceptual-reference policy on GPL-licensed R packages.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

probcal-0.1.2.tar.gz (811.9 kB view details)

Uploaded Source

Built Distribution

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

probcal-0.1.2-py3-none-any.whl (76.7 kB view details)

Uploaded Python 3

File details

Details for the file probcal-0.1.2.tar.gz.

File metadata

  • Download URL: probcal-0.1.2.tar.gz
  • Upload date:
  • Size: 811.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for probcal-0.1.2.tar.gz
Algorithm Hash digest
SHA256 faca9c3512979676d6051c8d64e4309b550c1bc751a85df68080676dcda3fadf
MD5 021342bfdb1e58011fcfb1342edd9c53
BLAKE2b-256 ba767147b0e571a5b2e509c91c5dabc4ff35c953ac1430086c853450d7400f03

See more details on using hashes here.

Provenance

The following attestation bundles were made for probcal-0.1.2.tar.gz:

Publisher: publish.yml on wlazlod/probcal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file probcal-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: probcal-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 76.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for probcal-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4fee47dc2252f173e69fbc137d0126d6a934c3764e6b2354e41bba3c11ca2ca3
MD5 94b491831d233cf395827f6368194ea4
BLAKE2b-256 84c689631a2730bbc734080c6880dc790a01caeb7b77755b63e5afd04d0f0690

See more details on using hashes here.

Provenance

The following attestation bundles were made for probcal-0.1.2-py3-none-any.whl:

Publisher: publish.yml on wlazlod/probcal

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.3.0

2 files

0.2.0

2 files

0.1.3

2 files

This release

0.1.2 This release

2 files

0.1.1

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page