ESMM学习笔记:如何解决CVR预估中的样本选择偏差与数据稀疏难题

发布时间:2026/9/13 7:11:57

ESMM学习笔记:如何解决CVR预估中的样本选择偏差与数据稀疏难题 ESMM学习笔记如何解决CVR预估中的样本选择偏差与数据稀疏难题引言CVR预估的两大挑战在推荐系统和广告点击率预估领域CVRConversion Rate转化率预估是一个核心任务。与CTRClick-Through Rate点击率预估不同CVR预估面临两个特殊的难题1.样本选择偏差Sample Selection BiasSSBCVR模型通常只在点击样本上训练但实际预测时需要对所有曝光样本进行预估。点击样本和未点击样本在用户行为模式上存在显著差异导致训练集和预测集的分布不一致模型泛化能力下降。2.数据稀疏Data SparsityDS转化行为远比点击行为稀少导致CVR训练样本数量远少于CTR。在广告场景中点击率可能只有1%-5%而转化率可能只有0.1%-0.5%这意味着CVR模型可用的正样本极其有限容易过拟合。为了解决这两个问题阿里巴巴在2018年提出了ESMMEntire Space Multi-Task Model全空间多任务模型。本文将循序渐进地讲解ESMM的原理与实现。## 基础概念从CTR预估到CVR预估### CTR预估与CVR预估的关系在电商或广告系统中用户行为通常遵循一个漏斗模型曝光Impression → 点击Click → 转化ConversionCTR预估关注的是给定曝光样本用户点击的概率 P(click1|impression)。CVR预估关注的是给定点击样本用户转化的概率 P(conversion1|click1)。传统方法中CVR模型只在点击样本上训练这就导致了样本选择偏差问题——模型从未见过未点击样本的特征分布却在预测时需要对它们进行推断。### 多任务学习的思想ESMM的核心思想是将CVR预估和CTR预估作为两个相关任务联合训练。既然点击和转化是顺序发生的那么我们可以利用CTR任务中丰富的点击样本信息来辅助CVR任务。具体来说ESMM引入了一个辅助任务——CTCVRClick-Then-Conversion Rate点击后转化率即 P(click1, conversion1|impression)。通过全空间所有曝光样本上的CTCVR预估间接学习CVR。## ESMM模型架构详解ESMM的模型架构包含以下几个关键部分1.共享嵌入层Shared Embedding Layer将高维稀疏特征映射到低维稠密向量。2.两个独立的塔Two TowersCTR塔和CVR塔分别用于预估CTR和CVR。3.乘积层Multiplication Layer通过CTR和CVR的乘积得到CTCVR的预估值。关键公式- CTR预估pCTR P(click1|impression)- CVR预估pCVR P(conversion1|click1)- CTCVR预估pCTCVR P(click1, conversion1|impression) pCTR × pCVR训练时我们用全空间样本包括未点击和点击来优化CTCVR损失和CTR损失而CVR损失则通过反向传播间接优化。## 代码实现从零构建ESMM下面我们实现一个简化版的ESMM模型。首先我们使用TensorFlow 2.x来构建模型。### 示例1模型架构定义pythonimport tensorflow as tffrom tensorflow.keras.layers import Dense, Embedding, Flatten, Concatenate, Inputfrom tensorflow.keras import Modelclass ESMM(Model): def __init__(self, feature_columns, embedding_dim8): feature_columns: 字典包含每个特征的类别数 embedding_dim: 嵌入维度 super(ESMM, self).__init__() self.feature_columns feature_columns self.embedding_dim embedding_dim # 共享嵌入层 self.embeddings {} for feat_name, vocab_size in feature_columns.items(): self.embeddings[feat_name] Embedding( input_dimvocab_size, output_dimembedding_dim, namefembedding_{feat_name} ) # CTR塔简单MLP self.ctr_dense1 Dense(64, activationrelu, namectr_dense1) self.ctr_dense2 Dense(32, activationrelu, namectr_dense2) self.ctr_output Dense(1, activationsigmoid, namectr_output) # CVR塔简单MLP self.cvr_dense1 Dense(64, activationrelu, namecvr_dense1) self.cvr_dense2 Dense(32, activationrelu, namecvr_dense2) self.cvr_output Dense(1, activationsigmoid, namecvr_output) def call(self, inputs, trainingFalse): # inputs: 字典每个键对应一个特征值为整数索引 # 共享嵌入 embeddings [] for feat_name in self.feature_columns.keys(): feat_input inputs[feat_name] emb self.embeddings[feat_name](feat_input) embeddings.append(Flatten()(emb)) # 展平为向量 # 拼接所有特征嵌入 concat_emb Concatenate()(embeddings) # CTR塔 ctr_hidden self.ctr_dense1(concat_emb) ctr_hidden self.ctr_dense2(ctr_hidden) ctr_pred self.ctr_output(ctr_hidden) # CVR塔 cvr_hidden self.cvr_dense1(concat_emb) cvr_hidden self.cvr_dense2(cvr_hidden) cvr_pred self.cvr_output(cvr_hidden) # CTCVR CTR * CVR ctcvr_pred ctr_pred * cvr_pred return ctr_pred, cvr_pred, ctcvr_pred# 假设有3个特征用户ID1000个、商品ID500个、广告位ID10个feature_columns { user_id: 1000, item_id: 500, ad_pos: 10}# 创建模型实例model ESMM(feature_columns, embedding_dim8)# 查看模型结构model.build(input_shape({user_id: (None,), item_id: (None,), ad_pos: (None,)}))model.summary()### 示例2训练循环与损失函数在ESMM的训练中我们需要同时优化CTR损失和CTCVR损失。注意CVR损失是基于点击样本的但ESMM巧妙地通过共享嵌入和乘积操作来间接优化。pythonimport numpy as np# 生成模拟数据def generate_synthetic_data(num_samples10000): np.random.seed(42) # 特征用户ID、商品ID、广告位ID data { user_id: np.random.randint(0, 1000, sizenum_samples), item_id: np.random.randint(0, 500, sizenum_samples), ad_pos: np.random.randint(0, 10, sizenum_samples) } # 标签点击5%概率和转化点击后10%概率 click np.random.binomial(1, 0.05, sizenum_samples) conversion np.random.binomial(1, 0.1 * click, sizenum_samples) # 只有点击后才可能转化 return data, click, conversion# 自定义损失函数def ctr_loss(y_true, y_pred): # y_true: [click, conversion] 这里我们只使用click return tf.keras.losses.binary_crossentropy(y_true[:, 0], y_pred[:, 0])def ctcvr_loss(y_true, y_pred): # y_true: [click, conversion] 这里使用conversion因为CTCVRclick conversion return tf.keras.losses.binary_crossentropy(y_true[:, 1], y_pred[:, 0])# 准备数据X, click, conversion generate_synthetic_data(2000)# 构建输入字典input_dict {k: v for k, v in X.items()}# 构建标签第一列是click第二列是conversiony np.stack([click, conversion], axis1)# 编译模型注意TensorFlow需要自定义损失函数optimizer tf.keras.optimizers.Adam(learning_rate0.001)# 训练步骤tf.functiondef train_step(features, labels): with tf.GradientTape() as tape: # 前向传播 ctr_pred, cvr_pred, ctcvr_pred model(features, trainingTrue) # 计算损失 # CTR损失使用点击标签 loss_ctr tf.reduce_mean( tf.keras.losses.binary_crossentropy(labels[:, 0], tf.squeeze(ctr_pred)) ) # CTCVR损失使用转化标签因为转化只发生在点击后 loss_ctcvr tf.reduce_mean( tf.keras.losses.binary_crossentropy(labels[:, 1], tf.squeeze(ctcvr_pred)) ) # 总损失两个损失相加可加权重 total_loss loss_ctr loss_ctcvr # 计算梯度并更新 gradients tape.gradient(total_loss, model.trainable_variables) optimizer.apply_gradients(zip(gradients, model.trainable_variables)) return total_loss, loss_ctr, loss_ctcvr# 训练10个epochfor epoch in range(10): total_loss, loss_ctr, loss_ctcvr train_step(input_dict, y) print(fEpoch {epoch1}: Total Loss {total_loss:.4f}, CTR Loss {loss_ctr:.4f}, CTCVR Loss {loss_ctcvr:.4f})# 训练完成后预测CVR注意只在点击样本上评估更合理import randomtest_sample { user_id: np.array([random.randint(0, 999)]), item_id: np.array([random.randint(0, 499)]), ad_pos: np.array([random.randint(0, 9)])}_, cvr_pred, _ model(test_sample, trainingFalse)print(f预测CVR: {cvr_pred.numpy()[0][0]:.4f})## 高级用法与优化技巧### 多任务学习的权重平衡在ESMM中CTR损失和CTCVR损失的权重可以调整。如果CVR任务特别稀疏可以适当增加CTCVR损失的权重让模型更关注转化信号。### 特征工程与嵌入维度在实际应用中共享嵌入层的维度选择非常关键。过小的嵌入维度会导致信息丢失过大的维度则会导致过拟合。通常建议在8-64之间调整。### 其他变体ESMM的后续改进包括-ESMMAttention在CVR塔中引入注意力机制让模型更关注与转化相关的特征。-Multi-ESMM处理多步转化如加购、收藏、支付的序列任务。## 总结ESMM通过多任务学习巧妙解决了CVR预估中的两大难题1.样本选择偏差通过在全空间所有曝光样本上训练CTCVR任务避免了只在点击样本上训练导致的分布偏移。即使未点击样本的CVR不可观测模型也能通过CTR和CTCVR的乘积关系学到正确的CVR。2.数据稀疏通过共享嵌入层让CTR任务中丰富的点击数据帮助CVR任务学习更好的特征表示。CTR任务提供了大量的训练信号缓解了CVR正样本不足的问题。ESMM的核心思想可以概括为用辅助任务CTR、CTCVR来间接优化主任务CVR同时利用共享表示来迁移知识。这种范式在推荐系统、广告预估等领域具有广泛的应用价值。理解ESMM不仅有助于解决CVR预估问题也为处理其他存在样本选择偏差或数据稀疏的任务提供了思路——例如在医疗诊断中我们可以用高频率的检查结果来辅助预测罕见疾病。
延伸阅读

更多相关文章

2026/8/31 13:17:30

AI订阅管家:智能监控与优化你的数字消费

1. 为什么我们总在不知不觉中成为"年费冤大头"前几天整理信用卡账单时,我突然发现自己在过去一年里,竟然为各种用不着的订阅服务支付了将近2000元。从某音乐平台的自动续费,到早已遗忘的云存储会员,再到试用后忘记取消的…

2026/9/9 15:44:02

Docker容器化实战:定制镜像、配置Yum源与部署服务

这次我们来看 Docker 容器化技术中几个非常核心的实战操作:如何定制一个简单的 Docker 镜像、如何在容器内部配置 Yum 软件仓库,以及如何在容器内完成服务的安装与部署。对于需要在隔离环境中快速构建和部署应用的开发者或运维人员来说,掌握这些技能是摆脱“只会用现成镜像”…

2026/9/12 6:31:07

暗黑破坏神2存档编辑器:Web端终极修改工具完整指南

暗黑破坏神2存档编辑器:Web端终极修改工具完整指南 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 你是否曾经为暗黑破坏神2的角色属性不够理想而烦恼?是否想要快速测试不同的装备组合却苦于重新练级&…

2026/9/13 7:07:23

运算放大器设计实战:虚短虚断、11种经典电路与稳定性分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/13 7:07:23

如何为 GitHub 账户添加 passkey 并用附近设备完成登录

如何为 GitHub 账户添加 passkey 并用附近设备完成登录 【免费下载链接】docs The open-source repo for docs.github.com 项目地址: https://gitcode.com/GitHub_Trending/do/docs 这篇文章面向想要摆脱密码登录的 GitHub 账户使用者:先为自己的账户注册一个…

2026/9/13 7:07:23

门控注意力机制优化大语言模型性能与效率

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/13 0:01:16

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/12 6:37:43

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码