Skip to main content

probcal

PyPI Downloads DOI License: MIT Python

Probability calibration for binary classifiers, built for regulated PD models. The runtime is numpy only. The calibration maps are the standard ones; what probcal adds is the evidence a validator asks for next, which scikit-learn does not produce:

  • Logit-scale diagnostics that keep 1% readable. calibration_guardrails reports slope, intercept, and Spiegelhalter's test in log-odds, and every reliability plot can draw on a logit axis (scale="logit"; the default is "probability"), so a 3% portfolio is not crushed into the bottom-left corner.
  • An auditable offset stage. A central-tendency adjustment is a LogitOffset object, not a refit: audit_report() records the mean before and after, the guardrails before and after, a timestamp, and a fingerprint.
  • Per-grade regulatory backtests. binomial_grade_test and jeffreys_grade_test give the traffic-light table per rating grade, and jeffreys_upper_bands turns the same posteriors into a masterscale.

Installation

pip install probcal            # runtime: numpy only
pip install "probcal[viz]"     # + matplotlib for probcal.plots
pip install "probcal[sklearn]" # + scikit-learn for probcal.sklearn adapters

Beta on PyPI. The change policy, public surface, and support matrix are on the API stability page of the docs; serialized artifacts carry the stronger promise that every 0.x release reads schema 1. Development setup:

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

Quickstart

The three things above, in one run. The calibrator is fitted on one synthetic 3% portfolio and every number below is measured on a second, held-out draw; fitting and scoring the same rows would make the "after" line an identity (see Data splitting in the docs):

from probcal import BetaCalibrator, LogitOffset, Masterscale, make_pd_portfolio
from probcal.metrics import calibration_guardrails, jeffreys_grade_test

cal_set = make_pd_portfolio(n=8000, random_state=42)   # synthetic 3% PD portfolio
test = make_pd_portfolio(n=8000, random_state=1)       # held-out draw, same distortion

# 1. Logit-scale diagnostics: slope, intercept, Spiegelhalter, before and after
g0 = calibration_guardrails(test.y, test.scores)
print(f"before: slope={g0.slope:.3f}  intercept={g0.intercept:+.3f}  ok={g0.all_ok}")
cal = BetaCalibrator().fit(cal_set.scores, cal_set.y)
p = cal.predict_proba(test.scores)                    # evaluated on the held-out set
g1 = calibration_guardrails(test.y, p)
print(f"after:  slope={g1.slope:.3f}  intercept={g1.intercept:+.3f}  ok={g1.all_ok}")

# 2. An auditable offset: re-anchor to a 3.5% policy PD and record what it cost
off = LogitOffset(target_mean=0.035).fit(p)
print(off.audit_report(test.y, p))
p_final = off.transform(p)

# 3. Per-grade regulatory backtest on a fixed PD masterscale
ms = Masterscale.from_edges([0.01, 0.02, 0.05, 0.10], names=list("ABCDE"))
res = jeffreys_grade_test(test.y, p_final, ms)
for g, n, k, pd_, light in zip(res.grades, res.n, res.k, res.pd, res.light):
    print(f"grade {g}: n={n:5d}  defaults={k:3d}  PD={pd_:.4f}  {light}")

Output:

before: slope=0.901  intercept=-0.743  ok=False
after:  slope=0.922  intercept=+0.021  ok=True
AuditReport(delta=+0.1238, odds factor 1.1317, fitted <timestamp>)
  portfolio mean: 0.03126 -> 0.03500
  slope:          +0.922 -> +0.922
  intercept:      +0.021 -> -0.103
  spiegelhalter p 0.460 -> 0.271
  guardrails ok:  True -> False
grade A: n= 1696  defaults=  7  PD=0.0063  green
grade B: n= 2043  defaults= 22  PD=0.0146  green
grade C: n= 2684  defaults= 97  PD=0.0319  green
grade D: n= 1114  defaults= 70  PD=0.0681  green
grade E: n=  463  defaults= 59  PD=0.1685  green

The audit report says what the policy offset cost: the intercept guardrail now fails by exactly the applied shift, on the record. The executed end-to-end notebook takes a rare-event portfolio through selection, backtests, offsetting, threshold translation, and monitoring.

Three calibrators, and the rest

PlattCalibrator, BetaCalibrator, and IsotonicCalibrator are the production path: the quickstart and the benchmark use them, each has exact inverse maps, interpret(), and JSON serialization pinned by golden files. Ten more (temperature, centered isotonic, histogram binning, scaling-binning, BBQ, ENIR, Venn–Abers IVAP and CVAP, spline, segmented) and the nested-CV CalibratorSelector are in the calibrator catalog, with monotonicity, inverses, data appetite, and fit cost per row. The 47-symbol metric catalog, with which metrics are safe to select on, is in Metrics and tests.

Serialization

Every fitted object round-trips through versioned, human-readable JSON, never pickle (auditable; loading executes no code):

cal.to_json("beta.json")
loaded = BetaCalibrator.from_json("beta.json")   # bit-identical predictions
cal.fingerprint()                                # sha-256 provenance id

Compatibility promise: every 0.x release reads schema 1, enforced by committed golden files in CI; schema bumps ship only with a converter. Details: the Serialization concepts chapter.

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. The Visualization chapter is a gallery of every plot, regenerated deterministically by docs/scripts/generate_figures.py; the CORP reliability diagram, MCB-DSC plane, and score decomposition have their own CORP and score decomposition chapter.

License

MIT. See LICENSE. GPL-licensed R packages are used as conceptual references only; no GPL code is included.

Metadata

Release files for probcal 0.3.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for probcal 0.3.5
File Size Uploaded
probcal-0.3.5.tar.gz 2.6 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for probcal 0.3.5
File Interpreter ABI Platform
probcal-0.3.5-py3-none-any.whl Python 3 none any Details

Total release size: 2.9 MB

Release files / probcal-0.3.5.tar.gz

Download URL probcal-0.3.5.tar.gz
Size 2.6 MB
Tags Source
SHA-256 checksum
How to use checksums
85a30f8d2934f205ae0901bd81875d6067276276cf200feed81faccf3c7b9363
BLAKE2b-256 checksum
How to use checksums
001ca6ee2f96547b7f990affb7975e61b59224f37f78ff1771b63e2b629175b7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release files / probcal-0.3.5-py3-none-any.whl

Download URL probcal-0.3.5-py3-none-any.whl
Size 252.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a351fcbb5c6ee7f6b450dd5a170495db4a12c2033a1165bf2ac512a560702bb5
BLAKE2b-256 checksum
How to use checksums
655800e62fe86677fa68a8b491f556f16468cd7c52fdc8bab861d7fbed9567c8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 12, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.5 This release

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release 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