滴滴搜索算法
一、模型为什么不用单任务估 pCVR,这不是更加直接?
这是一个很有代表性的问题,在广告、推荐等场景中,经常会面临预测点击率(CTR)、转化率(CVR)或预估转化点击率(pCVR)的任务。
首先:
p C V R = P ( C o n v e r s i o n ∣ C l i c k ) pCVR = P(Conversion | Click) pCVR=P(Conversion∣Click)
也就是说,pCVR 是在用户点击之后发生转化的概率,它是一个条件概率。
1.1. 为什么不直接做单任务学习预测 pCVR?
因为:正样本太稀疏!
- 实际中,大多数曝光广告都不会被点击;
- 被点击的广告中,转化(比如购买、注册等)更少;
- 所以:用于训练 pCVR 的样本是 “点击后转化” 的数据,而点击本身就已经是一个很小的子集,转化更少,极度稀疏。
1.2. 多任务模型怎么做的?
一般采用 Shared Bottom 或者 MMOE(Multi-gate Mixture-of-Experts) 架构,预测多个目标,比如:
- CTR(Click-Through Rate)
- CVR(Conversion Rate)
- pCVR(可以通过公式拆解:CTR × pCVR = CVR)
有的模型直接估 pCVR,也有的拆成:
pCVR = P(Click) × P(Conversion | Click)
二、为什么多任务比单任务更好?
多任务学习(Multi-task Learning, MTL)是一种训练策略,它通过在一个模型中同时学习多个相关任务,提高模型的泛化能力和整体性能。
2.1. 数据增强与稀疏问题缓解
- 在一些任务(如 pCVR 预估)中,正样本极度稀疏。多任务通过引入其他任务(如 CTR、CVR)提供更多训练信号。弥补目标任务数据不足的问题,有效提升表现。
2.2. 表示共享,促进知识迁移
- 多个任务共享底层网络或特征表示;
- 有助于模型学到更通用、更稳健的表达能力;
- 辅助任务中的有用信息可迁移到主任务中,提升主任务效果。
2.3. 提升泛化能力,减少过拟合
- 单任务模型可能在小数据集上过拟合;
- 多任务中其他任务提供了额外正则化效应(multi-task regularization);
- 更难让模型仅记住某一任务的噪声。
2.4. 联合建模真实世界的复杂目标
- 实际业务目标往往不止一个(如点击、转化、GMV);
- 多任务模型可同时优化多个目标,符合业务逻辑;
- 可提升整体收益,而非只提升某一中间指标。
三、广告模型有的特征都有哪些类别?用户侧有哪些特征?
在广告推荐系统中,主要分为三个大类吧。
3.1. 用户特征(User Features)
描述用户的属性、行为、偏好等,是广告模型的核心输入之一。
子类别 | 示例 |
---|---|
用户基础属性 | 性别、年龄段、地域(省/市)、设备类型 |
用户兴趣偏好 | 兴趣标签、常浏览类目、用户画像 |
用户行为历史 | 最近点击广告、浏览内容、搜索关键词 |
用户环境特征 | 网络类型、操作系统、设备分辨率、浏览器类型 |
用户价值特征 | 用户等级、用户生命周期阶段(新/老)、ARPU值等 |
3.2. 广告特征(item Features)
描述当前广告本身的各种属性。
子类别 | 示例 |
---|---|
广告基本信息 | 广告ID、广告主ID、计划ID、创意ID |
广告内容特征 | 类目、标题、文本、图片、视频、标签 |
广告样式特征 | 展示位置、样式类型(图文/视频)、尺寸等 |
广告历史表现 | 历史CTR、历史CVR、点击次数、曝光次数 |
3.3. 上下文特征(Context Features)
描述当前广告展示发生的时间、位置、设备等上下文信息。
子类别 | 示例 |
---|---|
时间特征 | 小时、星期、节假日、昼夜标记 |
地点特征 | GPS、城市、国家、地理分区 |
展示位置特征 | 页签位置、feed流位置、slot ID |
设备特征 | 手机型号、操作系统、APP名称、浏览器类型 |
四、你认为MMoE(Multi-gate Mixture-of-Experts)的最大亮点,写一下其伪代码
4.1. MMoE 的最大亮点
最大亮点:每个任务拥有独立的门控(Gate),在共享专家网络的基础上实现了任务级的软参数选择,解决了任务间冲突的问题。
与其他结构的对比
结构 | 特点 | 存在问题 |
---|---|---|
Shared-Bottom | 所有任务共享底层表示 | 容易出现任务间负迁移(任务冲突) |
Hard-parameter sharing | 参数共享硬性强 | 无法适配任务差异 |
MMoE | 多个专家网络 + 多任务门控 | 每个任务根据自身需要“选”专家,任务差异自适应建模 |
4.2. MoE代码示例
# 输入特征
x = input_feature # shape: [batch_size, input_dim]
# 定义多个专家(Expert)网络
experts = [MLP() for _ in range(num_experts)] # 每个 expert 是一个小网络
# 所有专家的输出 shape: [batch_size, num_experts, expert_out_dim]
expert_outputs = [expert(x) for expert in experts]
expert_outputs = stack(expert_outputs, axis=1)
# 为每个任务定义一个独立的门控网络(Gate)
task_outputs = []
for task_id in range(num_tasks):
gate = GateNetwork(task_id)(x) # 输出 shape: [batch_size, num_experts]
gate = softmax(gate, dim=-1) # 获得专家加权权重
# 加权组合专家输出
task_input = sum(gate[:, i] * expert_outputs[:, i] for i in range(num_experts))
# 进入对应任务的 Tower 网络
tower = TowerNetwork(task_id)
task_output = tower(task_input)
task_outputs.append(task_output)
五、选择那些特征进入ShareBottom。
ShareBottom 是一种多任务学习结构,多个任务共享同一个底层网络(Bottom),再接不同的任务塔(Tower)。 所以,输入到共享层的特征选择 非常关键,关系到多个任务的建模质量。
特征选取的核心原则
选择能同时服务多个任务的“通用特征”作为共享输入。
5.1. 全量拼接 + 后续学习筛选(常用)
所有任务的原始特征都拼接输入到底层网络,模型自动通过学习参数筛选出有效特征。
- 优点:最灵活,适配性强。
- 缺点:输入维度大,可能有噪声。
5.2. 交集特征法
- 仅使用多个任务共同依赖的特征,适合任务语义相近(如 CTR 和 CVR)的情况。
- 优点:可减少负迁移
- 缺点:可能丢失部分任务的关键特征
5.3. 手工划分:共享特征 + 特定特征
- 显式划分哪些特征共享,哪些专属。
- 比如:用户画像特征共享,广告ID特征仅用于CTR。
5.4. 特征重要性筛选法(特征打分)
- 单任务先训练模型,计算各特征对多个任务的重要性(如Gini、Gain、SHAP等)。
- 选择对多个任务都 重要 的作为共享特征。