Evaluation metrics for survival models (hand-rolled, NumPy only).
Functions
concordance_index(risk, time, event)
Harrell's concordance index (C-index).
The C-index is the probability that, for a randomly chosen comparable pair, the subject with the shorter observed event time is assigned the higher risk. A pair is comparable when the ordering of its event times is known despite censoring: the earlier time must be an observed event.
Parameters
risk
array-like of shape (n_samples,)
Predicted risk scores (higher = earlier expected event).
time
array-like of shape (n_samples,)
Observed times (event or censoring).
event
array-like of shape (n_samples,)
Event indicators (1 = event observed, 0 = right-censored).
Returns
c_index
float
Concordance index in
[0, 1]. Returns nan when no pair is comparable.
Notes
Ties in time are comparable only when both are events, in which case a tied risk counts as \tfrac{1}{2} and a difference counts as \tfrac{1}{2} (the standard Harrell convention).
python
>>> import numpy as np
>>> from tuiml.algorithms.survival.metrics import concordance_index
>>> time = np.array([1., 2., 3., 4.])
>>> event = np.ones(4)
>>> concordance_index([4, 3, 2, 1], time, event)
1.0
>>> concordance_index([1, 2, 3, 4], time, event)
0.0
integrated_brier_score(risk_or_model, X, time, event, times)
Integrated Brier score with inverse-probability-of-censoring weights.
The Brier score at time t measures the squared error between the predicted survival \hat{S}_i(t) and the observed survival status 1\{t_i > t\}, reweighted to correct for censoring (Graf et al., 1999):
BS(t) = \frac{1}{n} \sum_{i=1}^{n} \hat{w}_i(t) \left( \hat{S}_i(t) - 1\{t_i > t\} \right)^2
where the inverse-probability-of-censoring weight is \hat{w}_i(t) = 1\{t_i \leq t, \delta_i = 1\} / \hat{G}(t_i) + 1\{t_i > t\} / \hat{G}(t). The integrated Brier score is the mean of BS(t) over the requested times.
Parameters
risk_or_model
array-like or object
Either a fitted survival model exposing
predict_survival_function(X, times) (returning an (n_samples, n_times) array), or a 1-D array of risk scores, which are converted to survival curves via a Breslow baseline.
X
np.ndarray of shape (n_samples, n_features)
Covariates. Used only when
risk_or_model is a model.
time
array-like of shape (n_samples,)
Observed times (event or censoring).
event
array-like of shape (n_samples,)
Event indicators (1 = event observed, 0 = right-censored).
times
array-like of shape (n_times,)
Time grid over which to integrate the Brier score.
Returns
ibs
float
Integrated Brier score (lower is better).
python
>>> import numpy as np
>>> from tuiml.algorithms.survival.metrics import integrated_brier_score
>>> rng = np.random.RandomState(0)
>>> time = rng.uniform(1, 10, size=30)
>>> event = np.ones(30)
>>> risk = -time # perfectly anti-correlated risk: high risk at short time
>>> ibs = integrated_brier_score(risk, np.ones((30, 1)), time, event, [2., 5., 8.])
>>> 0.0 <= ibs <= 0.5
True
logrank_test(time_a, event_a, time_b, event_b)
Two-sample log-rank test for equality of survival curves.
Compares the observed number of events in group A against the number expected under the null hypothesis that both groups share the same hazard. The test statistic is asymptotically chi-square with one degree of freedom.
Parameters
time_a
array-like of shape (n_a,)
Observed times for group A.
event_a
array-like of shape (n_a,)
Event indicators for group A.
time_b
array-like of shape (n_b,)
Observed times for group B.
event_b
array-like of shape (n_b,)
Event indicators for group B.
Returns
statistic
float
The chi-square log-rank statistic.
p_value
float
Two-sided p-value from the chi-square distribution with 1 degree of freedom.
python
>>> from tuiml.algorithms.survival.metrics import logrank_test
>>> stat, p = logrank_test([1, 2, 3, 4], [1, 1, 1, 1],
... [5, 6, 7, 8], [1, 1, 1, 1])
>>> stat > 0 and p < 0.05
True