Integrated (time-averaged) Brier score for a cause-specific cumulative incidence.
integrated_brier_score_incidence(
surv,
incidence_prob,
times,
*,
data=None,
cause,
)
Summarizes cause-specific Brier scores computed at multiple time horizons into a single metric via trapezoidal integration. This provides an overall calibration measure for a competing-risks model’s predictions for a specific cause.
Use this to: Reduce multiple cause-specific Brier scores (one per time point) to a single number for model comparison. Especially useful when comparing Fine-Gray models for the same cause with different covariate sets.
Interpretation: Same scale as brier_score_incidence() (0 = perfect, 1 = worst).
Parameters
surv: Surv | Outcome | str
-
A multi-state Surv response (from gw.Surv() with a categorical event). An Outcome or a formula response such as 'Surv(time, status == 2)' is also accepted, with its columns read from data.
incidence_prob: Any
-
Predicted cumulative incidence probabilities for the cause of interest, shape (n_subjects, n_times).
times: Any
-
Evaluation times (at least 2). The integrated Brier score is computed as the area under the Brier-score curve from times[0] to times[-1], normalized by the time span.
cause: int
-
The cause of interest (integer event code from the Surv response).
data: Any = None
-
A data frame (pandas, Polars, PyArrow, DuckDB, a lazy frame, …) holding the columns named by the response and
incidence_prob. When surv is an Outcome or a formula, rows with a missing value in any column used are dropped first, along with the matching rows of any arrays passed alongside.
Returns
float
-
Integrated Brier score (time-averaged). Lower is better.
Examples
Summarize CIF calibration for progression (cause 1) into a single score using the mgus2 dataset:
import greenwood as gw
import numpy as np
# The first of progression (PCM) or death, each with its own time and status columns
mgus2 = gw.load_dataset("mgus2", backend="polars")
first = gw.Outcome.first_event(
endpoints={"pcm": ("ptime", "pstat"), "death": ("futime", "death")}
)
# Marginal CIF from Aalen-Johansen as a naive baseline
aj = gw.AalenJohansen().fit(first, data=mgus2)
cif_df = aj.to_frame(format="polars")
pcm_cif = cif_df.filter(cif_df["cause"] == "pcm")
# Evaluate over a fine time grid
times = np.linspace(30, 360, 12)
marginal = np.array(
[float(np.interp(t, pcm_cif["time"].to_numpy(), pcm_cif["estimate"].to_numpy()))
for t in times]
)
probs = np.tile(marginal, (mgus2.height, 1))
ibs = gw.integrated_brier_score_incidence(
first, incidence_prob=probs, times=times, cause=1, data=mgus2
)
ibs