infer.calibration¶
Probability calibration hooks for post-model adjustment, including
per-user calibration via CalibratorStore.
Overview¶
After the model produces raw class probabilities, the calibration layer optionally adjusts them before the reject decision is made:
Calibration improves the reliability of predicted probabilities without
changing the underlying model. Three calibrator implementations are
provided, all satisfying the Calibrator protocol:
| Class | Description |
|---|---|
IdentityCalibrator |
No-op pass-through (default when no calibrator is configured) |
TemperatureCalibrator |
Single-parameter temperature scaling: T > 1 softens, T < 1 sharpens |
IsotonicCalibrator |
Per-class isotonic regression via sklearn.isotonic.IsotonicRegression |
All calibrators must preserve input shape and ensure the output sums
to 1.0 along the class axis.
The concrete calibrator classes and CalibratorStore are implemented
as dataclasses; constructor signatures are unchanged.
Calibrator protocol¶
Any object with a calibrate(core_probs: np.ndarray) -> np.ndarray
method satisfies the protocol. The method accepts arrays of shape
(n_classes,) (single row) or (n_rows, n_classes) (batch).
CalibratorStore¶
CalibratorStore manages per-user calibration with a global fallback.
It holds a global calibrator (fitted on all users' validation data) and
optional per-user calibrators for users that meet the personalization
eligibility thresholds (see train calibrate).
At inference time, get_calibrator(user_id) returns the per-user
calibrator if one exists, otherwise the global calibrator.
calibrate_batch(core_probs, user_ids) applies the correct calibrator
row-by-row.
Directory layout¶
When persisted via save_calibrator_store, the store is written as:
<store_dir>/
store.json # metadata (see below)
global.json # global calibrator (any type)
users/
<user_id>.json # per-user calibrator (one file per user)
store.json fields¶
| Field | Type | Description |
|---|---|---|
method |
str |
"temperature" or "isotonic" |
user_count |
int |
Number of per-user calibrators |
user_ids |
list[str] |
Sorted list of user IDs with per-user calibrators |
model_bundle_id |
str \| null |
Run directory name of the model this store was fitted against |
model_schema_hash |
str \| null |
Schema hash of the model bundle (for cross-validation with inference policy) |
created_at |
str \| null |
ISO-8601 timestamp of store creation |
The model_bundle_id, model_schema_hash, and created_at fields
were added to enable model-bound calibration. Stores created before
this change will have null for these fields; they still load and
function normally.
Serialization¶
Single calibrator¶
from pathlib import Path
from taskclf.infer.calibration import (
TemperatureCalibrator, save_calibrator, load_calibrator,
)
cal = TemperatureCalibrator(temperature=1.35)
save_calibrator(cal, Path("artifacts/calibrator.json"))
loaded = load_calibrator(Path("artifacts/calibrator.json"))
Calibrator store¶
from pathlib import Path
from taskclf.infer.calibration import (
CalibratorStore, TemperatureCalibrator,
save_calibrator_store, load_calibrator_store,
)
store = CalibratorStore(
global_calibrator=TemperatureCalibrator(1.2),
user_calibrators={"alice": TemperatureCalibrator(1.05)},
method="temperature",
)
save_calibrator_store(store, Path("artifacts/calibrators"))
loaded_store = load_calibrator_store(Path("artifacts/calibrators"))
print(loaded_store.user_ids) # ['alice']
Eligibility¶
Per-user calibration is only fitted when the user meets the eligibility
thresholds defined in core.defaults (minimum labeled windows, days,
and distinct labels). See the
train calibrate CLI command and
personalization guide for details.
taskclf.infer.calibration
¶
Probability calibration hooks for post-model adjustment.
Provides a Calibrator protocol and concrete implementations:
- :class:
IdentityCalibrator— no-op pass-through (default). - :class:
TemperatureCalibrator— single-parameter temperature scaling. - :class:
IsotonicCalibrator— per-class isotonic regression.
Per-user calibration is managed through :class:CalibratorStore, which
maps user_id to a fitted calibrator and falls back to a global
calibrator for users without enough labeled data.
Calibrator
¶
Bases: Protocol
Minimal contract for a probability calibrator.
Implementations must:
- Preserve the shape of core_probs.
- Ensure the output sums to 1.0 along the class axis.
- Be deterministic (same input → same output).
Source code in src/taskclf/infer/calibration.py
calibrate(core_probs)
¶
Adjust a probability vector (or matrix) and return calibrated probabilities.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core_probs
|
ndarray
|
Array of shape |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Calibrated probabilities with the same shape. |
Source code in src/taskclf/infer/calibration.py
IdentityCalibrator
dataclass
¶
No-op calibrator that returns probabilities unchanged.
Source code in src/taskclf/infer/calibration.py
TemperatureCalibrator
dataclass
¶
Scale logits by a learned temperature before softmax.
A temperature > 1 softens the distribution (less confident); a temperature < 1 sharpens it (more confident).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
temperature
|
float
|
Positive scalar. Defaults to 1.0 (identity). |
1.0
|
Source code in src/taskclf/infer/calibration.py
IsotonicCalibrator
dataclass
¶
Per-class isotonic regression calibrator.
Wraps one sklearn.isotonic.IsotonicRegression per class. Each
regressor maps the model's raw probability for that class to a
calibrated value. After per-class transformation the vector is
renormalized to sum to 1.0.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
regressors
|
list
|
List of fitted |
required |
Source code in src/taskclf/infer/calibration.py
CalibratorStore
dataclass
¶
Per-user calibrator registry with global fallback.
Holds a global calibrator (fitted on all users' validation data) and optional per-user calibrators for users that meet the personalization eligibility thresholds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
global_calibrator
|
Calibrator
|
Calibrator applied to users without a dedicated calibrator. |
required |
user_calibrators
|
dict[str, Calibrator]
|
Mapping from |
dict()
|
method
|
str
|
Calibration method label ( |
'temperature'
|
model_bundle_id
|
str | None
|
Run directory name of the model bundle this
store was fitted against. |
None
|
model_schema_hash
|
str | None
|
Schema hash of the model bundle. Used by
:func: |
None
|
created_at
|
str | None
|
ISO-8601 timestamp of when the store was created. |
None
|
Source code in src/taskclf/infer/calibration.py
user_ids
property
¶
Return sorted list of user IDs with per-user calibrators.
get_calibrator(user_id)
¶
Return the per-user calibrator if available, else the global one.
calibrate_batch(core_probs, user_ids)
¶
Apply per-user calibration row by row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
core_probs
|
ndarray
|
Probability matrix |
required |
user_ids
|
Sequence[str]
|
Sequence of user_id strings aligned with rows. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Calibrated probability matrix of the same shape. |
Source code in src/taskclf/infer/calibration.py
save_calibrator(calibrator, path)
¶
Persist a calibrator to JSON.
Supports :class:IdentityCalibrator, :class:TemperatureCalibrator,
and :class:IsotonicCalibrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
calibrator
|
Calibrator
|
Calibrator instance to serialize. |
required |
path
|
Path
|
Destination file path. |
required |
Returns:
| Type | Description |
|---|---|
Path
|
The path that was written. |
Source code in src/taskclf/infer/calibration.py
load_calibrator(path)
¶
Load a calibrator from a JSON file written by :func:save_calibrator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Path to a calibrator JSON file. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
A |
Calibrator
|
class: |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the file contains an unknown calibrator type. |
Source code in src/taskclf/infer/calibration.py
save_calibrator_store(store, path)
¶
Persist a :class:CalibratorStore to a directory.
Layout::
path/
store.json # metadata + global calibrator
users/
<user_id>.json # per-user calibrator
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store
|
CalibratorStore
|
Store to serialize. |
required |
path
|
Path
|
Target directory (created if needed). |
required |
Returns:
| Type | Description |
|---|---|
Path
|
The directory path. |
Source code in src/taskclf/infer/calibration.py
load_calibrator_store(path)
¶
Load a :class:CalibratorStore from a directory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Path
|
Directory previously written by :func: |
required |
Returns:
| Type | Description |
|---|---|
CalibratorStore
|
A populated |