以前的博客:http://www.cnblogs.com/bentuwuying/p/6681943.html中简单介绍了Learning to Rank的基本原理,也讲到了Learning to Rank的几类经常使用的方法:pointwise,pairwise,listwise。前面已经介绍了pairwise方法中的 RankSVM 和 IR SVM,这篇博客主要是介绍另外一种pairwise的方法:GBRank。html
GBRank的基本思想是,对两个具备relative relevance judgment的Documents,利用pairwise的方式构造一个特殊的 loss function,再使用GBDT的方法来对此loss function进行优化,求解其极小值。函数
GBRank的创新点之一就在于构造一个特殊的loss function。首先,咱们须要构造pair,即在同一个query下有两个doc,咱们能够经过人工标注或者搜索日志中获取的方法,来对这两个doc与该query的相关程度进行判断,获得一个相关关系,即其中一个doc的相关程度要比另外一个doc的相关程度更高,这就是relative relevance judgment。一旦咱们有了这个pairwise的相对关系,问题就成了如何利用这些doc pair学习出一个排序模型。学习
假设咱们有如下的preference pairs 做为training data:优化
咱们构造出如下的loss function:spa
我我的以为,这个loss function有些受SVM中的hinge loss的启发,是在hinge loss的基础上,将原来为1的参数改为了。即当
与
的差距达到
以上的时候,loss才为0,不然loss为
。日志
而后问题就变成了怎样对这个loss function进行优化求解极小值。这里使用了GBDT的思想,即Functional Gradient Descent的方法。htm
首先咱们来回顾一下Functional Gradient Descent在GBDT中的使用,具体可见以前的博客:http://www.cnblogs.com/bentuwuying/p/6667267.html。blog
在GBDT中,Functional Gradient Descent的使用为:将须要求解的F(x)表示成一个additive model,即将一个函数分解为若干个小函数的加和形式,而这每一个小函数的产生过程是串行生成的,即每一个小函数都是在拟合 loss function在已有的F(x)上的梯度方向(因为训练数据是有限个数的,因此F(x)是离散值的向量,而此梯度方向也表示成一个离散值的向量),而后将拟合的结果函数进一步更新到F(x)中,造成一个新的F(x)。排序
再回到咱们如今面对的问题,对loss function,利用Functional Gradient Descent的方法优化为极小值。即将f(x)表示成additive model,每次迭代的时候,用一个regression tree来拟合loss function在当前f(x)上的梯度方向。此时因为训练数据是有限个数的,f(x)一样只是一系列离散值,梯度向量也是一系列离散值,而咱们就是使用regression tree来拟合这一系列离散值。但不同的地方在于,这里的loss function中,有两个不同的f(x)的离散值与
,因此每次咱们须要对f(x)在这两个点上的值都进行更新,即须要对一个training instance计算两个梯度方向。get
首先,咱们将
看作两个未知变量,而后求解loss function对这两个未知变量的梯度,以下:
若是,则此时对应的loss为0,咱们无需对f(x)进行迭代更新;而若是
,则此时的loss不为0,咱们须要对f(x)进行迭代更新,即便得新的f(x)在这个instance上的两个点的预测值可以更接近真实值。
具体为:
当学习速率等于1的时候,更新公式即为:
此时须要注意的是,有些feature vector x可能会出现屡次,关键在不一样instance中对其的更新值还可能不相同。
一种方法是对同一个feature vector x,将其不一样的更新值求平均,做为其最终须要更新到的目标值,再进行拟合。
另外一种更好的方法是,将全部的instance都加入到regression拟合过程当中,不论这些feature vector是否会出现屡次且不一样次的拟合目标还不同。咱们须要作的就是让regression拟合过程,结合全部instance的全局信息,本身决定该怎么样拟合,怎样解决同一个feature vector有不一样目标值得问题。
当咱们收集到全部loss值不为0的training instance后,咱们便获得了其对应的更新值:
接着,咱们便使用一棵regression tree对这些数据进行拟合,生成一个拟合函数gk(x),而后将此次迭代更新的拟合函数更新到f(x)中,此处采用线性叠加的方式:
其中,ß即为shrinking系数。
在这里你们或许会有疑问,为何在每次迭代更新的时候,新的regression tree不像GBDT中那样,纯粹地去拟合梯度方向(一个离散值的向量),而是去拟合这样一个 原始预测值+梯度更新值 后的新预测值向量呢?我本身的理解是这样的(不知道对不对?欢迎你们指正):由于在每次迭代更新的时候,只是取了部分训练数据(即全部loss值不为0的training instance中的doc pair),因此每次拟合的时候,都只是对这部分数据进行训练,获得一个regression tree,而后把这个新的拟合函数(即regression tree)添加到总的预测函数f(x)中去,即这个regression tree在预测时候是须要对全部训练数据,而不是部分数据,进行预测的。因此若是每次迭代是去拟合梯度的话(梯度方向彻底有可能与当前的f(x)向量方向相差很大),在预测的时候,这个regression tree对其他数据(并无参与这个regression tree训练的数据)的预测值会偏离它们原始值较多,并且这个偏离是不在指望之中的,由于这些数据的当前预测值已经相对靠谱了(不会对loss function有贡献)。因此,当每次拟合的目标是 原始f(x)向量 + 梯度向量 的时候,这个新的向量不会跑的太偏(即跟原始向量相差较小),这时候拟合出来的结果regression tree在对总体数据进行预测的时候,也不会跑的太偏,只是会根据梯度方向稍微有所改变,对其它并不须要更新的数据的影响也相对较小。但同时也在逐渐朝着总体的优化方向上去尝试,因此才会这么去作。
总结来看,GBRank的总体学习步骤总结以下:
版权声明:
本文由笨兔勿应全部,发布于http://www.cnblogs.com/bentuwuying。若是转载,请注明出处,在未经做者赞成下将本文用于商业用途,将追究其法律责任。