XGBoost - 學習排序



XGBoost 是各種 LTR 應用中最常見的選擇,例如推薦系統增強、點選率預測和 SEO。在本節中,我們將介紹各種目標函式,引導您完成資料準備步驟,並提供一些如何訓練模型的示例。

什麼是學習排序?

在開始之前,我們將簡單解釋什麼是排序。排序是監督機器學習的一個子集。它不是預測單個數據點的結果,而是在接收一組資料點和一個查詢後評估一系列資料點,這將其與更常見的分類和迴歸情況區分開來。

通常,搜尋引擎使用排序來識別最相關的結果。它還可以用於建議內容,根據之前的購買提供相關的建議,或者,就像它對我一樣,識別在下一場比賽中獲勝機率最高的馬匹。

XGBoost 提供三種用於排序的目標函式:逐點、成對和列表。這三種目標函式各有優缺點,它們代表了確定專案組等級的不同方法。許多資源對它們進行了詳細的描述,但我們將重點介紹這裡的主要內容。

逐點法

此技術獨立處理每個查詢文件對。您只需為每個查詢-文件對賦予一個分數,並構建一個可以預測相關性分數的模型。

考慮以下情況,我們有一組查詢-文件對的資料集,每對的相關性分數介於 1 和 5 之間。可以透過訓練迴歸模型來預測每對的相關性分數。

逐點法是一種很好的入門方法,因為它除了易於使用之外,出乎意料地強大且難以超越。此方法可以在 XGBoost 中與任何典型的迴歸或分類目標函式一起使用。請記住要調整資料集標籤中的任何不平衡。

成對法

成對方法評估文件對,並做出決定以最小化順序錯誤的對數。它被 RankNet 等演算法使用。

這種方法每次處理一個查詢和兩個文件,並調整預測的相關性分數,以便最相關的文件的分數高於最不相關的文件。

與逐點法相比,它同時考慮查詢和單個文件。在這裡,我們希望精確地模擬文件相對於查詢的相對順序。

XGBoost 為此策略提供了一些目標函式:

  • rank:pairwise: 這是原始的成對損失函式(也稱為 RankNet),它將 LambdaRank 與 MART(多加性迴歸樹)結合起來,也稱為 LambdaMART。

  • rank:ndcg: NDCG 代表歸一化折損累積增益。它是業界最流行的排序質量指標之一,因為它同時考慮了給定查詢的文件的相對順序和每個頁面的相關性分數。此目標函式使用從 NDCG 指標建立的替代梯度來最佳化模型。

  • rank:map: MAP 代表平均平均精度。當相關性分數為二進位制(0 或 1)時,使用此較短的排序質量指標。如果 MAP 用作評估指標,則通常需要使用此目標函式。

列表法

即使 XGBoost 不使用列表法,為了完整起見,仍然有必要討論它。它考慮特定查詢的整個文件集,試圖一次最佳化列表的順序。

由於它分析所有文件的相對順序,它是對逐點和成對過程的改進,並可能產生更好的結果。列表法損失函式的一個例子是 ListMLE。

交叉驗證是一種有用的技術,用於在嘗試選擇最佳目標函式時確定適合您問題的理想目標函式。逐點法完全無效。

使用 XGBoost 進行學習排序

我們將瞭解如何使用 XGBoost(一個強大的機器學習框架)準備資料並構建學習排序 (LTR) 模型。我們將使用來自微軟的 MSLR-WEB10K 真實世界資料集,該資料集在學習排序社群中很流行。此資料集中查詢-文件對的相關性等級顯示文件與使用者查詢的匹配程度。

步驟 1:準備資料

學習排序是搜尋引擎根據相關性對結果進行排序的策略。此集中給出了:使用者試圖查詢什麼?顯示了使用者的搜尋結果。此外,每個文件的相關性分數(4 為最高相關性級別)顯示了其與查詢的相關性級別。分數範圍為 0 到 4。

在建立模型之前,我們必須匯入一些用於資料處理的關鍵庫:

import pandas as pd
import numpy as np
from sklearn.datasets import load_svmlight_file

這些庫使資料處理更容易。NumPy 用於數值計算,Pandas 用於資料操作。使用 sklearn.datasets 中的 load_svmlight_file 方法載入文字格式的大型多特徵資料集。

之後我們將載入我們的訓練和驗證資料集:

train = load_svmlight_file(str(data_path / '/Python/vali.txt'), query_id=True)
valid = load_svmlight_file(str(data_path / '/Python/test.txt'), query_id=True)

我們的模型的訓練和測試資料儲存在 train 和 valid 中。每個資料集都包含三個組成部分:目標向量(相關性分數)、特徵矩陣(表示文件特性)和查詢 ID(用於將文件分組到同一個查詢下)。

現在我們將將其解包到變數中以便輕鬆使用:

X_train, y_train, qid_train = train
X_valid, y_valid, qid_valid = valid

現在,X_train 和 X_valid 是特徵矩陣,y_train 和 y_valid 是相關性分數,qid_train 和 qid_valid 用於按查詢對文件進行分組。我們可以使用這種方法來複制排序任務。

步驟 2:訓練 XGBRanker

在訓練過程中,我們構建一個模型來根據文件與查詢的相關性對文件進行排序。透過匯入 XGBoost 庫,我們將首先建立 XGBRanker 類,該類旨在用於涉及學習排序的任務。

import xgboost as xgb
model = xgb.XGBRanker(tree_method="hist", objective="rank:ndcg")

這裡:

  • tree_method="hist" 是一種快速生成決策樹的方法。

  • objective="rank:ndcg" 設定旨在最佳化歸一化折損累積增益 (NDCG),這是一個常用在排序任務中的統計量。

接下來,我們將模型擬合到訓練資料:

model.fit(X_train, y_train, qid=qid_train)

在這種情況下,我們傳遞查詢 ID (qid_train)、特徵矩陣 (X_train) 和相關性分數 (y_train)。使用查詢 ID 將屬於同一查詢的文件分組是排序過程中的一個重要步驟。

步驟 3:預測相關性分數

模型訓練完成後,我們可以使用模型進行預測。對於排序,通常每次預測一個查詢的相關性很有幫助。假設我們想預測驗證集中第一個查詢的結果:

X_query = X_valid[qid_valid == qids[0]]

這裡,X_query 包含與初始查詢相關的所有文件。現在,我們可以透過應用以下方法來預測它們的相關性分數:

y_pred = model.predict(X_query)

計算出的分數將顯示每個文件相對於其他文件的相關性。透過對這些預測進行排序,可以對文件進行評分;分數越高表示相關性越高。

步驟 4:使用 NDCG 評估模型

我們使用一種稱為歸一化折損累積增益或 NDCG 的指標來評估我們的排序系統的有效性。此統計量評估排序在多大程度上準確地反映了文件的實際重要性。以下是 NDCG 計算函式:

def ndcg(y_score, y_true, k):
   order = np.argsort(y_score)[::-1]
   y_true = np.take(y_true, order[:k])

   gain = 2 ** y_true - 1
   discounts = np.log2(np.arange(len(y_true)) + 2)
   return np.sum(gain / discounts)

透過比較預期分數 (y_score) 和真實相關性分數 (y_true),此函式計算 NDCG。我們遍歷驗證集中的每個查詢並計算 NDCG 分數:

ndcg_ = list()
qids = np.unique(qid_valid)

for i, qid in enumerate(qids):
   y = y_valid[qid_valid == qid]
    
   if np.sum(y) == 0:
      continue
    
   p = model.predict(X_valid[qid_valid == qid])
   idcg = ndcg(y, y, k=10)
   ndcg_.append(ndcg(p, y, k=10) / idcg)

最後,我們計算每個查詢的平均 NDCG 分數:

np.mean(ndcg_)

因此,我們剩下的只是一個代表模型整體效能的單個分數。NDCG 分數越高表示排序質量越高。

廣告
© . All rights reserved.