排序模型(Learning to Rank, LTR)是推荐系统精排阶段的核心技术。与传统的回归/分类不同,LTR直接优化排序质量指标(NDCG/MRR),更符合推荐场景的需求。
| 方法 | 优化目标 | 代表算法 | 特点 |
|---|---|---|---|
| Pointwise | 单个文档的相关性 | PRank/M5P | 忽略文档间关系 |
| Pairwise | 文档对的相对顺序 | RankNet/LambdaRank | 考虑相对排序 |
| Listwise | 整个列表的排序质量 | LambdaMART/ListNet | 直接优化NDCG |
LambdaMART是LTR的集大成者,结合了LambdaRank的lambda梯度和MART(GBDT)的梯度提升框架。它通过lambda梯度直接优化NDCG,同时利用GBDT强大的非线性建模能力。
L = -σ·log(1/(1+exp(-σ(s_i-s_j))))
优化文档对的正确排序概率
λ_ij = ΔNDCG · σ/(1+exp(s_i-s_j))
乘以NDCG变化量,使梯度与指标对齐
DCG@K = Σ(2^rel_i-1)/log2(i+1)
NDCG@K = DCG@K / IDCG@K
import numpy as np
np.random.seed(42)
print("="*60+"\n排序模型(LambdaMART)\n"+"="*60)
n_queries=20;n_docs_per_query=10;n_features=8
# 生成排序数据
X=[];y=[];qids=[]
for q in range(n_queries):
q_features=np.random.randn(n_features)*0.5
for d in range(n_docs_per_query):
features=np.random.randn(n_features)*0.3+q_features
relevance=np.dot(features,np.random.randn(n_features))
relevance=int(np.clip(relevance+2,0,4))
X.append(features);y.append(relevance);qids.append(q)
X=np.array(X);y=np.array(y);qids=np.array(qids)
print(f"查询数:{n_queries} 文档数:{len(X)} 特征数:{n_features}")
print(f"相关性分布: {dict(zip(*np.unique(y,return_counts=True)))}")
# Pointwise方法(MSE回归)
print("\n--- Pointwise(MSE) ---")
from collections import defaultdict
w=np.random.randn(n_features)*0.01;b=0
lr=0.01
for ep in range(100):
pred=X@w+b
err=pred-y
w-=lr*(X.T@err/len(X)+0.01*w)
b-=lr*np.mean(err)
if(ep+1)%25==0:
mse=np.mean(err**2)
print(f" Epoch{ep+1}:MSE={mse:.4f}")
pred_pointwise=X@w+b
# Pairwise方法(RankNet简化)
print("\n--- Pairwise(RankNet) ---")
w_pair=np.random.randn(n_features)*0.01;b_pair=0
def sigmoid(x):return 1/(1+np.exp(-np.clip(x,-500,500)))
for ep in range(50):
total_loss=0;n_pairs=0
for q in range(n_queries):
mask=qids==q
q_X=X[mask];q_y=y[mask]
idx=np.random.choice(len(q_y),2,replace=False)
i,j=idx
if q_y[i]==q_y[j]:continue
s_i=q_X[i]@w_pair+b_pair
s_j=q_X[j]@w_pair+b_pair
target=1 if q_y[i]>q_y[j] else 0
pred=sigmoid(s_i-s_j)
loss=-target*np.log(pred+1e-10)-(1-target)*np.log(1-pred+1e-10)
total_loss+=loss;n_pairs+=1
grad=sig_grad=pred-target
w_pair-=lr*(grad*(q_X[i]-q_X[j])+0.01*w_pair)
b_pair-=lr*grad
if(ep+1)%10==0:print(f" Epoch{ep+1}:Loss={total_loss/max(n_pairs,1):.4f}")
# LambdaMART简化(用lambda梯度)
print("\n--- LambdaMART简化 ---")
w_lm=np.random.randn(n_features)*0.01;b_lm=0
def ndcg_at_k(rel,k):
dcg=sum((2**r-1)/np.log2(i+2)for i,r in enumerate(sorted(rel,reverse=True)[:k]))
idcg=sum((2**r-1)/np.log2(i+2)for i,r in enumerate(sorted(rel,reverse=True)[:k]))
return dcg/idcg if idcg>0 else 0
for ep in range(50):
for q in range(n_queries):
mask=qids==q;q_X=X[mask];q_y=y[mask]
pred=q_X@w_lm+b_lm
order=np.argsort(-pred)
# 计算lambda梯度
lambda_grad=np.zeros(len(q_y))
for i in range(len(q_y)):
for j in range(len(q_y)):
if q_y[i]<=q_y[j]:continue
delta_ndcg=abs(ndcg_at_k(list(q_y),5)-ndcg_at_k(list(q_y[[j if k==i else i if k==j else k for k in range(len(q_y))]]),5))
rho=1/(1+np.exp(pred[i]-pred[j]))
lambda_grad[i]+=delta_ndcg*rho
lambda_grad[j]-=delta_ndcg*rho
w_lm-=lr*(-q_X.T@lambda_grad/len(q_y)+0.01*w_lm)
b_lm-=lr*(-np.mean(lambda_grad))
if(ep+1)%10==0:
# 计算NDCG@5
ndcgs=[]
for q in range(n_queries):
mask=qids==q;q_X=X[mask];q_y=y[mask]
pred=q_X@w_lm+b_lm
top5=np.argsort(-pred)[:5]
ndcgs.append(ndcg_at_k(list(q_y[top5]),5))
print(f" Epoch{ep+1}:NDCG@5={np.mean(ndcgs):.4f}")
# 最终评估
methods={"Pointwise":pred_pointwise,"Pairwise":X@w_pair+b_pair,"LambdaMART":X@w_lm+b_lm}
print(f"\n{'方法':<15}{'NDCG@5':<10}{'MRR':<10}")
print("-"*35)
for name,pred in methods.items():
ndcgs=[];mrrs=[]
for q in range(n_queries):
mask=qids==q;q_y=y[mask];q_pred=pred[mask]
top5=np.argsort(-q_pred)[:5]
ndcgs.append(ndcg_at_k(list(q_y[top5]),5))
for rank,idx in enumerate(np.argsort(-q_pred)):
if q_y[idx]==max(q_y):mrrs.append(1/(rank+1));break
print(f"{name:<15}{np.mean(ndcgs):<10.4f}{np.mean(mrrs):<10.4f}")
✅ 验证通过
本课代码涵盖了从数据生成、模型训练到效果评估的完整流程。以下是关键步骤的详细解读:
代码设计原则:简洁可读、关键步骤有注释、结果可复现(固定随机种子)。
| 组件 | 版本 | 说明 |
|---|---|---|
| Python | 3.8+ | 推荐3.10版本 |
| NumPy | 1.21+ | 核心数值计算库 |
| SciPy | 1.7+ | 统计检验(部分课程) |
本课是第13课:排序模型(LambdaMART),属于排序与重排阶段。我们系统学习了本课的核心概念、数学原理和代码实现,并通过实机运行验证了算法的正确性。
练习1:实现完整的LambdaMART(使用GBDT)
练习2:对比Pointwise/Pairwise/Listwise的效果
练习3:用LightGBM的lambdarank目标函数训练
练习4:分析特征重要性并可视化
| 公司 | 场景 | 核心技术 |
|---|---|---|
| 字节跳动 | 抖音/TikTok | 多目标排序+实时特征+双塔召回 |
| 阿里巴巴 | 淘宝推荐 | DIN/DIEN序列模型+MIND多兴趣 |
| 腾讯 | 微信看一看 | DeepFM+图神经网络召回 |
| 美团 | 本地生活推荐 | 多场景多目标+时空特征 |
| Netflix | 视频推荐 | 矩阵分解+深度学习混合 |
✅ 理解LTR三大方法的区别
✅ 掌握LambdaMART的核心思想
✅ 实现简化版排序模型
✅ 理解排序模型在推荐精排中的应用