ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

ESM2模型解析:全空间多任务CVR预估解决选择偏差与数据稀疏

ESM2模型解析:全空间多任务CVR预估解决选择偏差与数据稀疏

做推荐系统的同学,对“CVR预估”这个词肯定不陌生。但你如果翻过近几年的工业界论文,会发现大家反复在聊一个痛点:CVR模型往往只在点击样本上训练,上线后却要在曝光样本上做预测,中间隔着一条巨大的“选择偏差”鸿沟。ESM2,也就是 Elaborated Entire Space Supervised Multi-task Model,正是阿里针对这条鸿沟给出的一个相当完整的解法。

我第一次读这篇论文时,第一反应是“这不就是ESMM换个皮吗”——但真把结构图和损失函数逐行看下来,才发现它把“转化”这件事重新拆解了一遍,把用户从曝光、点击、加购到最终购买的全路径信号都揉进了一个多任务模型。这篇论文适合推荐算法工程师、做广告投放策略的同学,以及所有被“CVR样本稀疏”“点击率低导致正样本太少”折磨过的人去读。

这篇文章我会从问题动机开始,把ESM2的结构拆开讲清楚,再给出训练和线上推断时的实操经验。不铺垫太多理论,重点放在“为什么要这么设计”和“真落地时有哪些坑”上。

1. 先看懂ESM2要解决的三个老大难

1.1 CVR预估的两座大山:选择偏差与数据稀疏

任何做电商、广告、内容推荐的算法,最终都要回答一个问题:一个用户看到这个商品/广告后,会不会买?这个概率就是CVR(转化率)。很多团队最初的方案很直接:用“点击过且购买过”的样本训练一个二分类模型,特征用用户、商品、上下文。这个方案在实验评估里看起来还行,一旦上线就露馅。

为什么?因为训练数据只在点击样本里选,而推理时面对的是曝光样本。能点进来的用户本来就是有购买意向的偏置人群,模型在这种人群上拟合出来的概率分布,和全体曝光人群的概率分布完全不是一回事。这就是行业常说的“样本选择偏差”(Sample Selection Bias)。打个比方:你只根据进店的顾客做销售预测,却忽略了更多路过但没进来的人,预测结果当然失真。

另一座山是“数据稀疏”。在一个典型的电商场景里,如果点击率是2%,那么点击样本只有曝光样本的五十分之一。在这2%的点击样本里,能走到成交的又是少数,可能只有百分之几。最后你手里真正的“点击且购买”正样本,往往只剩整个曝光日志的千分之几。这么少的样本,喂给深层神经网络,特征交叉根本学不充分,模型很容易过拟合,或者直接学成一个“只会输出低概率”的保守鬼。

1.2 ESM2的思路:与其硬啃,不如把转化路径拆开

ESM2的聪明之处在于,它不直接去预测“点击后是否购买”这个二分类,而是把“转化”重新定义成一个多阶段事件。用户在电商场景里的行为漏斗大致是:曝光 → 点击 → 加购(或收藏、进店) → 购买(或加购后购买)。中间存在一个常见的中间环节:加购(Add-to-Cart)。

于是“最终买不买”这个事件,可以拆成两类:

  • 点击后直接下单支付;
  • 点击后先加购,之后通过购物车路径完成支付。

从行为依赖上看,第二类是个条件概率链:要先加购,再加购后购买。这样一来,原来那个极度稀疏的“点击→购买”目标,就被拆成了三个密度高得多的子目标:点击→直接购买、点击→加购、加购→购买。每个子目标的正样本数量都远大于最终成交的正样本,信号密度一下子就上来了。这正是“Elaborated”(精细化)这个词的核心含义——不满足于粗颗粒的最终转化,而是把转化过程精细建模出来。

1.3 全空间监督的本质:让模型在曝光空间上计算目标

ESM2名字里还有另一半:“Entire Space Supervised”。这意味着模型的目标函数是在全体曝光样本空间上定义并优化的,而不是只在点击样本上。要做到这一点,关键不是简单地“把所有曝光样本塞进去训练”,而是要构造出一个在数学上成立的目标关系,让曝光样本上也能出现监督信号。

ESM2借用了ESMM的经典套路,用乘法关系把整个漏斗串起来:

pCTCVR = pCTR × pCVR

只要点击概率和转化概率都能从同一条样本链路里拆出来,那么“曝光→成交”的联合概率就有定义。而曝光→成交这个事件,在全曝光样本里是可以观测到的(用户确实买了就能打正标签)。这就在理论上绕开了选择偏差——模型不再只看点击人群,而是在全部曝光人群上做有监督学习。

2. 模型结构拆解:一个网络怎么装下多个转化阶段

2.1 共享Embedding与双塔/多塔设计

ESM2在结构上延续了多任务学习的常见做法:底层是共享的Embedding层,把所有稀疏特征映射成稠密向量;往上分支出不同的任务塔,每个塔负责预测一个子概率。你把它画出来,大概是这样的感觉:

  • 输入层:用户特征、商品特征、上下文特征、交叉统计特征,全部过Embedding。
  • 共享层:多层全连接(MLP),把原始Embedding融合成通用表征。
  • 任务塔:CTR塔(预测点击概率 pCTR)、直接购买塔(预测点击后直接转化概率 pCVR_action)、加购塔(预测点击后加购概率 pCVR_cart)、加购后购买塔(预测加购后购买概率 pCVR_cart_to_purchase)。

每个塔之间不共享上层参数,但底层Embedding是共享的。共享Embedding的好处很实际:加购和购买共有的用户偏好、商品属性,可以在训练中被所有子任务共同强化;即便是某个商品“直接购买”样本很少,但它可能有较多“加购”样本,Embedding照样能学到该商品的表征,这在很大程度上缓解了长尾商品的稀疏问题。

如果你之前实现过ESMM,会发现这套结构和ESMM几乎同源。ESM2真正的变化是塔的数量和任务定义——ESMM只有CTR塔和CVR塔两个头;ESM2把CVR塔拆成了多个指向不同行为路径的头,然后通过概率公式把它们组合起来。

2.2 叠加除法:多个头的概率如何合成

ESM2最核心的公式其实不长。它定义:

pCTCVR = pCTR × (pCVR_action + pCVR_cart × pCVR_cart_to_purchase)

逐个拆:

  • pCTR:曝光后点击的概率;
  • pCVR_action:点击后直接购买的概率;
  • pCVR_cart:点击后加购的概率;
  • pCVR_cart_to_purchase:加购后最终购买的概率。

括号里的内容,本质上是“点击后最终购买”这一事件的全概率分解。用户点击后想买,一共有两条互斥路径:一条是不加购物车直接买,另一条是加购物车后买。两条路径概率相加,就是点击后购买的总概率。你再乘上pCTR,就把“曝光→购买”整条链路打通了。

这里有一个很多人第一次看会疑惑的点:为什么不是直接用 pCTCVR 除以 pCTR 得到 CVR,再用传统交叉熵 loss?这个疑问很关键。因为如果把“除法”直接作为模型输出的组合方式(比如pCVR = pCTCVR / pCTR),那么数值稳定性会很差:当pCTR很小或者预测不准时,除法结果可能爆炸。ESM2的处理是:每个子概率都分别由神经网络输出,再通过乘法/加法组合成最终的pCTCVR;而不是先预测pCTCVR再除。这样所有子任务都在参与优化,而不是让一个“商”承担所有误差。

2.3 损失函数在哪些样本上算?——全空间日志与分空间监督

多任务模型的损失函数通常写成多个交叉熵的加权和。ESM2的损失由四部分组成:CTR预测的损失、点击后直接购买预测的损失、点击后加购预测的损失、加购后购买预测的损失。

关键在于这四个损失作用在不同的样本子集上:

  • CTR损失:全部曝光样本。因为每个样本都有“是否点击”的标签。
  • 直接购买损失:仅在“点击样本”上计算。因为只有点了才有“是否直接购买”的标签。
  • 加购损失:同样仅在“点击样本”上计算。
  • 加购后购买损失:仅在“点击且加购”的样本上计算。

用一句更直白的话说:每个子任务都在它对应的行为空间上有监督信号,但整个模型的总损失依然是在全曝光样本上汇总的。ESM2把“全空间监督”和“分空间子任务监督”统一起来了,这也是它名字中间那个“Elaborated”的又一个体现。

3. 从损失函数到线上推断:ESM2的训练策略怎么落地

3.1 训练样本怎么攒:曝光日志联合行为序列

落地ESM2的第一件事不是写模型结构,而是把训练样本准备好。你需要一个包含完整行为序列的训练集,每条样本至少要有:

  • 曝光时间、曝光位置、上下文信息;
  • 是否点击、点击时间;
  • 是否加购、加购时间;
  • 是否成交、成交时间。

实操里最常见的问题是标签口径不一致。比如“购买”到底定义为下单成功、支付成功还是确认收货?我建议以“支付成功”为最终口径,因为下单可能被取消,确认收货又太慢,支付成功是电商业务中最稳定、最接近实时收入的信号。另外要注意时间窗口:用户点击后30天内购买都算转化,还是15天?窗口太短会漏掉计划性购物,窗口太长会让模型训练样本过期太久。我的经验是先按业务平均转化周期取中位数,比如7天或15天,曝光日志保留3到4个窗口的历史,后面再按实验效果调整。

“直接购买”和“加购后购买”的切分也很关键。严格来说,如果用户点击后先进了购物车再立刻支付,这算哪一类?我建议以“是否发生过加购行为”来切:只要加购过就算加购路径,不管中间间隔多久。这样做的好处是路径互斥,满足概率加法公式的使用前提。

3.2 损失权重:让每个头“均衡发展”

多任务模型一个容易踩的坑是:某个任务Loss占比过大,导致模型只顾那个头,其他头变成了摆设。ESM2的四个子任务样本量差异巨大:CTR有全网曝光日志,直接购买可能只有CTR样本的1%不到,加购后购买更是稀少。

所以实践中要给不同的头设置不同的损失权重。我的默认做法是:把每个头的Loss做“样本量归一化”,即每个样本贡献的Loss先除以该子任务的样本总量,再乘以一个全局权重。这样各头Loss的尺度大致一致,初始全局权重全设1.0也能均衡训练。如果发现某个头(比如加购后购买)依然学不动,就把那一路权重提高,但我最高不超过3.0,再高就容易把共享Embedding带偏。

还有个容易忽略的点:梯度回传。由于最终目标pCTCVR是由多个head通过乘法和加法组合的,CTR head和CVR各个head之间存在梯度路径上的耦合。你会发现CTR和CVR的梯度天然会互相影响,这是ESM2自带的“多任务相互作用”。不要人为地把某个head的梯度完全切断,否则就失去了联合训练的意义。正确的做法是:给不同任务设置梯度缩放系数(Gradient Scaling),控制在0.5到1.5之间微调,而不是粗暴地“停止梯度”。

3.3 线上推断:排序用哪个概率?

训练完成后,线上该用哪个输出做排序?这是每次讲ESM2时都被问到的问题。答案是:看业务目标。

  • 如果你的目标是优化GMV或交易笔数,应该用 pCTCVR 排序,因为它综合了点击概率和购买概率,对应“曝光后的成交期望”。
  • 如果你的目标是在“已点击”的流量内做转化优化,比如某些场景的二次营销,可以用 pCVR_action + pCVR_cart × pCVR_cart_to_purchase,这就是点击后购买条件概率本身。
  • 如果你的产品是购物车催付,那应该用 pCVR_cart_to_purchase 单独排名,把“加购后最可能买”的用户找出来发提醒。

我见过不少团队在这里踩坑:明明场景是首页推荐,却拿单独的pCVR去排,结果CTR权重完全消失,推荐结果偏向“点进来就买的高转化但低兴趣”的商品,整体流量效率反而下降。线上排序前,务必再确认一次你要优化的目标指标,而不是盲目套一个脑内默认值。

在工程实现上,ESM2也不复杂。推理时就是一次前向计算,四个输出头分别算一遍,然后用公式组合。要注意的是,如果希望得到稳定的浮点数,可以提前把pCTCVR的计算放到模型最后一层作为自定义输出节点,而不是在业务代码里做除法——避免pCTR极小时产生数值噪声。

4. 和ESMM相比,ESM2到底“精”在哪里

4.1 一张表看懂ESMM与ESM2的区别

把两篇论文放在一起对比,会发现ESM2不是推翻ESMM,而是把ESMM中“笼统的CVR”精细化成了行为路径上的多个概率。

维度ESMMESM2
模型结构共享Embedding + CTR塔 + CVR塔共享Embedding + CTR塔 + 多个CVR子塔
转化定义点击→购买,单一转化事件点击→直接购买 / 点击→加购→加购后购买
中间行为不显式建模显式建模加购(还可扩展到收藏、进店等)
损失监督空间全曝光空间联合监督全曝光空间损失汇总 + 分行为子空间监督
适用场景转化漏斗较短、中间行为不突出电商等中间行为(加购/收藏)明显的场景

ESMM的价值是“把CVR的全空间监督问题引入了业界”,ESM2的价值则是在此之上把“单点转化”丰富成“过程转化”。如果你的场景没有明显的中间行为,比如一个落地页直接填写表单就完成线索收集,那ESM2的收益不会太明显,ESMM已经足够。但凡是电商、外卖、旅游这种有明显“先加购/收藏,后支付”习惯的场景,ESM2就值得认真试。

4.2 为什么“加购”这个中间行为这么关键

你可能会问:中间行为为什么偏偏选“加购”?因为在所有用户行为里,加购是最接近购买意图的信号。收藏可能只是随便点了个心,进店也可能只是对比价格,唯独“加入购物车”是实际行动,而且平台大多提供了购物车入口,后链路可以继续追踪。

从数据角度看,“点击→加购→购买”这一路径覆盖了大量真实成交。很多场景下,直接下单的GMV占比其实低于加购后成交。如果把加购路径忽略了,就等于只建模了漏斗的一半。ESM2通过剥离一个中间行为,把原本混杂的成交信号分离成了“冲动型成交”和“计划型成交”。这两种成交背后,用户对价格敏感度、决策周期、复购倾向完全不同,分开建模后,特征表达会更有区分度。

更进一步的精细化还可以继续:在加购后,用户可能还会经历“访问购物车”“修改数量”“填写地址”等动作。ESM2论文中把这个框架表达成一种可扩展的模式,理论上每一层中间行为都可以继续分化。不过实操上不建议无限细化,因为分支越多,样本在每个分支上又会被切薄,而且线上维护成本直线上升。一般拆到“加购”这一层,性价比是最高的。

5. 实操避坑:样本、标签、调参的常见问题

5.1 常见问题速查表

这里把我见过的ESM2落地问题整理成表,每一条都是踩过的坑:

问题现象可能原因解决办法
线上pCTCVR排序效果不如pCTR业务目标其实是点击或互动,而非成交重新确认业务指标,选择正确的输出头
联合训练后CTR AUC下降很多多任务梯度冲突,共享底层被CVR任务带偏调低CVR各头损失权重,或对CTR塔单独加浅层
加购后购买分支基本不变正样本太少,或该路径业务占比本来就低检查加购后成交占比,如果低于10%可先忽略该分支
pCTCVR数值整体偏高/偏低训练数据时序穿越或标签口径漂移检查特征是否用了未来信息,标签时间窗口是否统一
模型在冷启动商品上预测很差共享Embedding没有冷启机制增加统计特征、图片/文本向量作为冷启补充
训练耗时暴增全曝光样本量是点击样本的50到100倍对曝光负样本降采样,保持CTR正样本全量

其中“曝光负样本降采样”是小技巧里最实用的一条。CTR任务用全曝光样本训练确实严格,但工业场景曝光日志体量大,没必要把所有曝光数据都端进去。我建议对“未点击”样本做随机降采样,采样比按计算资源和数据量取1:10到1:20,同时把CTR损失权重乘上一个“采样补偿系数”,也就是负样本的真实占比除以采样后占比。这样算出的CTR概率依然接近真实点击率,而训练速度可以快一个量级。

5.2 几条我个人的经验心得

第一,不要把ESM2当成一个“模型”,而要当成一个“建模范式”。ETL、标签、训练、上线,每个环节都要围绕“全空间+多路径”重新设计。很多团队直接把ESMM的代码改几个输出头,样本还是只取点击后的数据,那ESM2的好处完全发挥不出来。

第二,特征工程的重点要放在“区分两条购买路径”。比如“用户历史加购次数”“平均加购到支付间隔”“加购后是否频繁访问购物车”等特征,对直接购买分支和加购后购买分支有截然不同的含义。这类行为序列特征,往往比单纯的价格、品类特征提升更明显。

第三,线上服务阶段,模型文件一定要包含所有输出头,不要为了减小体积把CVR子塔剪掉。我遇到过有同学为了省推理时间,只保留CTR头和CVR总括头,结果后续想切换pCVR_cart_to_purchase做购物车催收时,还得重新部署一个新模型。ESM2的推理开销并没有比ESMM大多少,一次前向计算四个头,耗时通常增长不到10%,完全划得来。

我在实际落地ESM2时,最喜欢的一点是它的“路径可解释性”。过去调CVR模型,遇到预测值异常,只能模糊地归因到“特征分布变了”;现在可以直接看是点击概率掉了、加购概率掉了,还是加购后转化掉了。这种透明度,让算法和业务方的沟通顺畅了很多——业务说你最近推荐效果变差,你可以直接把漏斗环节的数据拉出来对照,问题出在哪一目了然。

如果你正在电商、生活服务或者任何“中间行为存在感强”的场景里做转化建模,ESM2是一个非常值得投入的基准模型。至少先实现一版和ESMM做对比,你会很快看见精细化漏斗建模带来的增量。

返回列表