Learning to Rank算法介紹:GBRank


之前的博客:http://www.cnblogs.com/bentuwuying/p/6681943.html中簡單介紹了Learning to Rank的基本原理,也講到了Learning to Rank的幾類常用的方法:pointwise,pairwise,listwise。前面已經介紹了pairwise方法中的 RankSVM 和 IR SVM,這篇博客主要是介紹另一種pairwise的方法:GBRank。

GBRank的基本思想是,對兩個具有relative relevance judgment的Documents,利用pairwise的方式構造一個特殊的 loss function,再使用GBDT的方法來對此loss function進行優化,求解其極小值。

1. 構造loss function

GBRank的創新點之一就在於構造一個特殊的loss function。首先,我們需要構造pair,即在同一個query下有兩個doc,我們可以通過人工標注或者搜索日志中獲取的方法,來對這兩個doc與該query的相關程度進行判斷,得到一個相關關系,即其中一個doc的相關程度要比另一個doc的相關程度更高,這就是relative relevance judgment。一旦我們有了這個pairwise的相對關系,問題就成了如何利用這些doc pair學習出一個排序模型。

假設我們有以下的preference pairs 作為training data:

我們構造出以下的loss function:

我個人覺得,這個loss function有些受SVM中的hinge loss的啟發,是在hinge loss的基礎上,將原來為1的參數改成了。即當的差距達到以上的時候,loss才為0,否則loss為

然后問題就變成了怎樣對這個loss function進行優化求解極小值。這里使用了GBDT的思想,即Functional Gradient Descent的方法。

2. Functional Gradient Descent

首先我們來回顧一下Functional Gradient Descent在GBDT中的使用,具體可見之前的博客:http://www.cnblogs.com/bentuwuying/p/6667267.html

在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計算兩個梯度方向。

首先,我們將

看做兩個未知變量,然后求解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有不同目標值得問題。

3. 模型學習步驟

當我們收集到所有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。如果轉載,請注明出處,在未經作者同意下將本文用於商業用途,將追究其法律責任。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM