Curve API Compatibility

rtichoke exposes parallel function families for discrimination, calibration, and decision-curve analysis. Most of them share the same input conventions; the main differences are in time-dependent heuristic handling, especially calibration.

This page focuses on the conventions that are shared across curve families and on the few places where users should expect different behavior.

Multiple named populations

The curve families accept named probability arrays, so populations such as Train and Test can be evaluated together. When outcomes are also supplied as a dictionary, matching dictionary keys are paired population-by-population. Each probability vector must match the outcome vector for its own population, but different populations may have different sample sizes.

import numpy as np
import rtichoke as rk

probs = {
    "Train": np.array([0.10, 0.90, 0.20, 0.80, 0.30, 0.70]),
    "Test": np.array([0.15, 0.85, 0.25, 0.75]),
}
reals = {
    "Train": np.array([0, 1, 0, 1, 0, 1]),
    "Test": np.array([0, 1, 0, 0]),
}

fig = rk.create_calibration_curve(probs=probs, reals=reals)

Here Train has six observations and Test has four. That is supported. What matters is the within-population alignment:

len(probs["Train"]) == len(reals["Train"])
len(probs["Test"])  == len(reals["Test"])

The same named-population pattern is used by ROC, precision-recall, Gains, Lift, decision, and calibration curve families. For time-dependent calls, times follows the same population alignment when supplied as a dictionary.

Censoring and competing-event heuristics

Time-dependent functions distinguish censoring from competing events. The heuristic for an outcome type matters only when observations of that type are present:

  • If there are no competing events, changing competing_heuristic does not change the statistical estimates because there are no competing events for that rule to act on.
  • If there are no censored observations, changing censoring_heuristic does not change the statistical estimates because there are no censored observations for that rule to act on.
  • If neither censoring nor competing events are present, the heuristic choices do not alter the estimates.

These statements describe the effect of the heuristics on the estimates. Function-specific input validation still applies: a function can reject an unsupported heuristic combination even when the corresponding outcome type is absent.

Time-dependent calibration heuristics

create_calibration_curve_times() differs from its ROC, precision-recall, Gains, Lift, and decision-curve siblings in two important ways:

  1. heuristics_sets is currently required rather than defaulted.
  2. Calibration explicitly rejects unsupported heuristic combinations, including censoring_heuristic="adjusted" and competing_heuristic="adjusted_as_censored", with an Unsupported calibration heuristics error instead of silently skipping every requested horizon.

Pass the calibration heuristic explicitly. For the currently working exclusion-based path:

heuristics_sets = [
    {
        "censoring_heuristic": "excluded",
        "competing_heuristic": "adjusted_as_negative",
    }
]

Then call:

fig = rk.create_calibration_curve_times(
    probs=probs,
    reals=reals,
    times=times,
    fixed_time_horizons=[3.0, 6.0, 9.0],
    heuristics_sets=heuristics_sets,
)

Numeric time horizons

fixed_time_horizons accepts integer or floating-point numeric values. Integer horizons are normalized to floats at the shared time-dependent processing boundary, so [3, 6, 9] and [3.0, 6.0, 9.0] are equivalent.