搜索排序算法
排序模型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。Pairwise模型是指所有文档两两组成一个pair,比如(X1,X2),如果X1的分值大于X2则将该pair当作正例+1,否则为负例-1. Pairwise的效果通常好于Pointwise(学术界是如此,工业界也越来越多用Pairwise了)。LambdaMart是Lambda和MART(Multiple Additive Regression Tree,GBDT的别名)的结合,是GBDT的一种针对排序问题的改进。在计算梯度时LambdaMart重新计算了Lambda,重新赋予了排序梯度的物理意义,它利用sigmoid来计算各pair的排序概率,使用交叉熵作为损失函数来判断拟合程度,并将排序离线指标(如MAP、NDCG)考虑到梯度中去。
- Listwise:将列表的最佳排序当作最终的优化目标,通过预测分布和真实排序分布的差距来优化模型,典型的模型如ListNet。引入规范化带折扣的累计收益(Normalized Discounted Cumulative Gain,NDCG)作为衡量列表排序质量的指标,以保证排序效果达到列表级别的最优。
下面介绍几个经典的排序模型及损失函数。
RankSVM
RankSVM 是配对法排序学习(Pairwise)的经典模型,通过SVM对query-(doc pair)进行打分和排序。RankSVM的输入特征维query-(doc pair)的特征差值,即 \(X_1-X_2\),标签为相对顺序(+1,-1)。
这和DSSM的双塔结构,每个塔单独输入query或doc的特征的方式有着显著的差别。
GBRank
GBRank 由雅虎提出,基本学习器是梯度提升器(Gradient Boosting Machine,GBM)。对于所有的x>y的N个偏序对的训练样本,其损失函数可定义为:
在使用梯度下降求解时,第m次迭代更新h:\(h(y_i^m)=h_{m-1}(y_i)-\rho_m\times{\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})\).在偏序学习正确时还需要保证学习的更健壮,因此需要让差值足够大,损失函数修改如下(Hinge loss与MSE的混合体):
这样在偏序学错后,更新:\(h(y_i^m)=h(x_i^{m-1})-\tau;\ h(x_i^m)=h(y_i^{m-1})+\tau\).
GBRank对所有GBM采用了归一化处理:\(h_m(x)={mh_{m-1}(x)+\eta g_m(x)\over m+1}\),其中\(\eta\)为收缩率。
RankNet - Logistic Pairwise loss
RankNet由博格斯提出(微软,ICML2005),比GBRank更早的提出观点:偏序学习可以避免建模过程中将每条样本映射为确切的排序值,而只需学习排序先后的偏序关系即可。RankNet通过神经网络来学习先后偏序的概率。设学习的目标概率是\(\bar P_{xy}\),当x排序在y之前(x>y)时,\(\bar P_{xy}=1\),反之为0,不能确定偏序关系时值为0.5. 设输入x,y对应的输出值分别为\(f(x),f(y),O_{xy}=f(x)-f(y)\),偏序预测值为\(\text{sigmoid}(O_{xy})={1\over 1+e^{-O_{xy}}}\). 损失函数定义为交叉熵损失(Logistic Pairwise loss):
由于pair的偏序概率具有传递性,因此RankNet可以是O(n)的复杂度。由于RankNet以减少错误pair为优化目标,因此对NDCG(关心相关文档所在的位置)等指标衡量的效果不是太好(同样的RankSVM、GBDT等排序模型亦是如此)。后续的改进模型包括LambdaRank、LambdaMart。
开源实现
:Ranklib包含了多种算法实现。
BPR loss
Bayesian personalized ranking (BPR) 是从最大后验估计推导而来的pairwise损失函数。
训练数据pair (u,i,j),表示用户u对item i的偏好高于item j。参数θ的后验估计通过bayes公式转化为 \(p(\Theta \mid >_u ) \propto p(>_u \mid \Theta) p(\Theta)\),从而有极大似然估计:
先验概率 p(Θ) 是一个高斯分布,以零为均值,方差-协方差矩阵(对角线为方差,其它位置为协方差)为 \(\Sigma_\Theta\),并且令 \(\Sigma_\Theta = \lambda_\Theta I\) 可推导出BPR损失。
对BPR-OPT取反便得到非负的损失函数,第二项 \(\lambda_\Theta |\Theta |^2\)等同于L2正则项。
这与RankNet中的Logistic Pairwise loss相似:
BPR loss增加了L2正则项。
参考:
- Personalized Ranking for Recommender Systems — Dive into Deep Learning
- paper:BPR: Bayesian Personalized Ranking from Implicit Feedback
- What is the variance-covariance matrix? - Minitab
Hinge loss
采用 Max-Margin 的 Hinge Loss:max{0,margin-(S(Q,D+)-S(Q,D-))}
LambdaMART - NDCG
LambdaMART 曾在微软 Bing 中使用了较长一段时间的模型,也在L2R这个领域享有盛誉。博格斯的团队意识到 RankNet 并不能直接优化搜索的评价指标(NDCG 或者 MAP 等)之后提出了 LambdaRank,使用NDCG的变化量对模型参数进行优化。随后把LambdaRank 和 GBDT 的思想结合起来,提出了更强的 LambdaMART。
Lambda 是被定义为两个文档 NDCG 的变化量(实际上用这个变化量乘以对数几率损失的梯度)。Lambda梯度更关注位置靠前的优质文档的排序位置的提升,有效的避免了下调位置靠前优质文档的位置这种情况的发生。
评价指标
Discounted Cumulative Gain(DCG)
如果将 Precision and Recall(P-R) 指标用于排序,会有两个明显缺点:
- 所有item只被分为相关和不相关两档,分类显然太粗糙。
- 没有考虑位置因素。
DCG解决了 P-R 的这两个问题。对于一个关键词,所有的文档可以分为多个相关性级别,这里以\(rel_1,rel_2,...\)来表示。文章相关性对整个列表评价指标的贡献随着位置的增加而对数衰减,位置越靠后,衰减越严重。
NDCG 是针对测试集的一个排序评价指标。NDCG 这个指标的假设是,在一个排序结果里,相关信息要比不相关信息排得更高,而最相关信息需要排在最上面,最不相关信息排在最下面。任何排序结果一旦偏离了这样的假设,就会受到“扣分”或者说是“惩罚”。
NDCG 是考虑到评分的排序,需要从CG开始说起。CG(cumulative gain,累计增益)可以用于评价基于打分/评分的个性推荐系统。假设我们推荐k个物品,这个推荐列表的累计增益计算公式如下:
\(\text{rel}_i\) 表示第 i 个物品的相关性或者评分。假设我们共推荐k个电影,\(\text{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说明推荐越准确。
参考: sofasofa
Mean Reciprocal Rank(MRR)
平均倒数排名(Mean Reciprocal Rank, MRR)是一个国际上通用的对搜索算法进行评价的机制。定义为多个查询语句的第一个正确答案的排名倒数的均值。主要用于寻址类检索(Navigational Search)或问答类检索(Question Answering)。
MRR为所有query的RR的平均值。其中,Q为样本query集合,rank i 表示在第i个query中,第一个正确答案的排名。
Expected Reciprocal Rank(ERR)
ERR (倒数排名的期望),表示用户的需求被满足时停止的位置的倒数的期望,是一个类似MRR的信息检索评价指标,但与 MRR 计算第一个相关文档的位置倒数不同。
与DCG相比,除了考虑位置衰减和允许多种相关级别(以R1,R2,R3...来表示)以外,ERR更进了一步,还考虑了排在文档之前所有文档的相关性。举个例子来说,文档A非常相关,排在第5位。如果排在前面的4个文档相关度都不高,那么文档A对列表的贡献就很大。反过来,如果前面4个文档相关度很大,已经完全解决了用户的搜索需求,用户根本就不会点击第5个位置的文档,那么文档A对列表的贡献就不大。
ERR的定义如下:
其中 Ri是关于文档i相关度等级的函数,假设该函数为:\(R_i = \frac {2^{l_i} - 1}{2^{l_m}}\),\(l_m\) 表示相关性评分最高的一档。\(l_i\) 表示样本中第 i 个结果的相关度标记。第 r 个文档被点击的概率(用户需求停留在第r个文档)为 \(R_r \prod_{i=1}^{r-1} (1 - R_i)\)。
如果将排名倒数 reciprocal rank 1/r 换成 1 / (log r+1), 则和 DCG 类似,只是分数计算方式不同(加法 vs 乘法)。