XGBoost中的Learning to Rank技术详解
概述
Learning to Rank(学习排序)是信息检索领域中的一项重要技术,旨在训练一个模型将查询结果排序成一个有序列表。在监督学习排序中,预测器是编码为特征矩阵的样本文档,标签是每个样本的相关性程度。相关性程度可以是多级(分级)或二元(相关或不相关)。训练样本通常按其查询索引分组,每个查询组包含多个查询结果。
XGBoost通过一组目标函数和性能指标实现了学习排序功能。默认目标是基于LambdaMART算法的rank:ndcg,该算法又是LambdaRank框架对梯度提升树的适应。
使用Pairwise目标进行训练
LambdaMART是一种成对排序模型,意味着它会比较查询组中每对样本的相关性程度,并为每对计算代理梯度。默认目标rank:ndcg使用从ndcg指标派生的代理梯度。
训练XGBoost排序模型时,我们需要一个额外的排序数组qid来指定输入样本的查询组。示例输入如下:
| QID | Label | Features |
|---|---|---|
| 1 | 0 | x₁ |
| 1 | 1 | x₂ |
| 1 | 0 | x₃ |
| 2 | 0 | x₄ |
| 2 | 1 | x₅ |
| 2 | 1 | x₆ |
| 2 | 1 | x₇ |
注意样本按其查询索引以非递减顺序排序。在上面的例子中,前三个样本属于第一个查询,后四个样本属于第二个查询。
位置偏差处理
获取查询结果的真实相关性程度是一项昂贵且费力的工作,需要人工标注者逐个标注所有结果。当这种标注任务不可行时,我们可能希望直接在用户点击数据上训练学习排序模型,因为点击数据相对容易收集。
然而,用户点击通常是有偏差的,因为用户倾向于选择显示在更高位置的结果。XGBoost实现了Unbiased LambdaMART算法来消除位置相关的点击数据偏差。
损失函数
XGBoost基于不同指标实现了不同的LambdaMART目标函数:
-
NDCG:可用于二元相关性和多级相关性。如果不确定数据特性,可以使用此指标作为默认。目标名称为
rank:ndcg -
MAP:二元度量。当相关性标签为0或1时使用。目标名称为
rank:map -
Pairwise:
rank:pairwise损失是成对损失的原始版本,也称为RankNet损失或成对逻辑损失
构建文档对
XGBoost实现了两种构建文档对的策略:
-
mean方法:为查询列表中的每个文档采样
lambdarank_num_pair_per_sample对 -
topk方法:为每个样本在顶部k位置构建约k×|query|数量的对
获得良好结果的技巧
学习排序是一项复杂的任务,以下是一些选择超参数的提示:
- 如果输入数据具有多级相关性程度,应使用
rank:ndcg或rank:pairwise - 当输入有二元标签时,选择应基于有效对的数量
- 使用mean策略生成对时,可以指定每个文档生成多少对
- 如果优先考虑顶部k文档,
lambdarank_num_pair_per_sample应设置为略高于k
总结:
- 如果有大量训练数据:
- 使用目标匹配的目标
- 选择
topk策略生成文档对
- 如果训练数据较少:
- 选择
NDCG或RankNet损失 - 选择
mean策略生成文档对
- 选择
分布式训练
XGBoost实现了与多种框架集成的分布式学习排序,包括Dask、Spark和PySpark。接口与单节点版本类似。
需要注意的是,位置去偏尚未支持现有的分布式接口。XGBoost使用集体操作,这意味着数据分散到多个工作节点。我们可以按查询组划分数据分区,并确保没有查询组被拆分到多个工作节点。
与1.7版本的结果比较
学习排序实现在2.0版本中进行了重大更新,添加了超参数和训练策略。要获得与1.7版本xgboost.XGBRanker类似的结果,应使用以下参数:
params = {
"lambdarank_pair_method": "mean",
"objective": "rank:pairwise",
"lambdarank_score_normalization": False,
"base_score": 0.5,
"tree_method": "approx",
"lambdarank_num_pair_per_sample": 1
}
可重现结果
与任何其他任务一样,在相同的硬件和软件环境(以及数据分区,如果使用分布式接口)下,XGBoost应该生成可重现的结果。但是,当lambdarank_pair_method设置为mean时,XGBoost使用随机采样,结果可能会因使用的平台而异。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



