настроенная функция пропорциональной потери риска Кокса в xgboost или lightgbm - PullRequest
0 голосов
/ 24 мая 2019

Я пытаюсь смоделировать время выживания, используя модель пропорциональной опасности Кокса, я хотел бы использовать структуру повышения градиента (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. Кто-нибудь может указать, где находится код, чтобы я мог изменить его в соответствии с моей проблемой?

...