排序模型LTR(L2R,learning to rank)
- Pointwise:对排序列表中的每一项,直接学习一个值,比如可以是预估点击率(Predict CTR,pCTR),然后按照预估值从大到小排序即可。常见模型有LR、FFM、GBDT、XGBoost。GBDT是LTR中应用较多的非线性模型。Additive Groves(简称AG)是在随机森林基础上构建的模型,加入Bagging算法,使得模型的泛化能力更强。AG由很多Grove 组合(bagging)而成,每一个Grove由多棵树组成,在训练时每棵树的拟合目标是真实值与其它树预测结果之和的残差。在训练的过程中达到了指定数目的树时,重新训练的树会替代掉以前的树。谷歌提出的FTRL方法能够在线对线性模型进行更新。
- Pairwise:两两学习两个项的先后关系。常见模型有GBRank、RankNet、LambdaMart、RankSVM。LambdaMart是Lambda和MART(Multiple Additive Regression Tree,GBDT的别名)的结合,是GBDT的一种针对排序问题的改进。在计算梯度时LambdaMart重新计算了Lambda,重新赋予了排序梯度的物理意义,它利用sigmoid来计算各pair的排序概率,使用交叉熵作为损失函数来判断拟合程度,并将排序离线指标(如MAP、NDCG)考虑到梯度中去。
- Listwise:将列表的最佳排序当作最终的优化目标,通过预测分布和真实排序分布的差距来优化模型,典型的模型如ListNet。引入规范化带折扣的累计收益(Normalized Discounted Cumulative Gain,NDCG)作为衡量列表排序质量的指标,以保证排序效果达到列表级别的最优。
Pairwise模型是指所有文档两两组成一个pair,比如(X1,X2),如果X1的分值大于X2则将该pair当作正例+1,否则为负例-1. Pairwise的效果通常好于Pointwise(学术界是如此,工业界也越来越多用Pairwise了)。
下面介绍几个排序经典模型:
RankSVM
RankSVM是配对法排序学习(Pairwise)的经典模型,通过SVM对query-doc pair进行打分和排序。RankSVM的输入特征维query-doc pair的特征差值,即 (X_1-X_2),标签为相对顺序(+1,-1).
GBRank
GBRank由雅虎的员工提出。基本学习器是梯度提升器(Gradient Boosting Machine,GBM)。对于所有的x>y的N个偏序对的训练样本,其损失函数可定义为:
在使用梯度下降求解时,第m次迭代更新h:(h(y_i^m)=h_{m-1}(y_i)- ho_m imes{partial L_2^{m-1}over partial y_i}).只有当偏序预测错误时才进行更新,此时有(h(y_i^m)=h(x_i^{m-1}); h(x_i^m)=h(y_i^{m-1})).在偏序学习正确时还需要保证学习的更健壮,因此需要让差值足够大,损失函数修改如下:
这样在偏序学错后,更新:(h(y_i^m)=h(x_i^{m-1})- au; h(x_i^m)=h(y_i^{m-1})+ au).
GBRank对所有GBM采用了归一化处理:(h_m(x)={mh_{m-1}(x)+eta g_m(x)over m+1}),其中(eta)为收缩率。
RankNet
RankNet由微软的博格斯提出(ICML2005),比GBRank更早的提出观点:偏序学习可以避免建模过程中将每条样本映射为确切的排序值,而只需学习排序先后的偏序关系即可。RankNet通过神经网络来学习先后偏序的概率。设学习的目标概率是(ar P_{xy}),当x排序在y之前(x>y)时,(ar P_{xy}=1),反之为0,不能确定偏序关系时值为0.5. 设输入x,y对应的输出值分别为(f(x),f(y),O_{xy}=f(x)-f(y)),偏序预测值为( ext{sigmoid}(O_{xy})={1over 1+e^{-O_{xy}}}). 损失函数定义为交叉熵损失(对数几率损失):
由于pair的偏序概率具有传递性,因此RankNet可以是O(n)的复杂度。由于RankNet以减少错误pair为优化目标,因此对NDCG(关心相关文档所在的位置)等指标衡量的效果不是太好(同样的RankSVM、GBDT等排序模型亦是如此)。后续的改进模型包括LambdaRank、LambdaMart。
开源代码实现
:Ranklib包含了多种算法实现。
LambdaMART
这是微软在 Bing 中使用了较长时间的模型,也在L2R这个领域享有盛誉。博格斯的团队意识到 RankNet 并不能直接优化搜索的评价指标(NDCG 或者 MAP 等)之后提出了 LambdaRank,使用NDCG的变化量对模型参数进行优化。随后把
LambdaRank 和 GBDT 的思想结合起来,提出了更强的 LambdaMART。
Lambda 是被定义为两个文档 NDCG 的变化量(实际上用这个变化量乘以对数几率损失的梯度)。Lambda梯度更关注位置靠前的优质文档的排序位置的提升,有效的避免了下调位置靠前优质文档的位置这种情况的发生。
Learning to rank 评价指标
Precision and Recall(P-R)
P-R的有两个明显缺点:
- 所有文章只被分为相关和不相关两档,分类显然太粗糙。
- 没有考虑位置因素。
Discounted Cumulative Gain(DCG)
DCG解决了 P-R 的这两个问题。对于一个关键词,所有的文档可以分为多个相关性级别,这里以(rel_1,rel_2,...)来表示。文章相关性对整个列表评价指标的贡献随着位置的增加而对数衰减,位置越靠后,衰减越严重。
NDCG 这个指标的假设是,在一个排序结果里,相关信息要比不相关信息排得更高,而最相关信息需要排在最上面,最不相关信息排在最下面。任何排序结果一旦偏离了这样的假设,就会受到“扣分”或者说是“惩罚”。NDCG 是针对测试集的一个排序评价指标。
NDCG 是考虑到评分的排序,说到NDCG就需要从CG开始说起。CG(cumulative gain,累计增益)可以用于评价基于打分/评分的个性推荐系统。假设我们推荐k个物品,这个推荐列表的CGk计算公式如下:
( ext{rel}_i) 表示第k个物品的相关性或者评分。假设我们共推荐k个电影,( ext{rel}_i) 可以是用户对第i部电影的评分。
比如豆瓣给用户推荐了五部电影: M1,M2,M3,M4,M5
该用户对这五部电影的评分分别是:5, 3, 2, 1, 2
那么这个推荐列表的CG等于
CG5=5+3+2+1+2=13.
CG没有考虑推荐的次序,在此基础之后我们引入对物品顺序的考虑,就有了DCG(discounted CG),折扣累积增益。公式如下:
那么这个推荐列表的DCG等于
对于排序引擎而言,不同请求的结果列表长度往往不相同。当比较不同排序引擎的综合排序性能时,不同长度请求之间的DCG指标的可比性不高。DCG没有考虑到推荐列表和每个检索中真正有效结果个数,目前在工业界常用的是Normalized DCG(NDCG),它假定能够获取到某个请求的前p个位置的完美排序列表,这个完美列表的分值称为Ideal DCG(IDCG),NDCG等于DCG与IDCG比值。所以NDCG是一个在0到1之间的值。
完美结果下的DCG,即IDCG的定义如下:
|REL|代表按照相关性排序好的最多到位置p的结果列表。
继续上面的例子,如果相关电影一共有7部:M1,M2,M3,M4,M5,M6,M7
该用户对这七部电影的评分分别是:5, 3, 2, 1, 2 , 4, 0
把这7部电影按评分排序:5, 4, 3, 2, 2, 1, 0
这个情况下的完美DCG是
所以, (NDCG_5 = frac{DCG_5}{IDCG_5}=frac{38.5}{46.5}=0.827)
NDCG是0到1的数,越接近1说明推荐越准确。
参考: http://sofasofa.io/forum_main_post.php?postid=1002561
Expected Reciprocal Rank(ERR)
与DCG相比,除了考虑位置衰减和允许多种相关级别(以R1,R2,R3...来表示)以外,ERR更进了一步,还考虑了排在文档之前所有文档的相关性。举个例子来说,文档A非常相关,排在第5位。如果排在前面的4个文档相关度都不高,那么文档A对列表的贡献就很大。反过来,如果前面4个文档相关度很大,已经完全解决了用户的搜索需求,用户根本就不会点击第5个位置的文档,那么文档A对列表的贡献就不大。
ERR的定义如下: