排序學習實踐---ranknet方法
http://www.cnblogs.com/LBSer/p/4439542.html
1 背景
隨著移動網際網路的崛起,越來越多的使用者開始習慣於從手機完成吃、喝、玩、樂、衣、食、住、行等各個方面的需求。開啟手機,點開手淘、美團等APP,商品玲玲滿目,而讓使用者將所有商品一頁頁看完已經不現實,通常情況下使用者也就檢視前幾頁,如果找不到滿意的商品則退出,從而造成流單。因此如何對商品進行排序使得使用者能儘快完成購買流程已經成為這些平臺的重要攻克方向。
圖1 手機淘寶、美團等app的商品排序示意
傳統的方法是找幾個特徵比如評分、銷量等,然後找個打分函式如簡單的線性函式:F=w1*評分+w2*銷量+...,並通過手工調整權重值w並結合abtest實驗來達到排序的目的(分數越高排名越高)。
這種方法非常簡單,但面臨著一些問題:1)每當增加一個特徵都得調整所有特徵的權重,並線上上進行abtest,費時費力;2)特徵較多時(當引入個性化特徵時),這種手工調整權重的方式已經不可能完成,很難找到一個較優解;3)隨著資料的不斷變化,每隔一段時間都需要人工重新調節權重。總體來講人工調參費時費力、效果也差!
為了避免人工調參,現在工業界主要採用排序學習方法。
2 排序學習簡介
排序學習的目的就是通過一些自動化的方法完成模型引數的訓練。根據不同型別的訓練資料可以將排序學習方法分為以下三類:a)單點標註(point wise);b)兩兩標註(pair wise);c)列表標註(list wise)。
2.1 point wise過程
下面介紹如何使用point wise方法來完成排序學習。
排序學習最重要的工作就是構造訓練樣本,即得到一組(V1,V2,V3,..., Y),其中V是特徵,Y是label,得到樣本之後帶入相應的機器學習模型即可完成訓練。
一般來說特徵可分成以下幾類(根據業務不同可自行新增特徵):a)商品(文件)本身特徵如:評分、銷量、價格等;b)使用者本身特徵如:性別、年齡、使用者的商品型別偏好等;c)使用者-商品關聯特徵如:是否看過此商品、是否買過此商品、對此商品的歷史評價等;d)場景特徵如:時間(早中晚)、與商品的距離、是否是節假日等。一般來說我們需要將這些特徵進行歸一化,原因參見:為什麼一些機器學習模型需要對資料進行歸一化?
找到特徵後需要定義label。我們認為給使用者展示過的商品label為1,使用者點選過的商品label為3,使用者購買過的商品label為7。
通過對歷史日誌資料的清洗整理我們可以得到成千上萬的樣本(V1,V2,V3,..., Y)。
得到樣本之後我們可以將此排序問題轉換為多分類問題(樣本特徵-類別標記)或者回歸問題(樣本特徵-連續值)。如果轉換為多分類問題,我們模型最後的輸出只能1、3或是7,往往導致在同一類中的文件(比如兩個文件輸入模型的得到的結果都是7)不好繼續排序,因此實際使用中往往將問題轉換為迴歸問題,常常採用LR、GBDT等來解決。
2.2 point wise缺點
point wise方法很直觀,非常容易將問題轉換為我們所熟知的問題,但其缺點是完全從單文件的分類角度計算,沒有考慮文件之間的相對順序。
舉個例子。假設圖2左圖紅框為某一次使用者點選的事件,這時候我們獲得一條樣本i (V1i,V2i,V3i,...,Xni, 3)。右圖紅框為某一次使用者點選的事件,我們獲得一條樣本j (V1j,V2j,V3j,...,Vnj, 3)。按照pointwise的思想,我們認為這兩條樣本的label都是3。但在第二張圖包含更重要的資訊,“使用者只點了紅框內的酒店,而沒有點綠框內的酒店(綠框內的酒店和左圖點選的酒店一致)”,即說明樣本j的label應該比樣本i的label大(樣本j排名比樣本i更靠前),而pointwise並沒有利用到這個資訊。
圖2 point wise缺點示意圖
自然我們的問題就是:如何將文件之間相對順序資訊利用進去呢?
2.3 pair wise方法
在pairwise方法中,我們不再從從單文件的分類角度來看待問題,而是從一個文件對如<d1,d2>來看待問題,即如圖2右圖所示,使用者點選了紅框的商品(d1)而沒有點選綠框中的商品(d2),那這個時候認為d1的相關性大於d2,那麼我們可以把 d1-d2的label設定為+1,d2-d1的label設定為為 -1。按照這種方式,我們就得到了二元分類器訓練所需的樣本了。預測時,只需要對所有pair進行分類,便可以得到文件集的一個偏序關係,從而實現排序。Pairwise方法有很多的實現,比如SVM Rank、RankNet、FRank、RankBoost等。
下面我們著重介紹下ranknet的原理以及應用。
3 ranknet
3.1 ranknet原理
假設有文件i和j,其中文件i的特徵向量是Xi(1i, v2i, v3i, ..., vni),文件j的特徵向量是Xj(v1i, v2j, v3j, ..., vnj),我們要找一個打分函式F,假設F是線性函式,F(Xi)=W*Xi=w1*v1i + w1*v2i + ... + wn*vni,其中w表示權重係數,F(Xi)表示針對文件Xi給出的得分。
我們希望找出這樣一個函式F(本質上是訓練得到這些權重w),當文件X1比X2排名高時,我們希望F(Xi) > F(Xj)。
下面我們需要定義損失函式了。首先定義概率Pij,用於表示Xi比Xj排名高的概率,直觀上可以設Pij=F(Xi)-F(Xj),這樣F(Xi)-F(Xj)越大表示Xi比Xj排名高的概率越大,但這裡問題的關鍵是概率值是在[0,1]區間範圍內的,因此需要歸一化。可以參考邏輯斯蒂迴歸的歸一化函式:
其中Oi=F(i),Oij=F(i)-F(j),這個函式有比較好的特質,當Oij=0時,Pij=0.5,當Oij>0時,Pij>0.5,並且當Oij趨向於無窮大時,Pij=1,反之當Oij<0時,Pij<0.5,當Oij趨向於無窮小時,Pij=0。
這個時候我們就可以定義損失函式了。損失函式常用有兩種型別:
1)平方損失函式
這是最常用的損失函式,但是現在由於已經做了歸一化邏輯對映,使得平方損失函式不再是一個凸函式,這給我們最優化求解造成了比較大的挑戰,因此實際常常使用另一種損失函式---交叉熵。
2)交叉熵
這裡插句題外話,為什麼非凸函式的最優解不好求?
如下圖所示一個非凸函式,要求最小值,我們常使用的梯度下降法或者牛頓迭代法往往限於區域性最優解,很難找到全域性最優解。
下面看看交叉熵損失函式是否能滿足我們的需求。
得到了凸損失函式之後,就可以使用梯度下降方法求解最優化引數。
如果直接這麼訓練最終得到的是線性模型,不能學習特徵之間的非線性關係,一般學習非線性關係有幾種方法:1)一種是對特徵進行高維對映,例如svm的核方法;2)樹模型;3)帶有隱藏層的神經網路。
3.2 基於神經網路的ranknet
在實際使用中,ranknet採用神經網路方法進行學習,一般採用的是帶有隱層的神經網路。學習過程一般使用誤差反向傳播方法來訓練。
這裡的輸入層(最底部)的神經元代表了樣本的每一個特徵,虛線的神經元代表隱藏層,最終輸出只有一個神經元。
如何訓練呢?這裡提供了兩種思路:
1)取一個樣本對(Xi, Xj),首先對Xi帶入神經網路進行前向反饋,其次將Xj帶入神經網路進行前向反饋,然後計算差分結果並進行誤差反向傳播,接著取下一個樣本對。。。
這種方法很直觀,缺點是收斂速度慢。
2)批量訓練。我們可以對同一個排序下的所有文件pair全部帶入神經網路進行前向反饋,然後計算總差分並進行誤差反向傳播,這樣將大大減少誤差反向傳播的次數,原理如下公式推導所示。
3.3 ranknet程式碼實現
開源ranknet實現:http://people.cs.umass.edu/~vdang/ranklib.html
3.4 應用
我們輸入的樣本如下所示:相應的欄位為:<target> qid:<qid> <feature>:<value> <feature>:<value> ... <feature>:<value> # <info>。其中target就是label,購買label=7,點選label=3,展示label=1;qid代表一次排序的標識,feature就是特徵,#後面是註釋資訊。
7 qid:1 1:1 2:1 3:0 4:0.2 5:0 # 1A
3 qid:1 1:0 2:0 3:1 4:0.1 5:1 # 1B
1 qid:1 1:0 2:1 3:0 4:0.4 5:0 # 1C
1 qid:1 1:0 2:0 3:1 4:0.3 5:0 # 1D
1 qid:2 1:0 2:0 3:1 4:0.2 5:0 # 2A
3 qid:2 1:1 2:0 3:1 4:0.4 5:0 # 2B
1 qid:2 1:0 2:0 3:1 4:0.1 5:0 # 2C
1 qid:2 1:0 2:0 3:1 4:0.2 5:0 # 2D
1 qid:3 1:0 2:0 3:1 4:0.1 5:1 # 3A
3 qid:3 1:1 2:1 3:0 4:0.3 5:0 # 3B
7 qid:3 1:1 2:0 3:0 4:0.4 5:1 # 3C
1 qid:3 1:0 2:1 3:1 4:0.5 5:0 # 3D
將樣本輸入到ranknet進行訓練,最終得到如下所示結果,其中我們特徵為46個,即輸入層中神經元個數為46個,隱藏層只設定了1層,隱藏層神經元個數設定為10個。
得到模型結果後,將此模型儲存到快取中。假設來一個線上請求,我們首先提取出各個文件的特徵向量(V1, V2, V3, ..., Vn),帶入此神經網路模型得到各個文件的評分,並按照評分進行排序。
4 小結
本文對排序學習做了一個簡單的介紹,並著重介紹了ranknet的原理以及應用,後面會對其他pair wise方法、list wise方法做一些探討。
檢索實踐文章系列:
lucene如何通過docId快速查詢field欄位以及最近距離等資訊?