API: integrations¶
Optional extras; each module imports its dependency only when used.
sklearn
¶
scikit-learn adapter: probcal calibrators as sklearn estimators.
Requires the probcal[sklearn] extra; import probcal itself stays
numpy-only — this subpackage is imported explicitly by its users.
SklearnCalibrator
¶
SklearnCalibrator(calibrator: BaseCalibrator | None = None, *, input: str = 'probability', positive_column: int = 1)
Bases: BinaryCalibratedMixin, ClassifierMixin, TransformerMixin, BaseEstimator
Probability calibration over a single score column, sklearn-style.
Wraps any probcal calibrator as a scikit-learn classifier/transformer
whose X is the score itself — shape (n,), (n, 1), or (in
probability mode) a two-column predict_proba-style matrix. Use it
to end a Pipeline (via :meth:transform) or anywhere an sklearn
estimator is expected; the fitted probcal object stays one attribute
away (calibrator_) with its full audit surface (interpret(),
interval_inverse, to_dict, fingerprint()). The prototype
passed as calibrator may also be a :class:~probcal.Chain.
The calibrator protocol (is_monotone_, interval_inverse,
point_inverse, affine_logit_coeffs_, interpret) and the JSON
surface (to_dict, to_json, fingerprint) are delegated to
calibrator_, exactly as on :class:CalibratedClassifier.
| PARAMETER | DESCRIPTION |
|---|---|
calibrator
|
Unfitted probcal prototype, cloned via
TYPE:
|
input
|
Scale of the score column.
TYPE:
|
positive_column
|
Which column of a two-column probability matrix holds
TYPE:
|
| ATTRIBUTE | DESCRIPTION |
|---|---|
calibrator_ |
The fitted probcal calibrator.
TYPE:
|
classes_ |
Class labels in
TYPE:
|
n_features_in_ |
1 or 2, depending on the
TYPE:
|
Source code in src/probcal/sklearn/_calibrator.py
57 58 59 60 61 62 63 64 65 66 | |
fit
¶
fit(X: object, y: object, sample_weight: object = None) -> SklearnCalibrator
Fit the wrapped calibrator on the score column.
| PARAMETER | DESCRIPTION |
|---|---|
X
|
Scores (probabilities, or logits with
TYPE:
|
y
|
Binary target; any two label values.
TYPE:
|
sample_weight
|
Non-negative observation weights; zero-weight rows are excluded (sklearn semantics).
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
SklearnCalibrator
|
The fitted adapter. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
Source code in src/probcal/sklearn/_calibrator.py
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 | |
transform
¶
transform(X: object) -> ndarray
Calibrated-probability column (n, 1) — lets the adapter end a Pipeline.
Source code in src/probcal/sklearn/_calibrator.py
138 139 140 | |
CalibratedClassifier
¶
CalibratedClassifier(estimator: object = None, *, calibrator: BaseCalibrator | None = None, cv: object = 5, method: str = 'predict_proba', stratify: bool = True, random_state: int | None = None)
Bases: BinaryCalibratedMixin, ClassifierMixin, BaseEstimator
Cross-validated probability calibration of a classifier, probcal-style.
The drop-in for sklearn.calibration.CalibratedClassifierCV with
ensemble=False: out-of-fold scores via cross_val_predict, one
probcal calibrator fitted on the pooled OOF scores, and the estimator
refit on all data (unless cv="prefit"). What probcal adds on top:
the fitted calibrator's audit surface (interpret(), bootstrap CIs
via probcal.metrics.evaluate), exact inverse maps, JSON
serialization, and fingerprints — see guide/sklearn.md.
Also exposes the probcal calibrator protocol (is_monotone_,
interval_inverse, point_inverse, affine_logit_coeffs_,
fingerprint) by delegation to calibrator_, so a fitted instance
can be handed directly to consumers of that protocol (e.g. treecf's
Target.calibrated).
X is passed to the estimator untouched (no float conversion), like
CalibratedClassifierCV: DataFrames, mixed-dtype columns for a
ColumnTransformer pipeline, and sparse matrices all work.
| PARAMETER | DESCRIPTION |
|---|---|
estimator
|
Classifier to calibrate.
TYPE:
|
calibrator
|
Unfitted probcal prototype (cloned via
TYPE:
|
cv
|
An integer
TYPE:
|
method
|
Score source.
TYPE:
|
stratify
|
For an integer
TYPE:
|
random_state
|
Fold-shuffling seed for an integer
TYPE:
|
| ATTRIBUTE | DESCRIPTION |
|---|---|
estimator_ |
The deployed classifier (input estimator for
TYPE:
|
calibrator_ |
The fitted probcal calibrator (one map, pooled OOF scores).
TYPE:
|
classes_ |
Class labels; column 1 of :meth:
TYPE:
|
n_features_in_ |
Copied from
TYPE:
|
Notes
:class:probcal.CalibratedModel (flow="cv") runs the same
out-of-fold protocol without sklearn, with deliberate differences:
its folds are always class-stratified and drawn with numpy's
default_rng(random_state) (so the same seed assigns different folds
than StratifiedKFold), and it alone offers ensemble=True (one
calibrator per fold). Both pass X to the model untouched and hand
sample_weight to the model fits when the estimator accepts it. Use this class inside
sklearn pipelines and searches, CalibratedModel for a numpy-only
deployment wrapper.
Source code in src/probcal/sklearn/_classifier.py
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | |
fit
¶
fit(X: object, y: object, sample_weight: object = None) -> CalibratedClassifier
Fit per the out-of-fold protocol (or score directly when prefit).
| PARAMETER | DESCRIPTION |
|---|---|
X
|
Features, passed to the wrapped estimator untouched.
TYPE:
|
y
|
Binary target; any two label values.
TYPE:
|
sample_weight
|
Non-negative observation weights (zero excludes a row from the
calibrator fit). Always used for the calibrator stage; also
handed to the cross-validated fits and the refit when the
estimator can take them. When it cannot, a
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
CalibratedClassifier
|
The fitted wrapper. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
| WARNS | DESCRIPTION |
|---|---|
UserWarning
|
If |
Source code in src/probcal/sklearn/_classifier.py
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | |
SklearnOffset
¶
SklearnOffset(delta: float | None = None, target_mean: float | None = None, *, positive_column: int = 1)
Bases: TransformerMixin, BaseEstimator
A logit offset over a probability column, sklearn-style.
Wraps :class:~probcal.offset.LogitOffset as an sklearn transformer
whose X is the probability itself — shape (n,), (n, 1), or
a two-column predict_proba-style matrix — so it can end (or sit
inside) a Pipeline right after a :class:~probcal.sklearn.SklearnCalibrator
step. The offset is deliberately a separate pipeline step rather than
a parameter folded into the calibrator: it keeps the central-tendency
re-anchoring inspectable and swappable on its own, exactly as
:class:~probcal.chain.Chain keeps it a separate stage. No y is
consumed (LogitOffset ignores it), so there is no orientation
check to run — the column-1 convention for two-column input is
documented (guide/sklearn.md), not checked.
| PARAMETER | DESCRIPTION |
|---|---|
delta
|
Mode A: the log-odds shift to apply directly. Mutually exclusive
with
TYPE:
|
target_mean
|
Mode B: the desired post-shift portfolio mean probability,
solved by bisection. Mutually exclusive with
TYPE:
|
positive_column
|
Which column of a two-column probability matrix holds
TYPE:
|
| ATTRIBUTE | DESCRIPTION |
|---|---|
offset_ |
The fitted inner offset.
TYPE:
|
n_features_in_ |
1 or 2, depending on the
TYPE:
|
Source code in src/probcal/sklearn/_offset.py
49 50 51 52 53 54 55 56 57 58 | |
fit
¶
fit(X: object, y: object = None, sample_weight: object = None) -> SklearnOffset
Fit the wrapped offset on the probability column.
| PARAMETER | DESCRIPTION |
|---|---|
X
|
Probabilities, or a two-column probability matrix.
TYPE:
|
y
|
Ignored; accepted for pipeline/estimator compatibility.
TYPE:
|
sample_weight
|
Non-negative observation weights; zero-weight rows are excluded (sklearn semantics), a negative weight raises.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
SklearnOffset
|
The fitted adapter. |
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If |
Source code in src/probcal/sklearn/_offset.py
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | |
transform
¶
transform(X: object) -> ndarray
Shifted probability column (n, 1) — lets the adapter end a Pipeline.
Source code in src/probcal/sklearn/_offset.py
107 108 109 | |
predict_proba
¶
predict_proba(X: object) -> ndarray
(n, 2) matrix [1 - p_shifted, p_shifted].
Source code in src/probcal/sklearn/_offset.py
111 112 113 114 115 116 | |
to_dict
¶
to_dict() -> dict[str, object]
The fitted inner offset's own envelope (loads back as a LogitOffset).
Source code in src/probcal/sklearn/_offset.py
118 119 120 121 | |
CalibratedScorecard serialization and scope¶
CalibratedScorecard (from calibrate_scorecard) serializes its calibration
layer with to_dict/to_json and checks provenance with fingerprint(), like
every probcal artifact. The scorecard itself is optbinning's object and is not
serialized, so loading needs it back:
CalibratedScorecard.from_json(path_or_str, scorecard=sc) (or from_dict(d,
scorecard=sc)). For the same reason the class is deliberately not in the
serialization registry that class-name dispatch such as
BaseCalibrator.from_dict(d) goes through (see
Serialization): a payload alone
could not rebuild it without the scorecard object.
The stored scorecard fingerprint is SHA-256 of a canonical JSON rendering of
table(style="detailed") (floats to 12 significant digits), so it does
not depend on pandas' formatting. A mismatch raises ValueError.
If the scorecard's probability is constant on the calibration data, the
points-to-log-odds map is unidentifiable: calibrate_scorecard warns,
points_affine_coeffs_ is None, and masterscale() refuses, exactly as
for rounding=True. predict_proba returns a 1-D array of calibrated PDs
(the probcal convention, so it feeds probcal.metrics directly); a scorecard
is not an sklearn estimator, and probcal.sklearn.CalibratedClassifier is the
route when sklearn's (n, 2) semantics are needed.
optbinning
¶
Calibrated optbinning scorecards.
Requires the probcal[optbinning] extra (optbinning >= 0.21). The
scorecard stays the deployed artifact — points are untouched; probcal adds a
calibrated PD layer on top plus exact translation between calibrated PD
bands and point cut-offs, possible because Scorecard.score is affine in
the fitted logistic regression's log-odds unless rounding=True.
CalibratedScorecard
¶
CalibratedScorecard(scorecard: object, calibrator: BaseCalibrator, points_affine_coeffs: tuple[float, float] | None)
Bases: JsonIO, CalibratorProtocolMixin
An optbinning Scorecard with a probcal calibration layer on top.
Built by :func:calibrate_scorecard. Points (score) are unchanged —
the scorecard remains the deployed artifact; predict_proba returns
the calibrated PD, and the calibrator protocol (interval_inverse,
point_inverse, ...) operates on the scorecard's model-probability
scale, so calibrated policies translate to raw probabilities and — via
points_affine_coeffs_ — exactly to the points scale.
predict_proba returns the 1-D calibrated PD (the probcal calibrator
convention), not sklearn's (n, 2) matrix: a scorecard is not an
sklearn estimator, and the 1-D form feeds probcal.metrics directly.
Persist with :meth:to_json and reload with
CalibratedScorecard.from_json(path, scorecard=...); the class is not
in the generic probcal load registry because a payload cannot be
rebuilt without the scorecard object, which optbinning persists itself.
| ATTRIBUTE | DESCRIPTION |
|---|---|
scorecard_ |
The wrapped, fitted scorecard.
TYPE:
|
calibrator_ |
The fitted probcal calibrator over the scorecard's probabilities.
TYPE:
|
points_affine_coeffs_ |
TYPE:
|
Source code in src/probcal/integrations/optbinning.py
96 97 98 99 100 101 102 103 104 | |
predict_proba
¶
predict_proba(X: object) -> ndarray
Calibrated PD for scorecard inputs (1-D, probcal convention).
Source code in src/probcal/integrations/optbinning.py
111 112 113 | |
score
¶
score(X: object) -> ndarray
Unchanged scorecard points — the deployed artifact is untouched.
Source code in src/probcal/integrations/optbinning.py
115 116 117 | |
masterscale
¶
masterscale(bands: object) -> dict[str, tuple[float, float]]
Calibrated PD bands -> scorecard point cut-offs, exactly.
Composes :func:probcal.thresholds.calibrated_bands_to_raw (bands on
the calibrated scale to raw log-odds intervals) with the verified
affine points map. Point intervals are returned as (lo, hi) with
lo <= hi (the affine slope is negative for the usual
higher-points-safer scaling), and the cut-offs are checked for
monotone ordering across bands.
| PARAMETER | DESCRIPTION |
|---|---|
bands
|
Calibrated PD bands, e.g.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
dict[str, tuple(points_lo, points_hi)]
|
Point cut-offs per band, as plain floats ( |
| RAISES | DESCRIPTION |
|---|---|
RuntimeError
|
If the scorecard is not affine in log-odds ( |
Source code in src/probcal/integrations/optbinning.py
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 | |
to_dict
¶
to_dict() -> dict[str, object]
Calibrator envelope plus a fingerprint of the scorecard table.
The scorecard object itself is not serialized (it is optbinning's
artifact); rebuild with CalibratedScorecard.from_dict(d,
scorecard=...) (or from_json(path, scorecard=...)) after
loading the scorecard through optbinning's own save/load.
Source code in src/probcal/integrations/optbinning.py
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 | |
from_dict
classmethod
¶
from_dict(d: dict, scorecard: object) -> CalibratedScorecard
Rebuild around a scorecard loaded through optbinning's own tooling.
The stored scorecard-table fingerprint must match scorecard.
| RAISES | DESCRIPTION |
|---|---|
ValueError
|
If the payload class differs, or the supplied scorecard's table fingerprint does not match the stored one. |
Source code in src/probcal/integrations/optbinning.py
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 | |
scorecard_fingerprint
¶
scorecard_fingerprint() -> str
SHA-256 of the scorecard table — names the deployed artifact.
Computed over a canonical JSON form of the detailed table (column names, and every cell with floats kept to 12 significant digits), so it does not depend on the pandas version's CSV formatting.
Source code in src/probcal/integrations/optbinning.py
233 234 235 236 237 238 239 240 | |
calibrate_scorecard
¶
calibrate_scorecard(scorecard: object, X_cal: object, y_cal: object, *, calibrator: BaseCalibrator | None = None, sample_weight: object = None) -> CalibratedScorecard
Fit a probcal calibration layer on a fitted optbinning scorecard.
| PARAMETER | DESCRIPTION |
|---|---|
scorecard
|
Fitted scorecard with
TYPE:
|
X_cal
|
Held-out calibration data (never the scorecard's training data — see the data-splitting chapter).
TYPE:
|
y_cal
|
Held-out calibration data (never the scorecard's training data — see the data-splitting chapter).
TYPE:
|
calibrator
|
Unfitted probcal prototype;
TYPE:
|
sample_weight
|
Positive observation weights for the calibration fit.
TYPE:
|
| WARNS | DESCRIPTION |
|---|---|
UserWarning
|
When the points are not affine in log-odds ( |
| RETURNS | DESCRIPTION |
|---|---|
CalibratedScorecard
|
Calibrated PD layer over the unchanged scorecard, with the affine
points map recovered and verified (or refused with a warning when
|
Source code in src/probcal/integrations/optbinning.py
243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 | |