src/objective/rank_obj.cu
xgboost官方文档中说明objective:rank 中的方法都是通过LambdaMart来实现的
数据结构:LambdaPair:包括pos_index(正索引) neg_index(负索引) 以及该lambdapair的权值(初始化为1)
ListEntry:包含pred预测值、label标签值、rindex原样本的索引
定义的类:
这段代码的主体为类模版:LambdaRankObj 根据LambdaWeightComputerT模版参数取PairWiseComputer MAPLambdaWeightComputer NDCGLambdaWeightComputer三种值来实例化不同的模版类,主要的区别在于delta的计算。
对父类中GetGradient方法进行了重载,由于rank回设置group所以要对当前group是否合理进行判断。(即大小是不是0以及pred和label的group大小是否一致)
方法:ComputeGradients()
形参: preds_h(预测值) labels(标签值) gpair(一阶与二阶梯度构成的pair)gptr(分组信息)
内部容器:pairs 用来存储LambdaPair lst用来存储ListEntry rec存储预测值与在原group内的索引值
按group对已有的数据进行操作
先初始化当前group中的lst(pred,label,rindex) 以及 梯度对(初始化为0)
Lambda的计算(对应xgboost中的g和h)
先按预测值进行排序,再将label与原有的预测值排序后的index进行对应并存入rec中,再将rec按照label大小进行排序
从i开始到rec的结尾产生随机数与当前下标匹配凑成pair(该过程由参数num_pairsample控制,当pairsample数量等于rec长度时就全部取样,小于时就取部分),当下标值小于当前index时pair pos_index = 随机数的index neg_index = i的index若随机数大于等于当前遍历的值则位置相反且 neg_index = 随机数index+1(防止产生相同的index)
计算lambda的值,对每一个pair计算lambda并将其汇总加到某个index的lambda中,于此同时计算每一个pair的二阶梯度最后将得到的两项与group占的权重以及delta值相乘得到该sample的g与h xgboost可以通过每个sample对应的一二阶导数计算各点的增益从而对分裂点进行寻找
PairWiseLambdaComputer
weight为初始值1,getweight函数为空,最后直接与lambda相乘
NDCGLambdaWeightComputer
首先根据label对排序算出IDCG的值
再根据输入的pos_index和neg_index计算出交换坐标导致的ndcg变化即delta数值,并将该数值以weight的形式存入pair中,最后与lambda相乘
MAPLambdaWeightComputer
根据pos_index neg_index以及两者的label和pred的值,计算在交换两者顺序的情况下的delta值,在计算完成后以weight的形式存入pair中,最后与lambda相乘
网友评论