我正在尝试找出 LightGBM 中的自定义目标函数,并且我认为一个好的起点是复制内置函数。LightGBM用来计算Tweedie指标的方程(https://github.com/microsoft/LightGBM/blob/1c27a15e42f0076492fcc966b9dbcf9da6042823/src/metric/regression_metric.hpp#L300-L318)似乎与我发现的Tweedie损失的定义相匹配在线(https://towardsdatascience.com/tweedie-loss-function-for-right-skewed-data-2c5ca470678f),虽然他们做了一个奇怪的 exp(ln(score)) 过程,但我猜测是为了数值稳定性。然而,他们的梯度和 Hessian 方程似乎是直接在分数对数上完成的(https://github.com/microsoft/LightGBM/blob/1c27a15e42f0076492fcc966b9dbcf9da6042823/src/objective/regression_objective.hpp#L702-L732)。
看起来他们正在使用这个方程:
gradients[i] = -label_[i] * e^((1 - rho_) * score[i]) + e^((2 - rho_) * score[i]);
Run Code Online (Sandbox Code Playgroud)
我期望梯度是:
gradients[i] = -label_[i] * score[i]^(- rho_) + score[i]^(1 - rho_);
Run Code Online (Sandbox Code Playgroud)
我的猜测是 LightGBM 将分数处理为 ln(score),就像使用参数 reg_sqrt 一样,但我找不到文档中对此进行描述的位置。
无论如何,我尝试将他们的公式和我自己的计算重新创建为自定义目标函数,但似乎都不起作用:
library(lightgbm)
library(data.table)
# Tweedie gradient with variance = 1.5, according to my own math
CustomObj_t1 <- function(preds, dtrain) {
labels <- dtrain$getinfo('label')
grad <- -labels * preds^(-3/2) + preds^(-1/2)
hess <- 1/2 * …Run Code Online (Sandbox Code Playgroud) 有没有办法在data.table中组合连接和子集功能?说我有下表:
dt = data.table(itemID = c(1,1,2,2),bucketID = c(1,2,2,3),value = 1:4)
Run Code Online (Sandbox Code Playgroud)
我想为每个项目的最低桶设置值为零.我的想法是:
ends = dt[,.(min = min(bucketID)),itemID]
dt[ends,on="itemID",bucketID==min,value:=0]
Run Code Online (Sandbox Code Playgroud)
即连接表,找到两行相同的位置,然后更新值列.但这不起作用.我可以得到正确的结果:
ends = dt[,.(min = min(bucketID)),itemID]
dt = dt[ends,on="itemID"][bucketID==min,value:=0][,c(-4)]
Run Code Online (Sandbox Code Playgroud)
然而,这看起来有点迂回.有没有更好的方法来结合连接和哪里?