@@ -136,6 +136,16 @@ def brier_score_incidence(self, y_true, y_pred, times):
136
136
else :
137
137
event_true = event_true > 0
138
138
139
+ if y_pred .ndim != 2 :
140
+ raise ValueError (
141
+ "'y_pred' must be a 2D array with shape (n_samples, n_times), got"
142
+ f" shape { y_pred .shape } ."
143
+ )
144
+ if y_pred .shape [0 ] != event_true .shape [0 ]:
145
+ raise ValueError (
146
+ "'y_true' and 'y_pred' must have the same number of samples, "
147
+ f"got { event_true .shape [0 ]} and { y_pred .shape [0 ]} respectively."
148
+ )
139
149
if y_pred .shape [1 ] != times .shape [0 ]:
140
150
raise ValueError (
141
151
f"'times' length ({ times .shape [0 ]} ) "
@@ -193,44 +203,37 @@ def _weighted_binary_targets(self, y_event, y_duration, times, ipcw_y_duration):
193
203
else :
194
204
k = self .event_of_interest
195
205
196
- # Specify the binary classification target for each record in y and
197
- # a reference time horizon:
206
+ # Specify the binary classification target for each record in y and a
207
+ # reference time horizon:
198
208
#
199
209
# - 1 when event of interest was observed before the reference time
200
210
# horizon,
201
211
#
202
- # - 0 otherwise: any other event happening at any time, censored record
203
- # or event of interest happening after the reference time horizon.
212
+ # - 0 otherwise: any competing event happening at any time, censored
213
+ # record or event of interest happening after the reference time
214
+ # horizon.
204
215
#
205
216
# Note: censored events only contribute (as negative target) when
206
217
# their duration is larger than the reference target horizon.
207
218
# Otherwise, they are discarded by setting their weight to 0 in the
208
219
# following.
209
-
210
- y_binary = np .zeros (y_event .shape [0 ], dtype = np .int32 )
211
- y_binary [(y_event == k ) & (y_duration <= times )] = 1
212
-
213
- # Compute the weights for each term contributing to the Brier score
214
- # at the specified time horizons.
215
- #
216
- # - error of a prediction for a time horizon before the occurence of an
217
- # event (either censored or uncensored) is weighted by the inverse
218
- # probability of censoring at that time horizon.
219
220
#
220
- # - error of a prediction for a time horizon after the any observed event
221
- # is weighted by inverse censoring probability at the actual time
222
- # of the observed event .
221
+ # Contrary to censored records, competing events always contribute as
222
+ # negative targets. There weight is always non-zero but differ if
223
+ # they happen either before or after the reference time horizon .
223
224
#
224
- # - "error" of a prediction for a time horizon after a censored event has
225
- # 0 weight and do not contribute to the Brier score computation.
225
+ # This IPCW scheme for survival analysis (binary events) is described
226
+ # in [Graf1999] and is extended to multiple competing events in
227
+ # [Kretowska2018].
228
+ event_k_before_horizon = (y_event == k ) & (y_duration <= times )
229
+ y_binary = event_k_before_horizon .astype (np .int32 )
226
230
227
- # Estimate the probability of censoring at current time point t.
228
231
ipcw_times = self .ipcw_est .compute_ipcw_at (times )
229
- before = times < y_duration
230
- weights = np .where (before , ipcw_times , 0 )
232
+ any_event_or_censoring_after_horizon = y_duration > times
233
+ weights = np .where (any_event_or_censoring_after_horizon , ipcw_times , 0 )
231
234
232
- after_any_observed_event = (y_event > 0 ) & (y_duration <= times )
233
- weights = np .where (after_any_observed_event , ipcw_y_duration , weights )
235
+ any_observed_event_before_horizon = (y_event > 0 ) & (y_duration <= times )
236
+ weights = np .where (any_observed_event_before_horizon , ipcw_y_duration , weights )
234
237
235
238
return y_binary , weights
236
239
@@ -257,6 +260,11 @@ def brier_score_survival(
257
260
:math:`t`, estimated on the training set by the Kaplan-Meier estimator on the
258
261
negation of the binary any-event indicator.
259
262
263
+ Note that this assumes independence between censoring and the covariates.
264
+ When this assumption is violated, the IPCW weights are biased and the Brier
265
+ score is not a proper scoring rule anymore. See [Gerds2006]_ for a study of this
266
+ bias.
267
+
260
268
Parameters
261
269
----------
262
270
y_train : record-array, dictionnary or dataframe of shape (n_samples, 2)
@@ -287,6 +295,16 @@ def brier_score_survival(
287
295
Returns
288
296
-------
289
297
brier_score : np.ndarray of shape (n_times)
298
+
299
+ References
300
+ ----------
301
+ .. [Graf1999] E. Graf, C. Schmoor, W. Sauerbrei, M. Schumacher, "Assessment
302
+ and comparison of prognostic classification schemes for survival data",
303
+ 1999
304
+
305
+ .. [Gerds2006] T. Gerds and M. Schumacher, "Consistent Estimation of the
306
+ Expected Brier Score in General Survival Models with Right-Censored
307
+ Event Times", 2006
290
308
"""
291
309
computer = IncidenceScoreComputer (
292
310
y_train ,
@@ -308,6 +326,11 @@ def integrated_brier_score_survival(
308
326
\mathrm{IBS} = \frac{1}{t_{max} - t_{min}} \int^{t_{max}}_{t_{min}}
309
327
\mathrm{BS}(u) du
310
328
329
+ Note that this assumes independence between censoring and the covariates.
330
+ When this assumption is violated, the IPCW weights are biased and the Brier
331
+ score is not a proper scoring rule anymore. See [Gerds2006]_ for a study of
332
+ this bias.
333
+
311
334
Parameters
312
335
----------
313
336
y_train : record-array, dictionnary or dataframe of shape (n_samples, 2)
@@ -338,6 +361,16 @@ def integrated_brier_score_survival(
338
361
Returns
339
362
-------
340
363
ibs : float
364
+
365
+ References
366
+ ----------
367
+ .. [Graf1999] E. Graf, C. Schmoor, W. Sauerbrei, M. Schumacher, "Assessment
368
+ and comparison of prognostic classification schemes for survival data",
369
+ 1999
370
+
371
+ .. [Gerds2006] T. Gerds and M. Schumacher, "Consistent Estimation of the
372
+ Expected Brier Score in General Survival Models with Right-Censored
373
+ Event Times", 2006
341
374
"""
342
375
computer = IncidenceScoreComputer (
343
376
y_train ,
@@ -360,32 +393,45 @@ def brier_score_incidence(
360
393
\mathrm{BS}_k(t) = \frac{1}{n} \sum_{i=1}^n \hat{\omega}_i(t)
361
394
(\mathbb{I}(t_i \leq t, \delta_i = k) - \hat{F}_k(t|\mathbf{x}_i))^2
362
395
363
- where :math:`\hat{F}_k(t | \mathbf{x}_i)` is the estimate of the cumulative
364
- incidence for the kth event up to time point :math:`t` for a feature vector
365
- :math:`\mathbf{x}_i`, and
396
+ where :math:`\hat{F}_k(t | \mathbf{x}_i)` is an estimate of the
397
+ (uncensored) cumulative incidence for the kth event up to time point
398
+ :math:`t` for a feature vector :math:` \mathbf{x}_i` [Edwards2016]_:
366
399
367
400
.. math::
368
401
369
- \hat{\omega}_i(t)=\mathbb{I}(t_i \leq t, \delta_i \neq 0)/\hat{G}(t_i)
370
- + \mathbb{I}(t_i > t)/\hat{G}(t )
402
+ \hat{F}_k(t | \mathbf{x}_i) \approx P(T_i \leq t, E_i = k |
403
+ \mathbf{x}_i )
371
404
372
- are IPCW weigths based on the Kaplan-Meier estimate of the censoring
373
- distribution :math:`\hat{G}(t)`.
405
+ and :math:`\hat{\omega}_i(t)` are IPCW weigths based on the Kaplan-Meier
406
+ estimate of the censoring distribution :math:`\hat{G}(t)`:
407
+
408
+ .. math::
409
+
410
+ \hat{\omega}_i(t)=\frac{\mathbb{I}(t_i \leq t, \delta_i \neq
411
+ 0)}{\hat{G}(t_i)} + \frac{\mathbb{I}(t_i > t)}{\hat{G}(t)}
412
+
413
+ This scheme was introduced in [Graf1999]_ in the context of survival
414
+ analysis and extended to competing events in [Kretowska2018]_.
415
+
416
+ Note that this assumes independence between censoring and the covariates.
417
+ When this assumption is violated, the IPCW weights are biased and the Brier
418
+ score is not a proper scoring rule anymore. See [Gerds2006]_ for a study of
419
+ this bias.
374
420
375
421
Parameters
376
422
----------
377
423
y_train : record-array, dictionnary or dataframe of shape (n_samples, 2)
378
- The target, consisting in the 'event' and 'duration' columns.
379
- This is used to fit the IPCW estimator.
424
+ The target, consisting in the 'event' and 'duration' columns. This is
425
+ used to fit the IPCW estimator.
380
426
381
427
y_test : record-array, dictionnary or dataframe of shape (n_samples, 2)
382
- The ground truth, consisting in the 'event' and 'duration' columns.
383
- In the "event" column, `0` indicates censoring, and any other values
428
+ The ground truth, consisting in the 'event' and 'duration' columns. In
429
+ the "event" column, `0` indicates censoring, and any other values
384
430
indicate competing event types.
385
431
386
432
y_pred : array-like of shape (n_samples, n_times)
387
- Incidence probability estimates predicted at ``times``.
388
- In the binary event settings, this is 1 - survival_probability.
433
+ Incidence probability estimates predicted at ``times``. In the binary
434
+ event settings, this is 1 - survival_probability.
389
435
390
436
times : array-like of shape (n_times)
391
437
Times at which the survival probability ``y_pred`` has been estimated
@@ -411,9 +457,20 @@ def brier_score_incidence(
411
457
412
458
References
413
459
----------
460
+ .. [Graf1999] E. Graf, C. Schmoor, W. Sauerbrei, M. Schumacher, "Assessment
461
+ and comparison of prognostic classification schemes for survival data",
462
+ 1999
463
+
464
+ .. [Kretowska2018] M. Kretowska, "Tree-based models for survival data with
465
+ competing risks", 2018
414
466
415
- [1] M. Kretowska, "Tree-based models for survival data with competing risks",
416
- Computer Methods and Programs in Biomedicine 159 (2018) 185-198.
467
+ .. [Gerds2006] T. Gerds and M. Schumacher, "Consistent Estimation of the
468
+ Expected Brier Score in General Survival Models with Right-Censored
469
+ Event Times", 2006
470
+
471
+ .. [Edwards2016] J. Edwards, L. Hester, M. Gokhale, C. Lesko,
472
+ "Methodologic Issues When Estimating Risks in Pharmacoepidemiology.",
473
+ 2016, doi:10.1007/s40471-016-0089-1
417
474
"""
418
475
# XXX: make times an optional kwarg to be compatible with
419
476
# sksurv.metrics.brier_score?
@@ -442,6 +499,14 @@ def integrated_brier_score_incidence(
442
499
\mathrm{IBS}_k = \frac{1}{t_{max} - t_{min}} \int^{t_{max}}_{t_{min}}
443
500
\mathrm{BS}_k(u) du
444
501
502
+ This scheme was introduced in [Graf1999]_ for survival analysis and
503
+ extended to competing events in [Kretowska2018]_.
504
+
505
+ Note that this assumes independence between censoring and the covariates.
506
+ When this assumption is violated, the IPCW weights are biased and the Brier
507
+ score is not a proper scoring rule anymore. See [Gerds2006]_ for a study of
508
+ this bias.
509
+
445
510
Parameters
446
511
----------
447
512
y_train : record-array, dictionnary or dataframe of shape (n_samples, 2)
@@ -480,9 +545,16 @@ def integrated_brier_score_incidence(
480
545
481
546
References
482
547
----------
548
+ .. [Graf1999] E. Graf, C. Schmoor, W. Sauerbrei, M. Schumacher, "Assessment
549
+ and comparison of prognostic classification schemes for survival data",
550
+ 1999
551
+
552
+ .. [Kretowska2018] M. Kretowska, "Tree-based models for survival data with
553
+ competing risks", 2018
483
554
484
- [1] M. Kretowska, "Tree-based models for survival data with competing risks",
485
- Computer Methods and Programs in Biomedicine 159 (2018) 185-198.
555
+ .. [Gerds2006] T. Gerds and M. Schumacher, "Consistent Estimation of the
556
+ Expected Brier Score in General Survival Models with Right-Censored
557
+ Event Times", 2006
486
558
"""
487
559
computer = IncidenceScoreComputer (
488
560
y_train ,
0 commit comments