43 · Pointwise、Pairwise与Listwise目标
单元:S14。先修:29、32–34、42。
来源:王树森固定目录。这是 Lab 自编实验;王树森后四模块只有公开目录,不称原作者完整讲义。
证据边界:构造分级标签与真梯度优化;29保留真实多特征融合训练。
学习方式:先预测每个对照,再只改一个变量,运行后解释差异。
import numpy as np
import pandas as pd
from IPython.display import display
from reclab.learning.search_curriculum import *三类目标
pointwise拟合每条标签;pairwise拟合有序对;listwise以整个候选列表建分布。此处固定同一三条候选,只改变loss,完整梯度训练,不称LambdaMART。
import torch
torch.manual_seed(42)
x=torch.tensor([[1.,0.],[0.,1.],[.8,.4]])
y=torch.tensor([3.,0.,2.])
print('features',x.shape,'labels',y.tolist())Notebook 保存的输出 · 本页未执行
features torch.Size([3, 2]) labels [3.0, 0.0, 2.0]
目标实现
pointwise MSE拟合分档;pairwise softplus(−(s_i−s_j))用于y_i>y_j;listwise交叉熵目标softmax(y)。标签缩放会改变前后两者,pairwise只看顺序。
def objective(s,y,kind):
if kind=='pointwise': return ((s-y)**2).mean()
if kind=='pairwise':
mask=y[:,None]>y[None,:]
return torch.nn.functional.softplus(-(s[:,None]-s[None,:])[mask]).mean()
return -(torch.softmax(y,0)*torch.log_softmax(s,0)).sum()
for kind in ['pointwise','pairwise','listwise']:
print(kind,float(objective(torch.zeros(3),y,kind)))Notebook 保存的输出 · 本页未执行
pointwise 4.333333492279053 pairwise 0.6931471824645996 listwise 1.0986123085021973
固定预算真优化
同初始化、步数和learning rate;不同loss尺度相同lr不代表最优可比配置。排名不一定不同,保留相同与负结果。
rows=[]
for kind in ['pointwise','pairwise','listwise']:
w=torch.zeros(2,requires_grad=True); opt=torch.optim.SGD([w],lr=.1)
for step in range(60):
opt.zero_grad(); loss=objective(x@w,y,kind); loss.backward(); opt.step()
scores=(x@w).detach().numpy(); order=np.argsort(-scores)
rows.append({'objective':kind,'loss':float(loss.detach()),'scores':scores.tolist(),'order':order.tolist(),'ndcg':graded_ndcg(order.tolist(),{0:3,1:0,2:2})})
display(pd.DataFrame(rows))Notebook 保存的输出 · 本页未执行
| objective | loss | scores | order | ndcg | |
|---|---|---|---|---|---|
| 0 | pointwise | 0.029805 | [2.8116273880004883, -0.07029175013303757, 2.2... | [0, 2, 1] | 1.0 |
| 1 | pairwise | 0.237659 | [1.0923994779586792, -1.136237382888794, 0.419... | [0, 2, 1] | 1.0 |
| 2 | listwise | 0.756533 | [0.8868535757064819, -0.986713707447052, 0.314... | [0, 2, 1] | 1.0 |
排名指标与loss不一致
给所有score加常数,排名不变;pairwise/listwise不变,MSE改变。验证不变量,再到29章检查融合特征scaler只fit训练query。
s=torch.tensor([2.,0.,1.])
for kind in ['pointwise','pairwise','listwise']:
a=objective(s,y,kind); b=objective(s+10,y,kind)
print(kind,float(a),float(b))
if kind!='pointwise': assert torch.allclose(a,b,atol=1e-5)Notebook 保存的输出 · 本页未执行
pointwise 0.6666666865348816 87.33333587646484 pairwise 0.2511504590511322 0.2511504590511322 listwise 0.7373405694961548 0.7373405694961548
本次保存结果的解读
三种loss的数值尺度不同,但本例60步后都得到[0,2,1]和NDCG=1,不能按训练loss绝对值挑模型。分数整体加10保持排名,pairwise/listwise loss不变,而MSE从约0.667变87.333,直接展示拟合分数与优化次序的差别。
改参数后应以新输出重新判断,不把这段固定解读当作新的测量。
复盘与练习
写下输入、输出、保持不变的量与本章不能支持的结论。选一个上面的单变量参数先预测再重跑;保留失败例。回到搜索学习路径继续下一语义单元。