API stability¶
Status: beta on PyPI. Until 1.0, an API-breaking change bumps the minor
version; a change that only alters computed numbers may ship in any release.
Both are listed in the changelog with the reasoning and keep an escape hatch
where the old behaviour had legitimate uses. A deprecated symbol warns with a
DeprecationWarning for at least one minor release before removal, naming its
replacement. Serialized artifacts carry a stronger promise: every 0.x release
reads schema 1, pinned by golden files in CI.
Two kinds of change¶
API-breaking. A public symbol is removed or renamed, a signature changes incompatibly, or a documented behaviour changes meaning. Before 1.0 this bumps the minor version, is listed in the changelog with the reasoning, and goes through the deprecation policy below.
Numerically visible. A default estimator, a numeric path, or a fitted
internal changes so that computed numbers move while every public call
still works. This may ship in a patch release. It always comes with a
changelog entry stating the size of the change and, where feasible, a
parameter that recovers the old values (the bins=None/grid_size=None
pattern).
What a patch release may therefore change: metric defaults and numeric
paths with an escape hatch; the shape of fitted internals that are not
part of the calibrator protocol (such as ENIRCalibrator.path_solutions_);
performance, documentation, and packaging. What it may not: public
signatures, exported names, the calibrator protocol, and the ability to
read every schema-1 artifact.
Public surface¶
The public API is exactly the export lists below; anything prefixed with
_ or not exported is internal and may change without notice.
probcal.__all__: the calibrators (PlattCalibrator,TemperatureCalibrator,BetaCalibrator,IsotonicCalibrator,CenteredIsotonicCalibrator,HistogramBinningCalibrator,ScalingBinningCalibrator,BBQCalibrator,ENIRCalibrator,VennAbersCalibrator,CrossVennAbersCalibrator,SplineCalibrator,SegmentedCalibrator),BaseCalibrator,UnattainableTargetError,CalibratorSelector,CalibratedModel,LogitOffset,OffsetEstimate,estimate_offset,offset_from_estimate,Chain,Masterscale,GradeTable, the reliability curves andcalibration_belt, threshold translation (calibrated_interval_to_raw,calibrated_bands_to_raw,build_masterscale), attribution repair,make_pd_portfolio,expit/logit, and themetrics/monitorsubmodules.probcal.metrics.__all__: the 47-symbol metric catalog (proper scores, binned and binning-free calibration errors, per-grade backtests, the mixture-LR grade e-test, Pluto-Tasche most-prudent PDs, Jeffreys upper masterscale bands, the recalibration-regression framework, SKCE,evaluate).probcal.monitor.__all__:CalibrationMonitor,MonitorStep,MonitorReport,AppliedAction,moc_offset,moc_offset_from_counts.probcal.sklearn.__all__(extraprobcal[sklearn]):SklearnCalibrator,SklearnOffset,CalibratedClassifier.probcal.integrations.optbinning.__all__(extraprobcal[optbinning]):calibrate_scorecard,CalibratedScorecard.probcal.plots.__all__(extraprobcal[viz]): the plotting catalog, includingplot_e_process.probcal.report.__all__(extraprobcal[viz]):validation_report. Not re-exported from top-levelprobcal, soimport probcalandimport probcal.reportboth stay matplotlib-free at import time.
New public symbols per release are listed in the changelog under Added.
Conventions that will not silently change¶
- New parameters are keyword-only; fitted attributes end in
_. import probcaldepends on numpy and the standard library only, enforced by a test rather than by review.- No silent clamps or approximations: numeric shortcuts keep an exact
escape hatch; refusals name the reason and the alternative
(
UnattainableTargetErrordoctrine). - Serialization is JSON, never pickle.
Deprecation policy¶
Pre-1.0: a deprecated symbol warns (DeprecationWarning) for at least one
minor release before removal, with the replacement named in the warning
and the changelog. Behavioral changes that alter numbers ship with a
detailed changelog entry and, where feasible, a parameter that
recovers the old values.
Deprecated in 0.3.4, all removed in 0.4.0 (each warns with a
DeprecationWarning naming its replacement; until then the deprecated
spelling keeps working):
| Deprecated | Replacement |
|---|---|
metrics.adaptive_ece(...) |
metrics.ece(..., strategy="mass") |
metrics.ecce(..., presorted=...) |
drop the argument (it is still honoured) |
metrics.evaluate(..., seed=...) |
random_state= (passing both raises TypeError) |
metrics.hosmer_lemeshow(..., g=...) |
n_bins= |
level= on metrics.jeffreys_upper_bands, curves.reliability_smooth, curves.corp_reliability |
confidence= (CorpResult.level keeps its name) |
BeltResult.lower_80 / upper_80 / lower_95 / upper_95 |
belt.bands[level], with the levels in belt.levels |
BBQCalibrator.weights_, ENIRCalibrator.weights_ |
model_weights_ |
positional CalibratedModel.offset_to(...) |
keywords target_mean= / delta= / X= |
positional LogitOffset.fit(p, sample_weight) |
LogitOffset.fit(p, sample_weight=...) |
The changelog lists every release that adds or removes a deprecation.
scikit-learn estimator checks¶
sklearn.utils.estimator_checks generates multi-column feature matrices of
arbitrary reals. Its data model contains no score-level estimator, so most of
the corpus cannot be run against SklearnCalibrator at all, the same kind of
domain restriction imbalanced-learn declares for its resamplers. Those checks
are declared inapplicable through sklearn's own mechanism
(expected_failed_checks on 1.6+, _more_tags()["_xfail_checks"] below it),
each entry naming the data that check generates and which part of the
score-level contract it violates. They are inapplicable, not known failures;
the checks whose data the contract does admit run live and pass. The
declarations are data in probcal.sklearn._xfail (imported lazily by the
adapters' _more_tags(), since sklearn < 1.6 reads them from the estimator
at runtime, and directly by the tests). CalibratedClassifier declares only
sklearn < 1.6's check_sample_weights_invariance (weight ≡ duplication cannot
hold through an integer-cv split); on 1.6+ its
check_sample_weight_equivalence_on_dense_data runs live and passes.
Every inapplicable check with a score-level analogue is re-implemented on
valid (n,) probability data in tests/test_sklearn_mirror_checks.py: fit
idempotence, no mutation of the passed arrays, __dict__ unchanged by the
predict-side methods, pickle (adapter) and JSON (core) round trips,
clone-then-fit, subset and sample-order invariance, and integer
sample_weight equal to row duplication over every registered calibrator
class, with the exceptions (CV- and quantile-based internals) named in a
table together with their measured tolerance. Checks with no analogue at all
(multiclass, pairwise, sparse) are listed in that module's docstring with one
line each. The score-level contract itself is pinned by
tests/test_calibrator_protocol.py.
Support matrix¶
| Dimension | Supported | Checked by |
|---|---|---|
| Python | 3.11, 3.12, 3.13 | CI matrix |
| numpy | ≥ 1.26, including 2.x | CI (lockfile tracks latest) |
| scikit-learn (adapter extra) | ≥ 1.4 | CI jobs at 1.4.2 and latest |
| scikit-learn (bare-core duck typing, no adapter) | ≥ 1.6 only | tests/test_sklearn_duck.py (importorskip(minversion="1.6")); runs in the main CI matrix (latest sklearn), skipped on the 1.4.2 sklearn-min job |
| optbinning (integration extra) | ≥ 0.21 | CI job at 0.21.0 |
| treecf (integration extra) | ≥ 0.2.4 | joint smoke test when installed |