搜索 / NOTEBOOK 课程

43 · Pointwise、Pairwise与Listwise目标

构造分级标签与真梯度优化;29保留真实多特征融合训练

构造机制只读 · 已保存的实验

已有输出来自保存的教学实验,并非打开页面时重新执行。 代码和原始输出保持不变;数据与历史注释保留原始语言。

43 · Pointwise、Pairwise与Listwise目标

单元:S14。先修:29、32–34、42。

来源:王树森固定目录。这是 Lab 自编实验;王树森后四模块只有公开目录,不称原作者完整讲义。

证据边界:构造分级标签与真梯度优化;29保留真实多特征融合训练。

学习方式:先预测每个对照,再只改一个变量,运行后解释差异。

PYTHON · 01
import numpy as np
import pandas as pd
from IPython.display import display
from reclab.learning.search_curriculum import *

三类目标

pointwise拟合每条标签;pairwise拟合有序对;listwise以整个候选列表建分布。此处固定同一三条候选,只改变loss,完整梯度训练,不称LambdaMART。

PYTHON · 02
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只看顺序。

PYTHON · 03
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不代表最优可比配置。排名不一定不同,保留相同与负结果。

PYTHON · 04
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。

PYTHON · 05
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,直接展示拟合分数与优化次序的差别。

改参数后应以新输出重新判断,不把这段固定解读当作新的测量。

复盘与练习

写下输入、输出、保持不变的量与本章不能支持的结论。选一个上面的单变量参数先预测再重跑;保留失败例。回到搜索学习路径继续下一语义单元。

继续阅读原文

本章来源

作者课程中文

王树森 · 搜索引擎技术

目录:排序 → 融合模型训练

固定版本:六模块目录、9份PDF。查询处理、召回、排序、查询推荐四模块主要是目录,Lab实验为独立教学实现。

学习标记可选,仅保存在当前浏览器中。打开页面不会自动标记已学。