I’m trying to implement the Tweedie regression objective function in R (so that I can test some changes later). The c++ implementation is shown here. Specifically:
bst_float grad = -y * expf((1 - rho) * p) + expf((2 - rho) * p); bst_float hess = -y * (1 - rho) * \ std::exp((1 - rho) * p) + (2 - rho) * expf((2 - rho) * p); _out_gpair[_idx] = GradientPair(grad * w, hess * w);
My attempt:
tw_obj <- function(preds, dtrain, rho = 1.5){
labels <- getinfo(dtrain, “label”)
w <- getinfo(dtrain, “weight”)
#labels = log(labels + .00000000001)
#preds = log(preds + .00000000001)
grad <- -labels * exp((1 - rho) * preds) + exp((2 - rho) * preds)
hess <- -labels * (1 - rho) * exp((1 - rho) * preds) + (2 - rho) * exp((2 - rho) * preds)return(list(grad = grad * w, hess = hess * w))
}
Using this function without the log transformations results in inf values and training fails. Using the function with the log transformation results in the likelihood never improving (calculated with eval_metric = “tweedie-nloglik@1.5”).
Is there a different transformation used in the c++ code that I’m not seeing? Or does the expf function handle the large values on its own? How I can fix this in R?