排序模型#
排序模型負責對召回階段產生的候選集做精細打分,是推薦系統最關鍵的環節之一,直接決定用戶看到的內容順序。
召回追求 recall(不要漏掉好物品),排序追求 precision(把最好的排到最前)。所以模型要更精細、特徵要更豐富、訓練要更花成本。
排序模型的演進#
LR → GBDT → LR + GBDT → FM → FFM → 深度模型(DeepFM、DIN、…)這條演進線的主軸是「特徵交叉怎麼自動學」:從 LR 的人工交叉,到 FM 的二階自動,到深度模型的高階自動。
CTR 預估#
問題定義#
CTR(Click-Through Rate)預估本質上是二分類問題:
P(click=1 | user, item, context)特徵工程#
| 特徵類別 | 範例 |
|---|---|
| 用戶特徵 | 年齡、性別、興趣標籤、歷史行為 |
| 物品特徵 | 類別、品牌、價格、標題關鍵詞 |
| 上下文特徵 | 時間、地點、設備、推薦位置 |
| 交叉特徵 | 用戶類別 × 物品類別、性別 × 品牌 |
特徵工程是傳統機器學習排序模型的核心,「好的特徵比好的模型更重要」是業界共識。深度模型的部分價值就在於把人工交叉自動化。
邏輯回歸(LR)#
模型公式#
P(y=1|x) = σ(w^T x + b) = 1 / (1 + e^(-(w^T x + b)))優缺點#
| 優點 | 缺點 |
|---|---|
| 訓練快、可解釋 | 只能學線性關係 |
| 支援線上學習 | 需要大量手工特徵工程 |
| 工業界廣泛驗證 | 難以捕捉特徵交叉 |
特徵處理#
# 連續特徵離散化
age_bucket = [0, 18, 25, 35, 45, 55, 65, float('inf')]
age_feature = np.digitize(age, age_bucket)
# 類別特徵 One-Hot 編碼
category_onehot = OneHotEncoder().fit_transform(category)連續特徵離散化的好處:對極端值不敏感、可學非線性、與類別特徵統一形式。LR 時代幾乎所有連續特徵都會分桶。
GBDT(梯度提升決策樹)#
原理#
加法模型,不斷加入新樹去擬合殘差:
F_m(x) = F_{m-1}(x) + γ_m × h_m(x)其中 h_m(x) 是擬合殘差的決策樹。
優缺點#
| 優點 | 缺點 |
|---|---|
| 自動發現特徵組合 | 難處理高維稀疏特徵 |
| 不需要特徵正規化 | 不支援線上學習 |
| 處理非線性關係佳 | 訓練速度較慢 |
LR + GBDT#
Facebook 經典方案#
Facebook 2014 年提出的經典方案,把 GBDT 當「特徵組合自動發現器」、LR 當「線上可更新的最終打分器」。
流程#
1. 訓練 GBDT 模型
2. 把樣本輸入 GBDT,記錄落入的葉子節點
3. 把葉子節點 ID 編碼為新特徵(One-Hot)
4. 用 LR 訓練這些新特徵範例
假設 GBDT 有 3 棵樹,每棵樹有 4 個葉子節點:
輸入樣本 → 落入葉子 [1, 0, 3]
編碼為:[0,1,0,0] + [1,0,0,0] + [0,0,0,1]
= [0,1,0,0,1,0,0,0,0,0,0,1]這個 12 維向量作為 LR 的輸入。
工程實作#
import lightgbm as lgb
# 訓練 GBDT
gbdt_model = lgb.LGBMClassifier(n_estimators=100)
gbdt_model.fit(X_train, y_train)
# 取葉子節點編碼
leaf_indices = gbdt_model.predict(X_train, pred_leaf=True)
# 用葉子節點訓練 LR
from sklearn.linear_model import LogisticRegression
lr_model = LogisticRegression()
lr_model.fit(leaf_one_hot, y_train)FM(Factorization Machines)#
動機#
LR 需要人工構造交叉特徵;FM 透過隱向量自動學習所有二階特徵交叉。
模型公式#
ŷ = w_0 + Σ w_i x_i + Σ Σ <v_i, v_j> x_i x_jw_0:偏置w_i:一階權重<v_i, v_j>:二階交叉,用隱向量內積表示
計算優化#
原始二階項複雜度 O(n²),透過數學變換可降到 O(kn):
Σ Σ <v_i, v_j> x_i x_j = 1/2 [||Σ v_i x_i||² - Σ ||v_i||² x_i²]優缺點#
| 優點 | 缺點 |
|---|---|
| 自動學特徵交叉 | 只能學二階交叉 |
| 處理稀疏特徵有效 | 對稠密特徵效果普通 |
| 計算效率高 | 需調整隱向量維度 k |
FFM(Field-aware FM)#
改進#
FM 對每個特徵只有「一條」隱向量;FFM 認為一個特徵與不同 Field 交叉時應使用不同的隱向量:
ŷ = w_0 + Σ w_i x_i + Σ Σ <v_{i,f_j}, v_{j,f_i}> x_i x_jf_i:特徵 i 所屬的 Fieldv_{i,f}:特徵 i 對 Field f 的隱向量
範例#
| 特徵 | Field |
|---|---|
| 用戶 ID | User |
| 廣告 ID | Ad |
| 廣告主 | Advertiser |
計算「用戶」與「廣告」交叉時,使用 v_{user, Ad}。
FFM 參數量是 FM 的 Field 數倍,容易過擬合,需要更多正則化。後續被深度模型(DeepFM、xDeepFM)逐步取代。
模型對比#
| 模型 | 特徵交叉 | 計算複雜度 | 線上學習 | 適用場景 |
|---|---|---|---|---|
| LR | 手動 | O(n) | 支援 | 基線模型 |
| GBDT | 自動 | O(n log n) | 不支援 | 離線批次 |
| LR+GBDT | 自動 | O(n) | 部分支援 | 工業傳統標準 |
| FM | 二階 | O(kn) | 支援 | 稀疏特徵 |
| FFM | 二階 | O(kfn) | 支援 | 多 Field 場景 |
| DeepFM 等 | 高階 | - | 支援 | 詳見 第 7 章 |
排序學習(Learning to Rank)#
前面的模型大多把排序當成「對每個物品獨立預測 CTR,再照分數排」。但排序的本質是相對順序,LTR 依「損失函數看幾個物品」分成三類:
| 範式 | 損失看的範圍 | 代表方法 | 特性 |
|---|---|---|---|
| Pointwise | 單一物品 | LR、GBDT、FM | 最簡單,但丟失「相對順序」資訊 |
| Pairwise | 一對物品(誰較好) | RankNet、LambdaRank | 直接學「i 應排在 j 前」 |
| Listwise | 整個清單 | ListNet、LambdaMART | 直接對齊 NDCG,品質最好但最複雜 |
取捨很直接:CTR 預估場景多用 pointwise(簡單、好校正、能算絕對機率);當目標是把清單整體排好、且在意位置時,pairwise / listwise 更貼合 NDCG。前一章的 BPR 就是 pairwise 思想在矩陣分解上的應用。
工程實踐要點#
1. 樣本構造#
正樣本:用戶點擊的物品
負樣本:曝光但未點擊的物品負樣本採樣:曝光量太大時對負樣本降採樣可加速訓練,但預測時要做機率校正(見第 3 點)。
類別極度不平衡:CTR 資料的正樣本常只占 0.1~1%。除了負樣本降採樣,還可用加權損失(提高正樣本的損失權重)或 focal loss(聚焦難分樣本)。注意降採樣會系統性壓低或抬高預測機率,必須搭配校正才能用於競價。
2. 特徵雜湊#
解決高維稀疏特徵的儲存問題:
def hash_feature(feature_name, value, n_bins=2**20):
return hash(f"{feature_name}:{value}") % n_bins代價是極小機率的雜湊衝突,但工程簡潔性收益極大。
3. 模型校正(Calibration)#
降採樣負樣本後,模型輸出的「機率」會偏高,需要還原:
校正後 CTR = 預測 CTR × 採樣率 / (預測 CTR × 採樣率 + 1 - 預測 CTR)廣告系統對校正特別敏感(因為要拿 CTR 算 eCPM 競價)。
除了上面的採樣率還原公式,通用的校正手法還有:Platt scaling(在模型輸出上再套一層 logistic 擬合)、isotonic regression(無參數的單調映射)、深度模型常用的 temperature scaling。校正好不好可用 可靠度圖(reliability diagram) 或 ECE(期望校正誤差) 量化:理想情況下「模型說 0.5 的那群樣本,實際點擊率也該接近 0.5」。
4. 評估指標#
| 指標 | 說明 |
|---|---|
| AUC | 全局排序能力,越接近 1 越好 |
| Log Loss | 預測機率的準確度 |
| Calibration | 預測值與實際 CTR 的偏差 |
| NDCG@K | 考慮位置的排序品質,位置越前權重越高 |
| GAUC | 每位用戶各算 AUC 再加權平均 |
AUC 與 NDCG 的分工:AUC 衡量「能不能把正樣本排在負樣本前面」,把所有正負對視為等重;NDCG 多了位置折扣(排第 1 和排第 10 的相關物品價值不同),更貼近「用戶只看前幾筆」的真實體驗。所以 pointwise 模型常看 AUC/GAUC,listwise 排序則直接以 NDCG 為優化與評估目標。
為什麼用 GAUC 而不是 AUC? AUC 算的是「全部正樣本與全部負樣本」的相對順序,但推薦的真實場景是「同一用戶內部排序」。AUC 高可能只是因為「活躍用戶傾向點什麼都點」這種跨用戶 bias。GAUC 才反映模型在每位用戶內部的排序能力。
總結#
| 要點 | 說明 |
|---|---|
| CTR 預估 | 預測用戶點擊機率,二分類問題 |
| LR | 簡單高效,需要手工特徵 |
| GBDT | 自動發現特徵組合,離線訓練 |
| LR + GBDT | Facebook 經典方案 |
| FM | 自動學二階交叉 |
| FFM | Field-aware 改進,但易過擬合 |
| LTR | pointwise / pairwise / listwise 三範式 |
| 工程要點 | 樣本構造、類別不平衡、模型校正、GAUC |
| 演進方向 | ➡️ 深度模型(DeepFM、Wide&Deep、DIN) |
下一章:深度學習推薦