搜尋排序演算法

2022-02-11 03:18:54 字數 3754 閱讀 5056

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是配對法排序學習(pairwise)的經典模型,通過svm對query-doc pair進行打分和排序。ranksvm的輸入特徵維query-doc pair的特徵差值,即 \(x_1-x_2\),標籤為相對順序(+1,-1).

gbrank由雅虎的員工提出。基本學習器是梯度提公升器(gradient boosting machine,gbm)。對於所有的x>y的n個偏序對的訓練樣本,其損失函式可定義為:

\[l_1=\sum_^n \max(0,h(y_i)-h(x_i)) \\

|| \\

l_2=\sum_^n (\max(0,h(y_i)-h(x_i)))^2

\]在使用梯度下降求解時,第m次迭代更新h:\(h(y_i^m)=h_(y_i)-\rho_m\times\over \partial y_i}\).只有當偏序**錯誤時才進行更新,此時有\(h(y_i^m)=h(x_i^);\ h(x_i^m)=h(y_i^)\).在偏序學習正確時還需要保證學習的更健壯,因此需要讓差值足夠大,損失函式修改如下:

\[l_3=\sum_^n (\max(0,\tau+h(y_i)-h(x_i)))^2

\]這樣在偏序學錯後,更新:\(h(y_i^m)=h(x_i^)-\tau;\ h(x_i^m)=h(y_i^)+\tau\).

gbrank對所有gbm採用了歸一化處理:\(h_m(x)=(x)+\eta g_m(x)\over m+1}\),其中\(\eta\)為收縮率。

ranknet由微軟的博格斯提出(icml2005),比gbrank更早的提出觀點:偏序學習可以避免建模過程中將每條樣本對映為確切的排序值,而只需學習排序先後的偏序關係即可。ranknet通過神經網路來學習先後偏序的概率。設學習的目標概率是\(\bar p_\),當x排序在y之前(x>y)時,\(\bar p_=1\),反之為0,不能確定偏序關係時值為0.5. 設輸入x,y對應的輸出值分別為\(f(x),f(y),o_=f(x)-f(y)\),偏序**值為\(\text(o_)=}}\). 損失函式定義為交叉熵損失(對數機率損失):

\[\begin

l_&=-\bar p_\log p_-(1-\bar p_)\log(1-p_) \\

&=-\bar p_[o_-\log(1+e^})]+(1-\bar p_)\log(1+o_) \\

&=-\bar p_o_+\log(1+e^})

\end

\]由於pair的偏序概率具有傳遞性,因此ranknet可以是o(n)的複雜度。由於ranknet以減少錯誤pair為優化目標,因此對ndcg(關心相關文件所在的位置)等指標衡量的效果不是太好(同樣的ranksvm、gbdt等排序模型亦是如此)。後續的改進模型包括lambdarank、lambdamart。

開源**實現:ranklib包含了多種演算法實現。

這是微軟在 bing 中使用了較長時間的模型,也在l2r這個領域享有盛譽。博格斯的團隊意識到 ranknet 並不能直接優化搜尋的評價指標(ndcg 或者 map 等)之後提出了 lambdarank,使用ndcg的變化量對模型引數進行優化。隨後把

lambdarank 和 gbdt 的思想結合起來,提出了更強的 lambdamart。

lambda 是被定義為兩個文件 ndcg 的變化量(實際上用這個變化量乘以對數機率損失的梯度)。lambda梯度更關注位置靠前的優質文件的排序位置的提公升,有效的避免了下調位置靠前優質文件的位置這種情況的發生。

p-r的有兩個明顯缺點:

沒有考慮位置因素。

ndcg 這個指標的假設是,在乙個排序結果裡,相關資訊要比不相關資訊排得更高,而最相關資訊需要排在最上面,最不相關資訊排在最下面。任何排序結果一旦偏離了這樣的假設,就會受到「扣分」或者說是「懲罰」。ndcg 是針對測試集的乙個排序評價指標。

ndcg 是考慮到評分的排序,說到ndcg就需要從cg開始說起。cg(cumulative gain,累計增益)可以用於評價基於打分/評分的個性推薦系統。假設我們推薦k個物品,這個推薦列表的cgk計算公式如下:

\[cg_k=\sum_^k \text_i

\]\(\text_i\) 表示第k個物品的相關性或者評分。假設我們共推薦k個電影,\(\text_i\) 可以是使用者對第i部電影的評分。

該使用者對這五部電影的評分分別是:5, 3, 2, 1, 2

那麼這個推薦列表的cg等於

cg5=5+3+2+1+2=13.

cg沒有考慮推薦的次序,在此基礎之後我們引入對物品順序的考慮,就有了dcg(discounted cg),折扣累積增益。公式如下:

\[dcg_k=\sum_^k \frac_i}-1}

\]那麼這個推薦列表的dcg等於

\[dcg_5=\frac+\frac+\frac+\frac+\frac=31+4.4+1.5+0.4+1.2=38.5

\]對於排序引擎而言,不同請求的結果列表長度往往不相同。當比較不同排序引擎的綜合排序效能時,不同長度請求之間的dcg指標的可比性不高。dcg沒有考慮到推薦列表和每個檢索中真正有效結果個數,目前在工業界常用的是normalized dcg(ndcg),它假定能夠獲取到某個請求的前p個位置的完美排序列表,這個完美列表的分值稱為ideal dcg(idcg),ndcg等於dcg與idcg比值。所以ndcg是乙個在0到1之間的值。

完美結果下的dcg,即idcg的定義如下:

\[\text_p=\sum_^-1 \over \log_2(i+1)}

\]|rel|代表按照相關性排序好的最多到位置p的結果列表。

\[ndcg_k=\frac

\]把這7部電影按評分排序:5, 4, 3, 2, 2, 1, 0

這個情況下的完美dcg是

\[idcg_5=\frac+\frac+\frac+\frac+\frac=31+9.5+3.5+1.3+1.2=46.5

\]所以, \(ndcg_5 = \frac=\frac=0.827\)

ndcg是0到1的數,越接近1說明推薦越準確。

參考:

與dcg相比,除了考慮位置衰減和允許多種相關級別(以r1,r2,r3...來表示)以外,err更進了一步,還考慮了排在文件之前所有文件的相關性。舉個例子來說,文件a非常相關,排在第5位。如果排在前面的4個文件相關度都不高,那麼文件a對列表的貢獻就很大。反過來,如果前面4個文件相關度很大,已經完全解決了使用者的搜尋需求,使用者根本就不會點選第5個位置的文件,那麼文件a對列表的貢獻就不大。

err的定義如下:

\[err=\sum_^n\prod_^(1-r_i)r_r

\]

演算法 排序演算法 搜尋演算法

排序演算法 function arraylist this.tostring function item 冒泡 this.bubblesort function function swap arr,index1,index2 改進冒泡,減少內迴圈不必要的比較次數,每一輪最後兩個數下一次沒必要再比較 ...

Python排序搜尋基本演算法 之拓撲排序

拓撲排序是對有向無環圖的一種排序,滿足如下兩個條件 1.每個頂點出現且只出現一次 2.若a在序列中排在b的前面,則在圖中不存在從b到a的路徑。如上的無環有向圖,v表示頂點 v a b c d e e表示有向邊 e a b a d b c d c d e e c 如下 def indegree0 v,...

演算法 搜尋旋轉排序陣列

假設按照公升序排序的陣列在預先未知的某個點上進行了旋轉。例如,陣列 0,1,2,4,5,6,7 可能變為 4,5,6,7,0,1,2 搜尋乙個給定的目標值,如果陣列中存在這個目標值,則返回它的索引,否則返回 1 可以假設陣列中不存在重複的元素。你的演算法時間複雜度必須是 o log n 級別。示例 ...