步行街的尽头,阿东开了一家奶茶店。他每天会想三件事:有多少人从橱窗前经过?有多少人推门进来?又有多少人掏钱买单?经过的叫曝光,进门的叫点击,买单的叫转化。这三个数字一层层变少,像一只漏斗。阿东过去只在“已经进门”的客人身上记笔记——谁爱加珍珠、谁点半糖——但他渐渐发现,这套笔记拿去预测街上所有路人时总是失准:因为进门的客人本来已经“偏好这家店”了,用他们的口味代表所有路人,自然有偏;更何况一天进店的人本来就不多,真正买单的更是寥寥几个,笔记薄得可怜。ESMM 就是一篇教算法“站在整条街上思考”的论文:它让两个店员——一个管门口(CTR 塔)、一个管柜台(CVR 塔)——共享同一套“识人眼光”(Embedding),用“既进门又买单”这个能数清的事件,巧妙地反推出“进门之后会买单”的概率。本文就用阿东的奶茶店,把 ESMM 从直觉到公式、从论文到工程一次讲透。
掌握 ESMM,你就掌握了推荐系统“曝光→点击→转化”全漏斗建模的核心范式——这是大厂推荐与广告算法岗的高频考点,也是多任务学习落地的经典范例。
目录
可视化演示
展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。
本节配有交互动效(进入视口后自动加载,约 3KB)。
系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T
问题背景:奶茶店的“两本账”
阿东发现,自己手里有两本完全不同的账:一本记“今天有多少人从橱窗前走过”,另一本记“进店的人里谁买了什么”。他本能地想——想知道谁会买单,那就盯着进店的人研究呗。于是他每天站在吧台后面,把进店客人的口味特征记录在案,用这些笔记训练自己的“直觉”。可这套直觉上了街就失灵:街上大部分路人根本没进过店,阿东的笔记里根本没有他们的影子。
在推荐系统里,阿东的“两本账”就是曝光日志与点击日志。推荐系统向用户展示商品叫曝光,用户点击商品叫点击,点击后完成购买(或安装、注册等)叫转化。CTR 模型预估“用户看到后会点击的概率”,CVR 模型预估“用户点击后会转化的概率”。传统 CVR 模型的做法,恰好就是阿东的旧习惯——只用点击样本训练,于是埋下两个隐患。
第一个隐患叫样本选择偏差:模型只在“已经点击”的人群上学习,却要拿去预测“所有曝光”的人群,相当于拿进店客人的口味去猜街上路人的口味,系统性跑偏。第二个隐患叫数据稀疏:转化本身是漏斗最底部的极端事件,一天下来真正的买单一双手数得过来,训练样本少得可怜,模型很难学稳。更麻烦的是,CTR 和 CVR 若各训各的,就像门口店员和柜台收银员互不交流,白白浪费了二者共享的“行人特征”。
阿东拿着那本只有进店客人笔记的小册子,站在街口发了愁。他知道,想要当好老板,必须换一种记账方式:把整条街都纳入视野。
- 点击变量 $y$$y$ 表示用户是否点击,$y=1$ 代表这次曝光发生了点击,它是推荐系统里最容易观测的事件。
- 转化变量 $z$$z$ 表示用户是否转化(购买),$z=1$ 代表发生了转化;转化通常只在点击之后才可能发生。
- 特征向量 $\boldsymbol{x}$$\boldsymbol{x}$ 是用户、商品、场景三类特征拼接而成的向量,用来描述“谁在什么场景下看到了什么”。
- 左边点击条件下的转化概率:$p(z=1 \mid y=1, \boldsymbol{x})$ 是“点击了的人”中转化比例,这正是传统 CVR 模型在点击样本上拟合的目标。
- 右边全空间转化概率:$p(z=1 \mid \boldsymbol{x})$ 是所有曝光样本上的转化比例,这才是推荐系统真正想要预估的量。
- 两者不相等点击人群是曝光人群的“筛选子集”,分布不一致导致两边概率天然不同——这就是样本选择偏差的数学刻画。
全空间建模:把计数器装到门口
阿东决定改革。他在橱窗旁装了一个感应计数器,能数清每一个经过的行人;又在收银台接上联动设备,记录“谁进门、谁买单”。这样一来,他的视野不再局限于店内,而是覆盖了整条街——这正是 ESMM 的核心思想:全空间建模,把 CVR 的训练从“点击子空间”搬到“曝光全空间”。
直接在全空间上训练 CVR 有一个绕不开的难题:没点击的人根本不可能产生转化,你无法给每个曝光样本打上“转化/未转化”的标签。阿东也明白,他没法知道街上每个没进店的人会不会买。但聪明的老板立刻发现:有一个事件是全空间可观测的——“这个人既进了店、又买了单”。于是他把目标从“进店后买单率”悄悄换成了“又进店又买单率”(pCTCVR),再借助概率论的乘法法则,把这个联合事件拆成 “进店率 × 进店后买单率”。
这就是 ESMM 的关键一步:它并不直接预测 CVR,而是先在全空间上学习“又点击又转化”的联合概率,再通过除法关系反推 CVR。数学上,只要两个子模型——pCTR 模型与 pCVR 模型——相乘能还原 pCTCVR,那么对全空间样本的监督就会同时约束两个子模型,CVR 模型便间接地“看到了”所有曝光样本,样本选择偏差从根上被消除,数据稀疏也因为全空间样本的注入而缓解。
阿东的感应计数器第一次让他看清了整条街的全貌。现在的问题只剩一个:门口店员和柜台收银员,如何分工协作,才能把这两项概率同时估准?
- 联合事件“点击且转化”$p(z=1, y=1 \mid \boldsymbol{x})$ 表示在特征 $\boldsymbol{x}$ 下,用户“既点击又转化”的概率,记为 pCTCVR,它在曝光日志里可以直接统计。
- $p(y=1 \mid \boldsymbol{x})$ 是 pCTR曝光后点击的概率,由 CTR 塔负责估计,训练标签就是“是否点击”。
- $p(z=1 \mid y=1, \boldsymbol{x})$ 是 pCVR点击后转化的概率,由 CVR 塔负责估计,这正是我们想要的转化率。
- 乘法法则联合概率等于边缘概率乘以条件概率,这是概率论的链式法则,也是 ESMM 乘积结构的来源。
- 关键洞察等式左边全空间可观测,右边第一项也有全空间标签(是否点击),于是右边第二项 pCVR 就能被间接约束——不需要每个曝光样本都有转化标签。
网络结构:共享地基的双层小楼
阿东给店里设计了一套“双层小楼”:一楼是共享地基,二楼是两个各司其职的塔。地基里存放着他对每位客人的基础认知——年龄、穿着、步速、逛街时段——这些信息对“会不会进店”和“进店后买不买”都有用。在 ESMM 中,这个地基就是共享 Embedding 层:用户、商品、场景特征被映射成稠密向量,CTR 塔和 CVR 塔共用同一份向量作为输入。
二楼的两座塔结构相似,但分工不同。CTR 塔像门口的迎宾员,拿着地基里的特征向量,判断“这位路人有多大概率进店”;CVR 塔像柜台的收银员,拿着同样的特征向量,判断“这位进店的客人有多大概率买单”。两座塔都是多层全连接网络(MLP),内部通过非线性激活函数完成特征交互——把用户特征、商品特征、场景特征的组合关系充分交叉,最终各自输出一个 0 到 1 之间的概率。
为什么必须共享 Embedding 而不是各学各的?因为转化样本太少,CVR 塔单独学 Embedding 几乎学不动;而点击样本丰富,CTR 塔能把地基“磨”得很精细。共享之后,CTR 塔磨好的地基直接供 CVR 塔使用,CVR 塔等于站在巨人的肩膀上——这正是多任务学习“任务互帮”的精髓。
地基共享、双塔分立的格局定下来了。但阿东还有一笔账没算清楚:收银员的“买单概率”到底怎么从“进店又买单”这个联合事件里反推出来?
- 共享嵌入 $\boldsymbol{e}_i$第 $i$ 个样本的用户、商品、场景特征经过 Embedding 层后得到稠密向量 $\boldsymbol{e}_i$,CTR 塔与 CVR 塔共用。
- 第一层全连接 $\boldsymbol{W}_1, \boldsymbol{b}_1$把嵌入向量投影到隐层空间,提取高阶交互特征。
- 第二层全连接 $\boldsymbol{W}_2, b_2$把隐层向量压缩成一个实数,作为“原始打分”。
- Sigmoid 激活 $\sigma$把任意实数映射到 $(0,1)$ 区间,得到概率含义的输出。
- CTR 塔同构CTR 塔结构完全相同、参数独立,只是输入同样的共享嵌入、输出各自任务对应的概率。
数学原理:一笔账串起两个概率
阿东在收银台贴了一张纸条:“进店且买单的概率 = 进店率 × 进店后买单率。”这句话看起来像废话,却是 ESMM 的灵魂。它意味着:模型不需要直接输出“进店后买单率”(这个数在没点击的样本上无标签、没法直接学),而是让两个塔的输出相乘,去拟合“进店且买单”这个全空间可观测的事件。
训练时,ESMM 同时优化两个损失。第一个是 CTR 损失:把 CTR 塔的输出 $\hat{p}^{CTR}$ 与全空间的点击标签 $y$ 做交叉熵或平方损失,监督“进店率”估得准不准。第二个是 CTCVR 损失:把两个塔输出的乘积 $\hat{p}^{CTR} \cdot \hat{p}^{CVR}$ 与全空间的联合标签 $y \cdot z$(点击且转化才是 1)做损失,监督“进店且买单率”估得准不准。两个损失相加,就是 ESMM 的总损失。
为什么这样设计就能反推 CVR?因为 CTCVR 损失同时牵动了两个塔:当乘积偏离真实联合概率时,梯度会同时流向 CTR 塔和 CVR 塔。经过充分训练后,只要 CTR 塔估得足够准,CVR 塔就必须“凑”出正确的 CVR,才能让乘积对得上全空间的联合标签。于是,CVR 塔虽然从没直接见过“曝光未点击”样本的转化标签,却通过乘积关系得到了全空间的无偏监督。
阿东把这张纸条贴在收银台后,两个店员的工作一下子有了交集:迎宾员的判断影响收银员的学习,收银员的偏差也会反馈给迎宾员。那么,这笔账在训练时具体是怎么“算”的?
- 全空间样本集 $\mathcal{D}$所有曝光样本的集合,既包含点击的样本,也包含大量未点击的样本——这是 ESMM 与旧方法最大的区别。
- 第一项 CTR 损失$\hat{p}^{CTR}_i$ 与点击标签 $y_i$ 计算损失,让 CTR 塔在全空间上学会预估点击率。
- 联合标签 $y_i \cdot z_i$只有“既点击又转化”的样本标签为 1,其余全为 0;这个标签在曝光日志中可以直接标注。
- 第二项 CTCVR 损失$\hat{p}^{CTR}_i \cdot \hat{p}^{CVR}_i$ 与联合标签计算损失,监督两个塔的乘积逼近真实的联合概率。
- 两项相加联合训练总损失由 CTR 损失与 CTCVR 损失相加构成,两个任务在共享 Embedding 上互相传递信息。
训练优化:老师傅带新徒弟
阿东把 CTR 塔比作老师傅,CVR 塔比作新徒弟。老师傅阅人无数,眼光老辣;新徒弟刚上手,看谁都像会买单的。徒弟怎么学?不是只站在柜台里等进店客人,而是每看到一个路人从街口走过,就要根据老师傅的判断(pCTR)来校正自己的猜测:这个人大概率不会进店,但他若真进了店,买不买?这样,每一个曝光样本——哪怕那人根本没进店——都在给徒弟提供“这人不买”的反馈,徒弟的练习量瞬间从“一天几十个进店客人”扩大到“每天上千个路人”。
机制上,这是通过梯度传播实现的。CTCVR 损失对 CVR 塔参数的偏导,中间会乘上一个 $\hat{p}^{CTR}$ 因子——可以理解为每个样本的“反馈强度”由 CTR 塔来加权:CTR 塔越有把握的样本,对 CVR 塔的修正力度越大。反过来,CTCVR 损失也会通过 $\hat{p}^{CVR}$ 因子把梯度传回 CTR 塔,让迎宾员也兼顾“最终买单”这个更远的目标。两个塔在训练中互相带教,共享 Embedding 层则同时收到两份梯度,像地基同时承受两层楼的承重一样。
实操层面还有几个收敛技巧。一是防止过拟合:CVR 塔参数多但有效样本少,通常给 CVR 塔加 Dropout,或用较小的学习率;二是损失权重:CTR 损失和 CTCVR 损失量级不同,可加权重系数平衡;三是 Embedding 维度:太大容易过拟合、太小表达不足,常见经验是 8~32 维起步;四是联合训练初期可先让 CTR 塔“预热”几个 epoch,再放开双塔联合优化,像老师傅先示范几天再放手让徒弟实操。
阿东看着徒弟一天天进步,心里踏实了:训练方法理顺了,接下来就是把这套“双层小楼”真正开成连锁店——从单店经营走向规模化部署。
- 链式法则CTCVR 损失对 CVR 塔参数的梯度,必须穿过“乘积”这个中间环节,按链式法则逐层展开。
- 乘积因子 $\hat{p}^{CTR}_i$因为 pCTCVR 对 pCVR 求偏导等于 pCTR,所以每个样本的梯度都乘上 CTR 塔的输出,作为权重。
- 全空间求和求和遍历所有曝光样本 $\mathcal{D}$,未点击样本的联合标签为 0,同样贡献梯度——这正是全空间训练的数学体现。
- 无偏性所有曝光样本按 pCTR 加权后参与 CVR 塔更新,训练分布就是推理分布,选择偏差随之消失。
- 双向带教同理,CTCVR 损失对 CTR 塔的梯度也会乘上 $\hat{p}^{CVR}$ 因子,两个塔在联合损失下互为对方的“老师”。
工程实践:从单店到连锁经营
阿东要开分店了。他总结了一套巡店手册,第一条是特征工程。地基里放什么特征,直接决定双塔的上限:用户画像特征(年龄、性别、历史消费水平)、商品特征(品类、价格、销量)、场景特征(时段、位置、设备),以及统计特征(商品近 7 天点击率、转化率等)。这些特征经过 Embedding 进入共享地基,CTR 塔和 CVR 塔都在其上做特征交互。
第二条是调参经验。除了上一节提到的 Dropout、学习率与 Embedding 维度,实际工程中还要关注样本拼接方式:曝光日志、点击日志、转化日志需要按时间窗口对齐,转化标签通常延迟到达,要设置合理的“转化等待窗口”(如 24 小时)。训练时建议先离线复现基线(单独训练的 CTR 与 CVR),再切换到 ESMM 联合训练,观察两个任务的 AUC 是否同步提升。
第三条是线上部署。模型训练完成后需要导出为线上服务格式,推荐系统中的排序链路通常先召回、再粗排、最后精排,ESMM 一般担任精排角色:线上同时计算 $\hat{p}^{CTR}$ 与 $\hat{p}^{CVR}$,再用乘积或加权组合得到最终排序分。由于两个塔共享 Embedding,一次前向计算即可同时得到两个概率,推理成本只比单任务略高,性价比很高。
第四条是离线评估。单任务常用 AUC,但推荐场景用户偏好差异巨大,业界更常用 GAUC——按用户分组算 AUC 再加权平均,能更公平地反映排序质量。ESMM 上线前要同时盯 CTR 任务的 AUC、CVR 任务的 AUC,以及 pCTCVR 的校准度(预测均值与真实转化率是否一致),避免“CTR 提升、CVR 反而崩坏”的跷跷板问题。
阿东的连锁店开到了第 20 家,每家都有一套标准化的“整条街统计 + 双塔协作”体系。他站在新店门口,看着街上川流不息的行人,终于明白:真正的好生意,从来不是只盯着进店的人,而是看清整条街。
- 用户集合 $\mathcal{U}$评估数据中的全部用户,GAUC 的核心思想是“按人分别算账”。
- 单用户 AUC $AUC_u$对每个用户 $u$,只看他自己的曝光样本,计算模型排序能力的 AUC。
- 权重 $w_u$通常取该用户的曝光次数,让活跃用户的排序质量在总指标中占更大权重。
- 加权平均所有用户的 AUC 按曝光量加权求和再归一化,得到全局 GAUC。
- 为什么要分组不同用户点击习惯差异大,全局 AUC 容易被“高活跃用户”主导,GAUC 能更公平地评估真实推荐效果。
AI 应用场景
电商平台“猜你喜欢”的成交率优化
阶段:精排模型设计
解决的问题:传统 CVR 模型只用点击样本训练,导致预测值对未点击商品系统性偏高;同时,转化样本稀疏让模型学不稳。ESMM 在全部曝光商品上联合建模,把“曝光→点击→成交”作为整体优化目标,直接服务于成交率(GMV)提升。
具体案例:某头部电商的首页信息流,每天有数十亿次商品曝光。引入 ESMM 后,精排模型以 pCTCVR 作为排序分数,未点击的商品也能通过 CTCVR 损失间接参与 CVR 塔的更新。实验显示,相比“CTR 与 CVR 分别训练再相乘”的基线,成交转化率提升 2%~4%,且 CVR 预测的校准度明显改善。
广告竞价中的转化出价
阶段:出价与拍卖策略
解决的问题:广告主按转化付费(oCPM/CPA)时,平台需要精确预估每次曝光的转化期望值。ESMM 提供的 $\hat{p}^{CVR}$ 比单纯在点击域训练的模型更接近真实转化概率,直接决定出价的合理性与广告主 ROI。
具体案例:某广告平台在信息流广告中部署 ESMM,线上同时输出 pCTR 与 pCVR,出价公式采用 pCTCVR 与广告主出价的乘积。由于 pCVR 在全空间上被校正,广告系统对“高展示、低点击但高转化”的流量识别更准,广告主 ROI 提升 15%,平台填充率同步上升。
内容平台的多目标增长
阶段:多任务学习框架
解决的问题:内容平台关注“曝光→点击→完播/关注/点赞”等多层转化目标,各目标样本量差异巨大。ESMM 的“共享 Embedding + 多塔 + 乘积关联”范式可推广为多目标模型,用主干任务(点击)的特征表达带动稀疏目标(关注、分享)的学习。
具体案例:某短视频 App 在推荐精排中采用类 ESMM 结构:主塔预估点击率,辅塔预估“点击后关注”率,二者乘积拟合“点击且关注”的联合事件。上线后关注转化率提升 5%,且冷门创作者的视频由于共享特征表达,也能获得更合理的关注率预估。
Python 演示
"""ESMM-Lite: 用 numpy 实现 ESMM 核心思想(共享嵌入+双塔+全空间联合损失)"""import numpy as np def sigmoid(x): x = np.clip(x, -30, 30) return 1.0 / (1.0 + np.exp(-x)) class ESMMLite(object): """迷你ESMM: 共享Embedding, CTR塔与CVR塔输出相乘得到pCTCVR""" def __init__(self, n_feat, dim=8, hid=16, seed=42): rng = np.random.RandomState(seed) self.e = rng.randn(n_feat, dim) * 0.1 # 共享底层 Embedding self.wc = rng.randn(dim, hid) * 0.1 # CTR 塔 self.bc = np.zeros(hid) self.vc = rng.randn(hid) * 0.1 self.cc = 0.0 self.wv = rng.randn(dim, hid) * 0.1 # CVR 塔 self.bv = np.zeros(hid) self.vv = rng.randn(hid) * 0.1 self.cv = 0.0 def _tower(self, x, W, b, v, c): h = np.tanh(self.e[x] @ W + b) return sigmoid(h @ v + c), h def train(self, X, yc, yb, lr=0.2, epochs=30): for ep in range(epochs): loss = 0.0 for x, c0, z in zip(X, yc, yb): pc, hc = self._tower(x, self.wc, self.bc, self.vc, self.cc) pv, hv = self._tower(x, self.wv, self.bv, self.vv, self.cv) pt = pc * pv # pCTCVR = pCTR * pCVR seg = (pc - c0) + (pt - c0 * z) * pv # CTR塔梯度(点击损失+pCTCVR损失) dc = seg * pc * (1 - pc) self.vc -= lr * dc * hc self.cc -= lr * dc self.wc -= lr * np.outer(self.e[x], dc * (1 - hc * hc)) self.bc -= lr * dc * (1 - hc * hc) dg = (pt - c0 * z) * pc * pv * (1 - pv) # CVR塔梯度(经pCTR加权) self.vv -= lr * dg * hv self.cv -= lr * dg self.wv -= lr * np.outer(self.e[x], dg * (1 - hv * hv)) self.bv -= lr * dg * (1 - hv * hv) loss += abs(pt - c0 * z) if ep % 10 == 0: print('epoch %d: 平均pCTCVR误差=%.4f' % (ep, loss / len(X))) def predict(self, x): pc, _ = self._tower(x, self.wc, self.bc, self.vc, self.cc) pv, _ = self._tower(x, self.wv, self.bv, self.vv, self.cv) return pc, pv def make_data(n=2000, seed=1): """构造曝光全空间样本: X为特征, yc为点击标签, yb为转化标签(仅点击后可发生)""" rng = np.random.RandomState(seed) X = rng.randint(0, 50, n) yc = (rng.rand(n) < sigmoid((X - 25) / 8.0)).astype(int) yb = ((yc == 1) & (rng.rand(n) < sigmoid((X - 30) / 10.0))).astype(int) return X, yc, yb if __name__ == '__main__': X, yc, yb = make_data() print('曝光=%d, 点击=%d, 转化=%d' % (len(X), yc.sum(), yb.sum())) m = ESMMLite(n_feat=50) m.train(X, yc, yb, epochs=30) for x in [10, 25, 40]: pc, pv = m.predict(x) print('样本%d: pCTR=%.2f, pCVR=%.2f, pCTCVR=%.3f' % (x, pc, pv, pc * pv))
self.e = rng.randn(n_feat, dim) * 0.1初始化共享底层 Embedding,CTR 塔与 CVR 塔都从它取特征;pc, hc = self._tower(x, self.wc, self.bc, self.vc, self.cc)CTR 塔前向传播,输出点击概率;pt = pc * pvESMM 核心一行:pCTCVR 等于 pCTR 乘 pCVR;seg = (pc - c0) + (pt - c0 * z) * pvCTR 塔同时收到点击误差与 pCTCVR 误差,体现了联合训练的双向带教;dg = (pt - c0 * z) * pc * pv * (1 - pv)CVR 塔的梯度被 pCTR 加权,所有曝光样本(包括未点击)都在更新 CVR 塔;yb = ((yc == 1) & (rng.rand(n) < sigmoid((X - 30) / 10.0))).astype(int)转化只在点击后发生,人为构造漏斗结构,模拟真实场景的稀疏性;if ep % 10 == 0: print(...)每 10 轮打印一次平均 pCTCVR 误差,观察全空间联合损失是否在下降。
常见误区
误区转化本来就是“点击之后”才发生的事,所以训练 CVR 模型当然要用点击样本,不用点击样本用什么?
正解训练样本的分布必须与推理时的分布一致。CVR 模型上线后要对所有曝光商品打分,可训练时只看点击样本,相当于奶茶店老板只研究进店客人的口味,却要预测街上所有路人的口味——这就是样本选择偏差。正确做法是像 ESMM 一样把训练搬到曝光全空间,用 pCTCVR 反推 CVR。
为何常见:人们容易把“转化的定义依赖点击”误解为“训练的数据也依赖点击”,忽略了训练与推理分布一致性这条机器学习的基本纪律。
误区先训练一个 CTR 模型,再训练一个 CVR 模型,线上把两个概率相乘,这不就是 ESMM 吗?
正解ESMM 的灵魂是联合训练:两个塔共享 Embedding,CTCVR 损失同时反向传播到两个塔,CVR 塔因此能利用全空间样本。而“分别训练再相乘”的 CVR 模型仍然只在点击样本上训练,偏差依旧存在,共享信息也没有被利用——只是换了层皮,没换内核。
为何常见:因为 ESMM 的线上推理形式就是“两个概率相乘”,初学者容易把“推理时的乘积”误当成“训练时的联合”,忽略了模型结构层面的差异。
误区既然 pCTCVR 在全空间可观测,那直接训练一个模型去拟合“点击且转化”这个标签,不也能用到全空间数据吗?何必拆成两个塔?
正解直接建模 pCTCVR 确实用到了全空间,但它只能给出“又点击又转化”的概率,无法分解出我们要的 pCVR。推荐系统排序需要的是 pCTR、pCVR 各自的估计,用于不同的业务目标(如 pCVR 用于广告出价)。ESMM 通过乘积结构在拟合 pCTCVR 的同时分离出两个子概率,一举两得。
为何常见:人们容易把“建模目标”与“业务需要”混为一谈,以为只要损失能下降就够了,忽略了模型输出必须服务于具体的业务决策。
误区ESMM 证明两个任务互相帮助效果很好,那我加上关注、收藏、分享、加购等一堆任务,模型一定更强。
正解多任务学习存在“跷跷板效应”:任务之间相关性弱时,共享参数反而互相干扰,导致部分任务指标下降。ESMM 的成功建立在 CTR 与 CVR 天然强相关(同一漏斗上下游)之上。实际工程中需要先做任务相关性分析,必要时用任务特定网络或动态权重来隔离冲突。
为何常见:看到“多任务”就以为“多多益善”,忽略了任务相关性这个前提条件,属于把个例成功泛化成了普遍规律。
面试题
Q1. ESMM 中 CVR 任务在哪个样本空间上训练?
- A.点击样本空间
- B.曝光全空间← 正确答案
- C.转化样本空间
- D.购买用户空间
答案:B。ESMM 的核心是全空间建模,CVR 任务通过 pCTCVR 的联合损失在曝光全空间上间接学习。若只在点击样本空间训练,就会重蹈样本选择偏差的覆辙;转化样本空间与购买用户空间样本更少,都不符合 ESMM 的设计。
Q2. 传统 CVR 模型的主要问题是什么?
- A.模型参数量大且不易训练
- B.样本选择偏差与数据稀疏← 正确答案
- C.线上推理延迟高且难部署
- D.特征工程复杂且维护成本高
答案:B。传统 CVR 模型只在点击样本上训练,推理时却要对全部曝光样本打分,训练与推理分布不一致,这是样本选择偏差;同时转化事件占比极低,训练样本稀疏。这两个问题才是 ESMM 要解决的核心痛点。
Q3. pCTCVR、pCTR、pCVR 三者满足什么关系?
- A.pCTCVR = pCTR + pCVR
- B.pCTCVR = pCTR × pCVR← 正确答案
- C.pCTCVR = pCTR − pCVR
- D.pCTCVR = pCVR ÷ pCTR
答案:B。根据概率论的乘法法则,“点击且转化”的联合概率等于“点击”概率乘以“点击后转化”的条件概率,即 pCTCVR = pCTR × pCVR。ESMM 正是利用这个乘积结构,用全空间可观测的 pCTCVR 反推点击域内的 pCVR。
Q4. ESMM 中 CTR 塔与 CVR 塔的结构关系是什么?
- A.完全独立无共享参数联系
- B.共享底层嵌入且输出相乘关联← 正确答案
- C.共享全部网络层与输出参数
- D.共用同一份损失与训练标签
答案:B。两个塔各自是独立的 MLP,但它们共享底层 Embedding,且输出通过乘法组成 pCTCVR 参与联合损失。完全独立会丢失多任务共享信息,共享全部参数则无法输出两个不同的概率,共用同一损失更无从谈起。
Q5. ESMM 如何解决样本选择偏差问题?
- A.对点击样本做随机欠采样
- B.在全空间建模并反推转化率← 正确答案
- C.仅扩展点击样本的特征维度
- D.对转化样本重复采样增广
答案:B。ESMM 把训练目标从“点击域内的 CVR”改为“曝光全空间上的 pCTCVR”,让 CVR 塔通过全空间样本的联合损失间接获得无偏监督。欠采样、特征扩展、过采样都只是操作数据,没有改变训练分布与推理分布不一致的根源。
Q6. ESMM 的总损失函数由哪些部分构成?
- A.联合使用CTR损失与CTCVR损失← 正确答案
- B.仅使用CVR损失单独训练模型
- C.仅使用CTR损失单独训练模型
- D.直接使用曝光次数作为损失函数
答案:A。ESMM 的损失是两项相加:CTR 塔在全空间点击标签上的损失,加上两个塔乘积与“点击且转化”联合标签的 CTCVR 损失。只用 CTR 或只用 CVR 损失都无法实现双塔联合优化,曝光次数根本不是监督信号。
Q7. 在 ESMM 中,CVR 塔是如何在曝光全空间上被训练的?
- A.通过 pCTCVR 损失的梯度传播← 正确答案
- B.直接使用转化标签做全空间监督
- C.仅在点击样本上做反向传播更新
- D.由 CTR 塔的输出直接复制得到
答案:A。未点击样本没有转化标签,无法直接监督 CVR 塔。ESMM 的巧妙之处是让 pCTCVR 损失对 CVR 塔参数求梯度,经过乘积链式法则后,每个曝光样本(包括未点击)都按 pCTR 加权贡献一份梯度,从而在无转化标签的情况下实现全空间训练。
Q8. 以下哪些属于 ESMM 的关键设计?
- A.共享底层 Embedding 参数← 正确答案
- B.损失定义在曝光全空间之上← 正确答案
- C.用乘积关系分解 pCTCVR← 正确答案
- D.特征工程与模型结构无关
答案:ABC。共享 Embedding、全空间损失、乘积分解是 ESMM 三大支柱。特征工程当然重要,但“与模型结构无关”的说法错误——ESMM 恰恰通过结构设计放大了特征表达的价值。
Q9. 关于 ESMM 的梯度传播,下列说法正确的有哪些?
- A.CTCVR 损失经 pCTR 加权回传 CVR 塔← 正确答案
- B.CTR 塔只受点击标签损失监督
- C.共享 Embedding 接收双任务梯度← 正确答案
- D.CVR 塔只在点击样本上更新
答案:AC。CTCVR 损失对 CVR 塔的梯度要乘以 pCTR 因子,A 正确;CTR 塔同时收到点击损失与 CTCVR 损失(经 pCVR 加权)的梯度,B 错误;共享 Embedding 汇聚两个塔的梯度,C 正确;CVR 塔通过全空间上的 pCTCVR 损失更新,D 错误。
Q10. 推荐系统中“曝光→点击→转化”漏斗的环节包括哪些?
- A.曝光环节展示给用户← 正确答案
- B.点击环节用户点击商品← 正确答案
- C.转化环节用户完成购买← 正确答案
- D.退款环节用户申请退款
答案:ABC。漏斗的三个核心环节是曝光、点击、转化,CVR 模型关注的就是“点击后转化”这一跳。退款发生在转化之后,不属于漏斗前置环节,也不是 CVR 建模的目标。