Я пытаюсь смоделировать время выживания, используя модель пропорциональной опасности Кокса, я хотел бы использовать структуру повышения градиента (xgboost или lightgbm). Я знаю, что в xgboost реализована реализация потерь по coxph, однако моя функция потерь немного изменена, времена выживания сгруппированы по разным экспериментальным группам, и я действительно заинтересован в ранжировании среди групп и вероятностях перестановок. Каждая из групп может иметь разные размеры, и могут быть правильные данные, подвергнутые цензуре.
Например, предположим, что у нас есть переменные, время = [10,3,1,6,4,1,7,30,21,15,25,24], группы = [0,0,0,1 , 1,1,1,1,2,2,2,2], наблюдается = [1,0,1,1,1,0,1,0,0,1,1,1], где время Время выживания, группы - это идентификатор группы, такой, что время жизни может быть сгруппировано в соответствии с ним, и наблюдаемым является статус цензуры (1 - данные наблюдений, 0 - данные, подвергнутые цензуре).
Я реализовал модель с нейронной сетью с помощью Tensorflow, но сейчас я хотел бы попробовать ее в xgboost, я не уверен, что в моем случае значения grad и hess, возвращаемые моей функцией loss (см. Документ: https://github.com/dmlc/xgboost/blob/master/demo/guide-python/custom_objective.py).
вот код, который я реализовал в Tensorflow для версии нейронной сети:
def compute_cox_loss(time, predict, observed, groups):
'''predict is the score output by the model,
other param are the same as in the problem description
'''
#ensure the data have the correct shape
time = tf.reshape(time, (-1,))
predict = tf.reshape(predict, (-1,))
observed = tf.reshape(observed, (-1,))
#split the data into groups
splitted_time = tf.split(time, groups, axis=0)
splitted_predict = tf.split(predict, groups, axis=0)
splitted_observed = tf.split(observed, groups, axis=0)
#target is the total loss
target = 0
count = 1
batch_size = len(splitted_time)
#for each group, calculate the CoxPH loss and add it into target
for i in range(batch_size):
sorted_time = tf.sort(splitted_time[i], direction='ASCENDING')
sort_arg = tf.argsort(splitted_time[i], direction='ASCENDING')
sorted_predict = tf.exp( tf.gather(splitted_predict[i], sort_arg) )
sorted_observed = tf.gather(splitted_observed[i], sort_arg)
mask = tf.cast( sorted_observed, tf.bool )
L = tf.boolean_mask( tf.log(sorted_predict) - tf.log( tf.cumsum(sorted_predict, reverse=True) ), mask )
loss = -tf.reduce_mean(L)
target += loss
count += 1
return target/count
Кроме того, я не могу найти код, реализующий потерю coxph в xgboost в официальном github. Кто-нибудь может указать, где находится код, чтобы я мог изменить его в соответствии с моей проблемой?