A bug in predict of AFT

The predict method doesn’t look like correct to me with the AFT model since I got all the same predictions after trying on multiple data sets. I wish there was a document on predict method for AFT.

 > ## example 1
 > # 4-by-2 Data matrix
 > X <- matrix(c(1., -1., -1., 1., 0., 1., 1., 0.),
 +             nrow=4, ncol=2, byrow=TRUE)
 > dtrain <- xgb.DMatrix(X)
 >
 > # Associate ranged labels with the data matrix.
 > # This example shows each kind of censored labels.
 > #                   uncensored  right  left  interval
 > y_lower_bound <- c(        2.,    3.,   0.,       4.)
 > y_upper_bound <- c(        2.,  +Inf,   4.,       5.)
 > setinfo(dtrain, 'label_lower_bound', y_lower_bound)
 [1] TRUE
 > setinfo(dtrain, 'label_upper_bound', y_upper_bound)
 [1] TRUE
 > params <- list(objective='survival:aft',
 +                eval_metric='aft-nloglik',
 +                aft_loss_distribution='normal',
 +                aft_loss_distribution_scale=1.20,
 +                tree_method='hist',
+                learning_rate=0.05,
 +                max_depth=2)
 > watchlist <- list(train = dtrain)
 > bst <- xgb.train(params, dtrain, nrounds=5, watchlist)
 [1] train-aft-nloglik:2.301421
 [2] train-aft-nloglik:2.241837
 [3] train-aft-nloglik:2.186329
 [4] train-aft-nloglik:2.134619
 [5] train-aft-nloglik:2.086451
 > predict(bst, dtrain)
 [1] 0.6762048 0.6762048 0.6762048 0.6762048

**> # example 2 with no censoring**
 > ### 4-by-2 Data matrix
 > X <- matrix(c(1., -1., -1., 1., 0., 1., 1., 0.),
 +             nrow=4, ncol=2, byrow=TRUE)
 > y_lower_bound <- X[,1]
 > y_upper_bound <- X[,1]
 > dtrain <- xgb.DMatrix(data=X, label_lower_bound=y_lower_bound, label_upper_bound=y_upper_bound)
 > params <- list(objective='survival:aft',
 +                eval_metric='aft-nloglik',
 +                aft_loss_distribution='normal',
 +                aft_loss_distribution_scale=1.20,
 +                tree_method='hist',
 +                learning_rate=0.05,
 +                max_depth=2)
 > watchlist <- list(train = dtrain)
 > bst <- xgb.train(params, dtrain, nrounds=5, watchlist)
[1] train-aft-nloglik:27.631021
 [2] train-aft-nloglik:27.631021
 [3] train-aft-nloglik:27.631021
 [4] train-aft-nloglik:27.631021
 [5] train-aft-nloglik:27.631021
 > predict(bst, dtrain)
 [1] NaN NaN NaN NaN

**> ##example 3 like example 3, but with large n**
 > X <- matrix(rnorm(200), nrow=100)
 > y_lower_bound <- X[,1]
 > y_upper_bound <- X[,1]
 > dtrain <- xgb.DMatrix(data=X, label_lower_bound=y_lower_bound, label_upper_bound=y_upper_bound)
 > bst <- xgb.train(params, dtrain, nrounds=5, watchlist)
 [1] train-aft-nloglik:27.631021
 [2] train-aft-nloglik:27.631021
 [3] train-aft-nloglik:27.631021
 [4] train-aft-nloglik:27.631021
 [5] train-aft-nloglik:27.631021
 **> predict(bst, dtrain)**
**   [1] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN**
**  [19] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN**
**  [37] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN**
**  [55] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN**
**  [73] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN**
**  [91] NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN**

You should try to adjust the hyperparameters aft_loss_distribution and aft_loss_distribution_scale, since train-aft-nloglik is too high.

I suggest you look at https://github.com/dmlc/xgboost/blob/master/demo/aft_survival/aft_survival_viz_demo.py, where AFT is able to fit the toy data

X = np.array([1, 2, 3, 4, 5]).reshape((-1, 1))
INF = np.inf
y_lower = np.array([ 10,  15, -INF, 30, 100])
y_upper = np.array([INF, INF,   20, 50, INF])
dmat = xgb.DMatrix(X)
dmat.set_float_info('label_lower_bound', y_lower)
dmat.set_float_info('label_upper_bound', y_upper)

Thanks. The example and the link helped. But I still think there is a bug in the code when the predict method returns NA for a toy data model. Hopefully that doesn’t matter.