Calibration Methods¶
This module contains all calibration algorithms implemented in Calibre.
Base Classes¶
- class calibre.BaseCalibrator(enable_diagnostics: bool = False)[source]¶
Bases:
BaseEstimator,TransformerMixinBase class for all calibrators.
All calibrator classes should inherit from this base class to ensure consistent API and functionality. This follows the scikit-learn transformer interface with fit/transform/fit_transform methods.
- Parameters:
enable_diagnostics – Whether to run plateau diagnostics after fitting.
Notes
Subclasses must implement the fit() and transform() methods. The fit_transform() method is provided by default.
Examples
>>> import numpy as np >>> from calibre import BaseCalibrator >>> >>> class SimpleCalibrator(BaseCalibrator): ... def __init__(self, enable_diagnostics=False): ... super().__init__(enable_diagnostics=enable_diagnostics) ... def fit(self, X, y): ... self.mean_ = np.mean(y) ... return self ... ... def transform(self, X): ... return np.full_like(X, self.mean_) >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = SimpleCalibrator() >>> cal.fit(X, y) >>> cal.transform(X) array([0.667, 0.667, 0.667])
- diagnostic_summary()[source]¶
Get a human-readable summary of diagnostic analysis.
- Returns:
summary (str) – Human-readable plateau summary.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> print(cal.diagnostic_summary())
- fit(X: ndarray, y: ndarray)[source]¶
Fit the calibrator.
This method implements the template method pattern: it handles data storage and diagnostics, while delegating the actual fitting logic to the abstract _fit_impl() method that subclasses must implement.
- Parameters:
X – The values to be calibrated (e.g., predicted probabilities).
y – The target values (e.g., true labels).
- Returns:
BaseCalibrator – Returns self for method chaining.
- fit_transform(X: ndarray, y: ndarray)[source]¶
Fit the calibrator and then transform the data.
This is a convenience method that combines fit() and transform() in a single call. The default implementation simply calls fit() followed by transform().
- Parameters:
X – The values to be calibrated.
y – The target values.
- Returns:
ndarray– Calibrated values.
Examples
>>> import numpy as np >>> from calibre import IsotonicCalibrator >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> cal = IsotonicCalibrator() >>> X_calibrated = cal.fit_transform(X, y)
- get_diagnostics()[source]¶
Get diagnostic results.
- Returns:
dict | None – Diagnostic results from plateau analysis, or None if diagnostics were not computed or are not available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> diagnostics = cal.get_diagnostics() >>> if diagnostics: ... print(f"Found {diagnostics['n_plateaus']} plateaus")
- get_metadata_routing()¶
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing (MetadataRequest) – A
MetadataRequestencapsulating routing information.
- get_params(deep=True)¶
Get parameters for this estimator.
- Parameters:
deep (bool, default=True) – If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
params (dict) – Parameter names mapped to their values.
- has_diagnostics()[source]¶
Check if diagnostic information is available.
- Returns:
has_diag (bool) – True if diagnostics have been computed and are available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> if cal.has_diagnostics(): ... print("Diagnostics available!")
- set_output(*, transform=None)¶
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({“default”, “pandas”, “polars”}, default=None) – Configure output of transform and fit_transform.
“default”: Default output format of a transformer
“pandas”: DataFrame output
“polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self (estimator instance) – Estimator instance.
- set_params(**params)¶
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
**params (dict) – Estimator parameters.
- Returns:
self (estimator instance) – Estimator instance.
- transform(X: ndarray)[source]¶
Apply calibration to new data.
- Parameters:
X – The values to be calibrated.
- Returns:
ndarray– Calibrated values.- Raises:
NotImplementedError – This method must be implemented by subclasses.
Calibration Algorithms¶
Cost- and Data-Informed Isotonic Calibrator (Research)¶
- class calibre.CDIIsotonicCalibrator(thresholds: Iterable[float] | None = None, threshold_weights: Iterable[float] | None = None, bandwidth: float = 0.05, alpha: float = 0.05, gamma: float = 0.15, window: int = 25, normalize_scores: bool = True, clip_output: bool = True, _fitted: bool = False, _s_min: float = 0.0, _s_max: float = 1.0, _x_unique: ndarray | None = None, _x_unique_scaled: ndarray | None = None, _z_fit: ndarray | None = None, _L: ndarray | None = None, _R: ndarray | None = None, _w_block: ndarray | None = None)[source]¶
Bases:
BaseEstimator,TransformerMixinCost- and Data-Informed Isotonic calibrator (CDI-ISO).
- Parameters:
thresholds – Operating thresholds in [0,1] that matter economically. If None, uniform attention across the score range is assumed.
threshold_weights – Nonnegative weights matching thresholds. If None, equal weights.
bandwidth – Half-width h of the triangular kernel around each threshold (in score units, after optional min-max normalization). Defaults to 0.05.
alpha – Significance level for the two-proportion normal approximation used to gate minimum-slope enforcement (default 0.05 -> z≈1.96).
gamma – Global multiplier in [0,1] for the minimum-slope budget phi_i (default 0.15).
window – Number of adjacent unique-score points used on each side to form the left/right evidence blocks (default 25). Automatically clipped at edges.
normalize_scores – If True (default), min-max normalize training scores to [0,1] for the economics kernel; the same affine scaling is applied at transform time.
clip_output – If True (default), clip calibrated outputs to [0,1].
Notes
Builds local bounds L_i = phi_i - epsilon_i on sorted unique training scores.
Solves a single weighted PAVA on shifted labels (O(n)) and shifts back.
Predictions are stepwise-constant in the training score order.
- __init__(thresholds: Iterable[float] | None = None, threshold_weights: Iterable[float] | None = None, bandwidth: float = 0.05, alpha: float = 0.05, gamma: float = 0.15, window: int = 25, normalize_scores: bool = True, clip_output: bool = True, _fitted: bool = False, _s_min: float = 0.0, _s_max: float = 1.0, _x_unique: ndarray | None = None, _x_unique_scaled: ndarray | None = None, _z_fit: ndarray | None = None, _L: ndarray | None = None, _R: ndarray | None = None, _w_block: ndarray | None = None)¶
- adjacency_bounds_()[source]¶
Return the learned local bounds L_i per adjacency (shape: m-1) or None if not fitted.
- fit(scores: ndarray, y: ndarray, sample_weight: ndarray | None = None)[source]¶
Fit CDI-ISO on (scores, y).
- Parameters:
scores – Raw model scores; will be sorted internally. If normalize_scores=True, an affine min-max transform to [0,1] is learned and applied in transform.
y – Binary labels {0,1}.
sample_weight – Nonnegative per-sample weights.
- Returns:
CDIIsotonicCalibrator– Returns self for method chaining.- Raises:
ValueError – If scores and y have different lengths, y contains invalid values, or sample_weight has invalid values.
- fit_transform(X, y=None, **fit_params)¶
Fit to data, then transform it.
Fits transformer to X and y with optional parameters fit_params and returns a transformed version of X.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Input samples.
y (array-like of shape (n_samples,) or (n_samples, n_outputs), default=None) – Target values (None for unsupervised transformations).
**fit_params (dict) – Additional fit parameters.
- Returns:
X_new (ndarray array of shape (n_samples, n_features_new)) – Transformed array.
- get_metadata_routing()¶
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing (MetadataRequest) – A
MetadataRequestencapsulating routing information.
- get_params(deep=True)¶
Get parameters for this estimator.
- Parameters:
deep (bool, default=True) – If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
params (dict) – Parameter names mapped to their values.
- set_fit_request(*, sample_weight: bool | None | str = '$UNCHANGED$', scores: bool | None | str = '$UNCHANGED$') CDIIsotonicCalibrator¶
Configure whether metadata should be requested to be passed to the
fitmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed tofitif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it tofit.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
sample_weight (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
sample_weightparameter infit.scores (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
scoresparameter infit.
- Returns:
self (object) – The updated object.
- set_output(*, transform=None)¶
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({“default”, “pandas”, “polars”}, default=None) – Configure output of transform and fit_transform.
“default”: Default output format of a transformer
“pandas”: DataFrame output
“polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self (estimator instance) – Estimator instance.
- set_params(**params)¶
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
**params (dict) – Estimator parameters.
- Returns:
self (estimator instance) – Estimator instance.
- set_transform_request(*, scores: bool | None | str = '$UNCHANGED$') CDIIsotonicCalibrator¶
Configure whether metadata should be requested to be passed to the
transformmethod.Note that this method is only relevant when this estimator is used as a sub-estimator within a meta-estimator and metadata routing is enabled with
enable_metadata_routing=True(seesklearn.set_config()). Please check the User Guide on how the routing mechanism works.The options for each parameter are:
True: metadata is requested, and passed totransformif provided. The request is ignored if metadata is not provided.False: metadata is not requested and the meta-estimator will not pass it totransform.None: metadata is not requested, and the meta-estimator will raise an error if the user provides it.str: metadata should be passed to the meta-estimator with this given alias instead of the original name.
The default (
sklearn.utils.metadata_routing.UNCHANGED) retains the existing request. This allows you to change the request for some parameters and not others.Added in version 1.3.
- Parameters:
scores (str, True, False, or None, default=sklearn.utils.metadata_routing.UNCHANGED) – Metadata routing for
scoresparameter intransform.- Returns:
self (object) – The updated object.
- transform(scores: ndarray)[source]¶
Map new scores to calibrated probabilities (stepwise-constant).
- Parameters:
scores – Input scores to calibrate.
- Returns:
ndarray– Calibrated probabilities in [0,1] (if clip_output=True).- Raises:
RuntimeError – If called before fit().
Note
CDI-ISO is a research-grade calibrator that uses economic decision theory and statistical evidence to make informed monotonicity decisions. It requires specification of operating thresholds where discrimination matters most.
Isotonic Calibrator¶
- class calibre.IsotonicCalibrator(y_min: float | None = None, y_max: float | None = None, increasing: bool = True, out_of_bounds: str = 'clip', enable_diagnostics: bool = False)[source]¶
Bases:
BaseCalibratorIsotonic regression calibrator.
This calibrator wraps sklearn’s IsotonicRegression for probability calibration.
- Parameters:
y_min – Lower bound for the calibrated values.
y_max – Upper bound for the calibrated values.
increasing – Whether the calibration function should be increasing.
out_of_bounds – How to handle out-of-bounds values in transform. Options: ‘nan’, ‘clip’, ‘raise’.
enable_diagnostics – Whether to enable plateau diagnostics analysis.
Examples
>>> import numpy as np >>> from calibre import IsotonicCalibrator >>> >>> X = np.array([0.1, 0.2, 0.3, 0.4, 0.5]) >>> y = np.array([0, 0, 1, 1, 1]) >>> >>> # Basic usage >>> cal = IsotonicCalibrator() >>> cal.fit(X, y) >>> X_calibrated = cal.transform(X) >>> >>> # With diagnostics >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> if cal.has_diagnostics(): ... print(cal.diagnostic_summary())
Notes
Isotonic regression finds the best monotonic fit to the data, which is particularly useful for calibration because well-calibrated predictions should maintain the rank order of predictions while improving probability estimates.
See also
NearlyIsotonicCalibratorRelaxed monotonicity constraint
SmoothedIsotonicCalibratorIsotonic with smoothing
- __init__(y_min: float | None = None, y_max: float | None = None, increasing: bool = True, out_of_bounds: str = 'clip', enable_diagnostics: bool = False)[source]¶
- diagnostic_summary()¶
Get a human-readable summary of diagnostic analysis.
- Returns:
summary (str) – Human-readable plateau summary.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> print(cal.diagnostic_summary())
- fit(X: ndarray, y: ndarray)¶
Fit the calibrator.
This method implements the template method pattern: it handles data storage and diagnostics, while delegating the actual fitting logic to the abstract _fit_impl() method that subclasses must implement.
- Parameters:
X – The values to be calibrated (e.g., predicted probabilities).
y – The target values (e.g., true labels).
- Returns:
BaseCalibrator – Returns self for method chaining.
- fit_transform(X: ndarray, y: ndarray)¶
Fit the calibrator and then transform the data.
This is a convenience method that combines fit() and transform() in a single call. The default implementation simply calls fit() followed by transform().
- Parameters:
X – The values to be calibrated.
y – The target values.
- Returns:
ndarray– Calibrated values.
Examples
>>> import numpy as np >>> from calibre import IsotonicCalibrator >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> cal = IsotonicCalibrator() >>> X_calibrated = cal.fit_transform(X, y)
- get_diagnostics()¶
Get diagnostic results.
- Returns:
dict | None – Diagnostic results from plateau analysis, or None if diagnostics were not computed or are not available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> diagnostics = cal.get_diagnostics() >>> if diagnostics: ... print(f"Found {diagnostics['n_plateaus']} plateaus")
- get_metadata_routing()¶
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing (MetadataRequest) – A
MetadataRequestencapsulating routing information.
- get_params(deep=True)¶
Get parameters for this estimator.
- Parameters:
deep (bool, default=True) – If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
params (dict) – Parameter names mapped to their values.
- has_diagnostics()¶
Check if diagnostic information is available.
- Returns:
has_diag (bool) – True if diagnostics have been computed and are available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> if cal.has_diagnostics(): ... print("Diagnostics available!")
- set_output(*, transform=None)¶
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({“default”, “pandas”, “polars”}, default=None) – Configure output of transform and fit_transform.
“default”: Default output format of a transformer
“pandas”: DataFrame output
“polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self (estimator instance) – Estimator instance.
- set_params(**params)¶
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
**params (dict) – Estimator parameters.
- Returns:
self (estimator instance) – Estimator instance.
- transform(X: ndarray)[source]¶
Apply isotonic calibration to new data.
- Parameters:
X – The values to be calibrated.
- Returns:
ndarray– Calibrated values.- Raises:
ValueError – If called before fit().
Nearly Isotonic Calibrator¶
- class calibre.NearlyIsotonicCalibrator(lam: float = 1.0, method: str = 'cvx', enable_diagnostics: bool = False)[source]¶
Bases:
BaseCalibratorNearly-isotonic regression for flexible monotonic calibration.
This calibrator implements nearly-isotonic regression, which relaxes the strict monotonicity constraint of standard isotonic regression by penalizing rather than prohibiting violations. This allows for a more flexible fit while still maintaining a generally monotonic trend.
- Parameters:
lam – Regularization parameter controlling the strength of monotonicity constraint. Higher values enforce stricter monotonicity.
method – Method to use for solving the optimization problem: - ‘cvx’: Uses convex optimization with CVXPY - ‘path’: Uses a path algorithm similar to the original nearly-isotonic paper
enable_diagnostics – Whether to enable plateau diagnostics analysis.
Notes
Nearly-isotonic regression solves the following optimization problem:
\[\min_{\beta} \sum_{i=1}^{n} (y_i - \beta_i)^2 + \lambda \sum_{i=1}^{n-1} \max(0, \beta_i - \beta_{i+1})\]where \(\beta\) is the calibrated output, \(y\) are the true labels, and \(\lambda > 0\) controls the strength of the monotonicity penalty.
This formulation penalizes violations of monotonicity proportionally to their magnitude, allowing small violations when they significantly improve the fit.
Examples
>>> import numpy as np >>> from calibre import NearlyIsotonicCalibrator >>> >>> X = np.array([0.1, 0.2, 0.3, 0.4, 0.5]) >>> y = np.array([0.12, 0.18, 0.35, 0.25, 0.55]) >>> >>> cal = NearlyIsotonicCalibrator(lam=0.5) >>> cal.fit(X, y) >>> X_calibrated = cal.transform(np.array([0.15, 0.35, 0.55]))
See also
IsotonicCalibratorStrict monotonicity constraint
RegularizedIsotonicCalibratorL2 regularization with strict monotonicity
- diagnostic_summary()¶
Get a human-readable summary of diagnostic analysis.
- Returns:
summary (str) – Human-readable plateau summary.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> print(cal.diagnostic_summary())
- fit(X: ndarray, y: ndarray)¶
Fit the calibrator.
This method implements the template method pattern: it handles data storage and diagnostics, while delegating the actual fitting logic to the abstract _fit_impl() method that subclasses must implement.
- Parameters:
X – The values to be calibrated (e.g., predicted probabilities).
y – The target values (e.g., true labels).
- Returns:
BaseCalibrator – Returns self for method chaining.
- fit_transform(X: ndarray, y: ndarray)¶
Fit the calibrator and then transform the data.
This is a convenience method that combines fit() and transform() in a single call. The default implementation simply calls fit() followed by transform().
- Parameters:
X – The values to be calibrated.
y – The target values.
- Returns:
ndarray– Calibrated values.
Examples
>>> import numpy as np >>> from calibre import IsotonicCalibrator >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> cal = IsotonicCalibrator() >>> X_calibrated = cal.fit_transform(X, y)
- get_diagnostics()¶
Get diagnostic results.
- Returns:
dict | None – Diagnostic results from plateau analysis, or None if diagnostics were not computed or are not available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> diagnostics = cal.get_diagnostics() >>> if diagnostics: ... print(f"Found {diagnostics['n_plateaus']} plateaus")
- get_metadata_routing()¶
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing (MetadataRequest) – A
MetadataRequestencapsulating routing information.
- get_params(deep=True)¶
Get parameters for this estimator.
- Parameters:
deep (bool, default=True) – If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
params (dict) – Parameter names mapped to their values.
- has_diagnostics()¶
Check if diagnostic information is available.
- Returns:
has_diag (bool) – True if diagnostics have been computed and are available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> if cal.has_diagnostics(): ... print("Diagnostics available!")
- set_output(*, transform=None)¶
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({“default”, “pandas”, “polars”}, default=None) – Configure output of transform and fit_transform.
“default”: Default output format of a transformer
“pandas”: DataFrame output
“polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self (estimator instance) – Estimator instance.
- set_params(**params)¶
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
**params (dict) – Estimator parameters.
- Returns:
self (estimator instance) – Estimator instance.
- transform(X: ndarray)[source]¶
Apply nearly-isotonic calibration to new data.
- Parameters:
X – The values to be calibrated.
- Returns:
X_calibrated (array-like of shape (n_samples,)) – Calibrated values.
- Raises:
ValueError – If method is not ‘cvx’ or ‘path’.
Spline Calibrator¶
- class calibre.SplineCalibrator(n_splines: int = 10, degree: int = 3, cv: int = 5, enable_diagnostics: bool = False)[source]¶
Bases:
BaseCalibratorI-Spline calibration with cross-validation.
This calibrator uses monotonic I-splines with non-negative coefficients to ensure monotonicity while providing a smooth calibration function. Cross-validation is used to find the best model.
- Parameters:
n_splines – Number of spline basis functions.
degree – Polynomial degree of spline basis functions.
cv – Number of cross-validation folds.
enable_diagnostics – Whether to enable plateau diagnostics analysis.
Examples
>>> import numpy as np >>> from calibre import SplineCalibrator >>> >>> X = np.array([0.1, 0.2, 0.3, 0.4, 0.5]) >>> y = np.array([0.12, 0.18, 0.35, 0.25, 0.55]) >>> >>> cal = SplineCalibrator(n_splines=5) >>> cal.fit(X, y) >>> X_calibrated = cal.transform(np.array([0.15, 0.35, 0.55]))
Notes
I-splines are integrated versions of M-splines (monotone splines) that are guaranteed to be monotonically increasing when coefficients are non-negative. This calibrator fits a Ridge regression with positive=True constraint to ensure monotonicity.
See also
IsotonicCalibratorNon-parametric monotonic calibration
SmoothedIsotonicCalibratorIsotonic with local smoothing
- __init__(n_splines: int = 10, degree: int = 3, cv: int = 5, enable_diagnostics: bool = False)[source]¶
- diagnostic_summary()¶
Get a human-readable summary of diagnostic analysis.
- Returns:
summary (str) – Human-readable plateau summary.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> print(cal.diagnostic_summary())
- fit(X: ndarray, y: ndarray)¶
Fit the calibrator.
This method implements the template method pattern: it handles data storage and diagnostics, while delegating the actual fitting logic to the abstract _fit_impl() method that subclasses must implement.
- Parameters:
X – The values to be calibrated (e.g., predicted probabilities).
y – The target values (e.g., true labels).
- Returns:
BaseCalibrator – Returns self for method chaining.
- fit_transform(X: ndarray, y: ndarray)¶
Fit the calibrator and then transform the data.
This is a convenience method that combines fit() and transform() in a single call. The default implementation simply calls fit() followed by transform().
- Parameters:
X – The values to be calibrated.
y – The target values.
- Returns:
ndarray– Calibrated values.
Examples
>>> import numpy as np >>> from calibre import IsotonicCalibrator >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> cal = IsotonicCalibrator() >>> X_calibrated = cal.fit_transform(X, y)
- get_diagnostics()¶
Get diagnostic results.
- Returns:
dict | None – Diagnostic results from plateau analysis, or None if diagnostics were not computed or are not available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> diagnostics = cal.get_diagnostics() >>> if diagnostics: ... print(f"Found {diagnostics['n_plateaus']} plateaus")
- get_metadata_routing()¶
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing (MetadataRequest) – A
MetadataRequestencapsulating routing information.
- get_params(deep=True)¶
Get parameters for this estimator.
- Parameters:
deep (bool, default=True) – If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
params (dict) – Parameter names mapped to their values.
- has_diagnostics()¶
Check if diagnostic information is available.
- Returns:
has_diag (bool) – True if diagnostics have been computed and are available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> if cal.has_diagnostics(): ... print("Diagnostics available!")
- set_output(*, transform=None)¶
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({“default”, “pandas”, “polars”}, default=None) – Configure output of transform and fit_transform.
“default”: Default output format of a transformer
“pandas”: DataFrame output
“polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self (estimator instance) – Estimator instance.
- set_params(**params)¶
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
**params (dict) – Estimator parameters.
- Returns:
self (estimator instance) – Estimator instance.
- transform(X: ndarray)[source]¶
Apply I-Spline calibration to new data.
- Parameters:
X – The values to be calibrated.
- Returns:
X_calibrated (array-like of shape (n_samples,)) – Calibrated values.
- Raises:
ValueError – If model has not been fitted before transform.
Relaxed PAVA Calibrator¶
- class calibre.RelaxedPAVACalibrator(percentile: float = 10, adaptive: bool = True, enable_diagnostics: bool = False)[source]¶
Bases:
BaseCalibratorRelaxed Pool Adjacent Violators Algorithm (PAVA) for calibration.
This calibrator implements a relaxed version of PAVA that allows small monotonicity violations up to a threshold determined by the percentile of differences between adjacent sorted points.
- Parameters:
percentile – Percentile of absolute differences to use as threshold. Lower values enforce stricter monotonicity.
adaptive – Whether to use the adaptive implementation (recommended) or the block-merging implementation.
enable_diagnostics – Whether to enable plateau diagnostics analysis.
Examples
>>> import numpy as np >>> from calibre import RelaxedPAVACalibrator >>> >>> X = np.array([0.1, 0.2, 0.3, 0.4, 0.5]) >>> y = np.array([0.12, 0.18, 0.35, 0.25, 0.55]) >>> >>> cal = RelaxedPAVACalibrator(percentile=20) >>> cal.fit(X, y) >>> X_calibrated = cal.transform(np.array([0.15, 0.35, 0.55]))
See also
IsotonicCalibratorStrict monotonicity constraint
NearlyIsotonicCalibratorPenalized monotonicity violations
- diagnostic_summary()¶
Get a human-readable summary of diagnostic analysis.
- Returns:
summary (str) – Human-readable plateau summary.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> print(cal.diagnostic_summary())
- fit(X: ndarray, y: ndarray)¶
Fit the calibrator.
This method implements the template method pattern: it handles data storage and diagnostics, while delegating the actual fitting logic to the abstract _fit_impl() method that subclasses must implement.
- Parameters:
X – The values to be calibrated (e.g., predicted probabilities).
y – The target values (e.g., true labels).
- Returns:
BaseCalibrator – Returns self for method chaining.
- fit_transform(X: ndarray, y: ndarray)¶
Fit the calibrator and then transform the data.
This is a convenience method that combines fit() and transform() in a single call. The default implementation simply calls fit() followed by transform().
- Parameters:
X – The values to be calibrated.
y – The target values.
- Returns:
ndarray– Calibrated values.
Examples
>>> import numpy as np >>> from calibre import IsotonicCalibrator >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> cal = IsotonicCalibrator() >>> X_calibrated = cal.fit_transform(X, y)
- get_diagnostics()¶
Get diagnostic results.
- Returns:
dict | None – Diagnostic results from plateau analysis, or None if diagnostics were not computed or are not available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> diagnostics = cal.get_diagnostics() >>> if diagnostics: ... print(f"Found {diagnostics['n_plateaus']} plateaus")
- get_metadata_routing()¶
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing (MetadataRequest) – A
MetadataRequestencapsulating routing information.
- get_params(deep=True)¶
Get parameters for this estimator.
- Parameters:
deep (bool, default=True) – If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
params (dict) – Parameter names mapped to their values.
- has_diagnostics()¶
Check if diagnostic information is available.
- Returns:
has_diag (bool) – True if diagnostics have been computed and are available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> if cal.has_diagnostics(): ... print("Diagnostics available!")
- set_output(*, transform=None)¶
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({“default”, “pandas”, “polars”}, default=None) – Configure output of transform and fit_transform.
“default”: Default output format of a transformer
“pandas”: DataFrame output
“polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self (estimator instance) – Estimator instance.
- set_params(**params)¶
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
**params (dict) – Estimator parameters.
- Returns:
self (estimator instance) – Estimator instance.
Regularized Isotonic Calibrator¶
- class calibre.RegularizedIsotonicCalibrator(alpha: float = 0.1, enable_diagnostics: bool = False)[source]¶
Bases:
BaseCalibratorRegularized isotonic regression with L2 regularization.
This calibrator adds L2 regularization to standard isotonic regression to prevent overfitting and produce smoother calibration curves.
The optimization problem solved is:
\[\min_{\beta} \sum_{i=1}^{n} (y_i - \beta_i)^2 + \alpha \sum_{i=1}^{n} \beta_i^2\]subject to \(\beta_i \leq \beta_{i+1}\) for all \(i\).
- Parameters:
alpha – Regularization strength. Higher values result in smoother curves.
enable_diagnostics – Whether to enable plateau diagnostics analysis.
Examples
>>> import numpy as np >>> from calibre import RegularizedIsotonicCalibrator >>> >>> X = np.array([0.1, 0.2, 0.3, 0.4, 0.5]) >>> y = np.array([0.12, 0.18, 0.35, 0.25, 0.55]) >>> >>> cal = RegularizedIsotonicCalibrator(alpha=0.2) >>> cal.fit(X, y) >>> X_calibrated = cal.transform(np.array([0.15, 0.35, 0.55]))
See also
IsotonicCalibratorNo regularization
NearlyIsotonicCalibratorPenalizes monotonicity violations
- diagnostic_summary()¶
Get a human-readable summary of diagnostic analysis.
- Returns:
summary (str) – Human-readable plateau summary.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> print(cal.diagnostic_summary())
- fit(X: ndarray, y: ndarray)¶
Fit the calibrator.
This method implements the template method pattern: it handles data storage and diagnostics, while delegating the actual fitting logic to the abstract _fit_impl() method that subclasses must implement.
- Parameters:
X – The values to be calibrated (e.g., predicted probabilities).
y – The target values (e.g., true labels).
- Returns:
BaseCalibrator – Returns self for method chaining.
- fit_transform(X: ndarray, y: ndarray)¶
Fit the calibrator and then transform the data.
This is a convenience method that combines fit() and transform() in a single call. The default implementation simply calls fit() followed by transform().
- Parameters:
X – The values to be calibrated.
y – The target values.
- Returns:
ndarray– Calibrated values.
Examples
>>> import numpy as np >>> from calibre import IsotonicCalibrator >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> cal = IsotonicCalibrator() >>> X_calibrated = cal.fit_transform(X, y)
- get_diagnostics()¶
Get diagnostic results.
- Returns:
dict | None – Diagnostic results from plateau analysis, or None if diagnostics were not computed or are not available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> diagnostics = cal.get_diagnostics() >>> if diagnostics: ... print(f"Found {diagnostics['n_plateaus']} plateaus")
- get_metadata_routing()¶
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing (MetadataRequest) – A
MetadataRequestencapsulating routing information.
- get_params(deep=True)¶
Get parameters for this estimator.
- Parameters:
deep (bool, default=True) – If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
params (dict) – Parameter names mapped to their values.
- has_diagnostics()¶
Check if diagnostic information is available.
- Returns:
has_diag (bool) – True if diagnostics have been computed and are available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> if cal.has_diagnostics(): ... print("Diagnostics available!")
- set_output(*, transform=None)¶
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({“default”, “pandas”, “polars”}, default=None) – Configure output of transform and fit_transform.
“default”: Default output format of a transformer
“pandas”: DataFrame output
“polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self (estimator instance) – Estimator instance.
- set_params(**params)¶
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
**params (dict) – Estimator parameters.
- Returns:
self (estimator instance) – Estimator instance.
Smoothed Isotonic Calibrator¶
- class calibre.SmoothedIsotonicCalibrator(window_length: int | None = None, poly_order: int = 3, interp_method: str = 'linear', adaptive: bool = False, min_window: int = 5, max_window: int | None = None, enable_diagnostics: bool = False)[source]¶
Bases:
BaseCalibrator,MonotonicMixinLocally smoothed isotonic regression.
This calibrator applies standard isotonic regression and then smooths the result using a Savitzky-Golay filter, which preserves the monotonicity properties while reducing jaggedness.
- Parameters:
window_length – Window length for Savitzky-Golay filter. Should be odd. If None, window_length is set to max(5, len(X)//10)
poly_order – Polynomial order for the Savitzky-Golay filter. Must be less than window_length.
interp_method – Interpolation method to use (‘linear’, ‘cubic’, etc.)
adaptive – Whether to use adaptive window sizes based on local density.
min_window – Minimum window length when using adaptive=True.
max_window – Maximum window length when using adaptive=True. If None, max_window is set to len(X)//5.
enable_diagnostics – Whether to enable plateau diagnostics analysis.
Examples
>>> import numpy as np >>> from calibre import SmoothedIsotonicCalibrator >>> >>> X = np.array([0.1, 0.2, 0.3, 0.4, 0.5]) >>> y = np.array([0.12, 0.18, 0.35, 0.25, 0.55]) >>> >>> cal = SmoothedIsotonicCalibrator(window_length=7) >>> cal.fit(X, y) >>> X_calibrated = cal.transform(X)
See also
IsotonicCalibratorIsotonic regression without smoothing
RegularizedIsotonicCalibratorL2 regularization instead of smoothing
- __init__(window_length: int | None = None, poly_order: int = 3, interp_method: str = 'linear', adaptive: bool = False, min_window: int = 5, max_window: int | None = None, enable_diagnostics: bool = False)[source]¶
- static check_monotonicity(y: ndarray, strict: bool = False)¶
Check if an array is monotonically increasing.
- Parameters:
y – Values to check for monotonicity.
strict – If True, check for strictly increasing (no equal consecutive values). If False, check for non-decreasing (allows equal consecutive values).
- Returns:
bool– True if the array is monotonic according to the specified criteria.
Examples
>>> import numpy as np >>> from calibre.base import MonotonicMixin >>> >>> y1 = np.array([0.1, 0.2, 0.3, 0.4]) >>> MonotonicMixin.check_monotonicity(y1) True >>> >>> y2 = np.array([0.1, 0.3, 0.2, 0.4]) >>> MonotonicMixin.check_monotonicity(y2) False >>> >>> y3 = np.array([0.1, 0.2, 0.2, 0.3]) >>> MonotonicMixin.check_monotonicity(y3, strict=False) True >>> MonotonicMixin.check_monotonicity(y3, strict=True) False
- diagnostic_summary()¶
Get a human-readable summary of diagnostic analysis.
- Returns:
summary (str) – Human-readable plateau summary.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> print(cal.diagnostic_summary())
- static enforce_monotonicity(y: ndarray, inplace: bool = False)¶
Enforce monotonicity on an array.
This method ensures the array is non-decreasing by replacing any value that is less than the previous value with the previous value.
- Parameters:
y – Values to make monotonic.
inplace – If True, modify the array in place. Otherwise, return a copy.
- Returns:
ndarray– Monotonically increasing version of the input array.
Examples
>>> import numpy as np >>> from calibre.base import MonotonicMixin >>> >>> y = np.array([0.1, 0.3, 0.2, 0.5, 0.4]) >>> y_mono = MonotonicMixin.enforce_monotonicity(y) >>> print(y_mono) [0.1 0.3 0.3 0.5 0.5] >>> >>> # Original array unchanged >>> print(y) [0.1 0.3 0.2 0.5 0.4]
- fit(X: ndarray, y: ndarray)¶
Fit the calibrator.
This method implements the template method pattern: it handles data storage and diagnostics, while delegating the actual fitting logic to the abstract _fit_impl() method that subclasses must implement.
- Parameters:
X – The values to be calibrated (e.g., predicted probabilities).
y – The target values (e.g., true labels).
- Returns:
BaseCalibrator – Returns self for method chaining.
- fit_transform(X: ndarray, y: ndarray)¶
Fit the calibrator and then transform the data.
This is a convenience method that combines fit() and transform() in a single call. The default implementation simply calls fit() followed by transform().
- Parameters:
X – The values to be calibrated.
y – The target values.
- Returns:
ndarray– Calibrated values.
Examples
>>> import numpy as np >>> from calibre import IsotonicCalibrator >>> X = np.array([0.1, 0.3, 0.5, 0.7, 0.9]) >>> y = np.array([0, 0, 1, 1, 1]) >>> cal = IsotonicCalibrator() >>> X_calibrated = cal.fit_transform(X, y)
- get_diagnostics()¶
Get diagnostic results.
- Returns:
dict | None – Diagnostic results from plateau analysis, or None if diagnostics were not computed or are not available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> diagnostics = cal.get_diagnostics() >>> if diagnostics: ... print(f"Found {diagnostics['n_plateaus']} plateaus")
- get_metadata_routing()¶
Get metadata routing of this object.
Please check User Guide on how the routing mechanism works.
- Returns:
routing (MetadataRequest) – A
MetadataRequestencapsulating routing information.
- get_params(deep=True)¶
Get parameters for this estimator.
- Parameters:
deep (bool, default=True) – If True, will return the parameters for this estimator and contained subobjects that are estimators.
- Returns:
params (dict) – Parameter names mapped to their values.
- has_diagnostics()¶
Check if diagnostic information is available.
- Returns:
has_diag (bool) – True if diagnostics have been computed and are available.
Examples
>>> from calibre import IsotonicCalibrator >>> import numpy as np >>> >>> X = np.array([0.1, 0.3, 0.5]) >>> y = np.array([0, 1, 1]) >>> >>> cal = IsotonicCalibrator(enable_diagnostics=True) >>> cal.fit(X, y) >>> if cal.has_diagnostics(): ... print("Diagnostics available!")
- set_output(*, transform=None)¶
Set output container.
See Introducing the set_output API for an example on how to use the API.
- Parameters:
transform ({“default”, “pandas”, “polars”}, default=None) – Configure output of transform and fit_transform.
“default”: Default output format of a transformer
“pandas”: DataFrame output
“polars”: Polars output
None: Transform configuration is unchanged
Added in version 1.4: “polars” option was added.
- Returns:
self (estimator instance) – Estimator instance.
- set_params(**params)¶
Set the parameters of this estimator.
The method works on simple estimators as well as on nested objects (such as
Pipeline). The latter have parameters of the form<component>__<parameter>so that it’s possible to update each component of a nested object.- Parameters:
**params (dict) – Estimator parameters.
- Returns:
self (estimator instance) – Estimator instance.
Usage Examples¶
Basic Example¶
from calibre import IsotonicCalibrator
import numpy as np
# Generate example data
np.random.seed(42)
X = np.random.uniform(0, 1, 1000)
y = np.random.binomial(1, X, 1000)
# Fit calibrator
calibrator = IsotonicCalibrator()
calibrator.fit(X, y)
# Transform predictions
X_new = np.random.uniform(0, 1, 100)
y_calibrated = calibrator.transform(X_new)
Comparing Methods¶
from calibre import (
CDIIsotonicCalibrator,
IsotonicCalibrator,
NearlyIsotonicCalibrator,
SplineCalibrator,
RelaxedPAVACalibrator,
RegularizedIsotonicCalibrator
)
# Initialize different calibrators
calibrators = {
'CDI-ISO': CDIIsotonicCalibrator(thresholds=[0.3, 0.7], gamma=0.15),
'Isotonic': IsotonicCalibrator(),
'Nearly Isotonic': NearlyIsotonicCalibrator(lam=1.0),
'Spline': SplineCalibrator(n_splines=10),
'Relaxed PAVA': RelaxedPAVACalibrator(percentile=10),
'Regularized': RegularizedIsotonicCalibrator(alpha=0.1)
}
# Fit and compare
results = {}
for name, cal in calibrators.items():
cal.fit(X, y)
y_cal = cal.transform(X_new)
results[name] = y_cal
print(f"Calibrated {len(X_new)} predictions using {len(calibrators)} methods")
CDI-ISO Usage Example¶
from calibre import CDIIsotonicCalibrator
import numpy as np
# Generate example data
np.random.seed(42)
X = np.random.uniform(0, 1, 1000)
y = np.random.binomial(1, X, 1000)
# CDI-ISO with economic thresholds (e.g., decision points at 0.3 and 0.7)
cdi_cal = CDIIsotonicCalibrator(
thresholds=[0.3, 0.7], # Operating decision thresholds
threshold_weights=[0.6, 0.4], # Relative importance
bandwidth=0.1, # Kernel bandwidth around thresholds
gamma=0.2, # Minimum slope strength
alpha=0.05, # Statistical significance level
window=30 # Evidence window size
)
# Fit the calibrator
cdi_cal.fit(X, y)
# Get calibrated predictions
X_test = np.random.uniform(0, 1, 100)
y_calibrated = cdi_cal.transform(X_test)
# Access diagnostic information
bounds = cdi_cal.adjacency_bounds_()
breakpoints = cdi_cal.breakpoints_()
print(f"CDI calibrator learned {len(bounds)} local bounds")
print(f"Calibration function has {len(breakpoints[0])} breakpoints")