Запись времени выживания Xgboost cox

Как в новой реализации модели выживания cox ph в xgboost 0.81 указать время начала и окончания события?

Спасибо

Эквивалентная функция R будет, например, такой:

cph_mod = coxph(Surv(Start, Stop, Status) ~ Age + Sex + SBP, data=data)

person aiedu    schedule 30.11.2018    source источник


Ответы (1)


XGBoost не допускает запуска (т.е. отложенного входа). Если это имеет смысл для приложения, вы всегда можете изменить базовую шкалу времени, чтобы все предметы начинались с time = 0. Однако XGBoost допускает правильную цензуру данных. Кажется невозможным найти какую-либо документацию / пример того, как реализовать модель Кокса, но в исходном коде вы можете прочитать " Регрессия Кокса для цензурированных данных о выживаемости (отрицательные метки считаются цензурированными) ".

Вот краткий пример для тех, кто хочет попробовать XGBoost с obj = "survival: cox". Мы можем сравнить результаты с пакетом выживания scikit-learn sksurv. Чтобы сделать XGBoost более похожим на этот фреймворк, мы используем линейный бустер вместо древовидного бустера.

import pandas as pd
import xgboost as xgb
from sksurv.datasets import load_aids
from sksurv.linear_model import CoxPHSurvivalAnalysis

# load and inspect the data
data_x, data_y = load_aids()
data_y[10:15]
Out[586]: 
array([(False, 334.), (False, 285.), (False, 265.), ( True, 206.),
   (False, 305.)], dtype=[('censor', '?'), ('time', '<f8')])

# Since XGBoost only allow one column for y, the censoring information
# is coded as negative values:
data_y_xgb = [x[1] if x[0] else -x[1] for x in data_y]
data_y_xgb[10:15]
Out[3]: [-334.0, -285.0, -265.0, 206.0, -305.0]

data_x = data_x[['age', 'cd4']]
data_x.head()
Out[4]: 
    age    cd4
0  34.0  169.0
1  34.0  149.5
2  20.0   23.5
3  48.0   46.0
4  46.0   10.0

# Since sksurv output log hazard ratios (here relative to 0 on predictors)
# we must use 'output_margin=True' for comparability.
estimator = CoxPHSurvivalAnalysis().fit(data_x, data_y)
gbm = xgb.XGBRegressor(objective='survival:cox',
                       booster='gblinear',
                       base_score=1,
                       n_estimators=1000).fit(data_x, data_y_xgb)
prediction_sksurv = estimator.predict(data_x)
predictions_xgb = gbm.predict(data_x, output_margin=True)
d = pd.DataFrame({'xgb': predictions_xgb,
                  'sksurv': prediction_sksurv})
d.head()
Out[13]: 
     sksurv       xgb
0 -1.892490 -1.843828
1 -1.569389 -1.524385
2  0.144572  0.207866
3  0.519293  0.502953
4  1.062392  1.045287

d.plot.scatter('xgb', 'sksurv')

введите описание изображения здесь

Обратите внимание, что это прогнозы на основе тех же данных, которые использовались для соответствия модели. Кажется, что XGBoost получает значения правильно, но иногда с линейным преобразованием. Я не знаю, почему. Поиграйте с base_score и n_estimators. Возможно, кто-нибудь сможет дополнить этот ответ.

person PeterStrom    schedule 06.01.2019
comment
Спасибо за ответ. В качестве альтернативы я мог бы использовать группировку в Dmatrix, но я не думаю, что пока это обрабатывается для cox ph. - person aiedu; 07.01.2019