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预估问题也为处理其他存在样本选择偏差或数据稀疏的任务提供了思路——例如在医疗诊断中我们可以用高频率的检查结果来辅助预测罕见疾病。

相关新闻

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

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

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

2026/7/25 18:07:39 阅读更多 →
Docker容器化实战:定制镜像、配置Yum源与部署服务

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

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

2026/7/25 18:07:39 阅读更多 →
独立开发者如何利用Taotoken以更低成本实验多种大模型API

独立开发者如何利用Taotoken以更低成本实验多种大模型API

独立开发者如何利用Taotoken以更低成本实验多种大模型API 对于独立开发者或小型工作室而言,在有限的预算内探索不同的大模型能力,是一项兼具挑战与机遇的任务。直接对接多个厂商的API,意味着需要分别注册账号、管理多个密钥、理解不同的计费…

2026/7/25 18:06:39 阅读更多 →

最新新闻

花椒智能分拣系统:基于QueryInst的杂质检测技术实践

花椒智能分拣系统:基于QueryInst的杂质检测技术实践

1. 项目背景与需求解析花椒作为我国重要的调味品和经济作物,其品质直接影响市场价值。在规模化种植场景中,采摘后的花椒常混入叶片、枝梗、石块、塑料等杂质,传统人工分拣方式效率低下且成本高昂。我们团队基于实际产线需求,开发了…

2026/7/25 18:16:44 阅读更多 →
Windows内存终极清理指南:Mem Reduct 3.5.2完整免费教程

Windows内存终极清理指南:Mem Reduct 3.5.2完整免费教程

Windows内存终极清理指南:Mem Reduct 3.5.2完整免费教程 【免费下载链接】memreduct Lightweight real-time memory management application to monitor and clean system memory on your computer. 项目地址: https://gitcode.com/gh_mirrors/me/memreduct …

2026/7/25 18:16:44 阅读更多 →
Unity色彩分级实战:从原理到应用,打造电影级视觉风格

Unity色彩分级实战:从原理到应用,打造电影级视觉风格

1. 项目概述:从“能看”到“好看”的视觉魔法在Unity项目开发的后期,尤其是当你完成了核心玩法和场景搭建后,一个常被忽视却又至关重要的环节就是视觉效果的最终打磨。我们常常会遇到这样的困境:场景里的模型精度不低,…

2026/7/25 18:16:44 阅读更多 →
Kimi代码解释器安全红线警告:3类高危代码自动执行场景,及企业合规接入的5项强制配置

Kimi代码解释器安全红线警告:3类高危代码自动执行场景,及企业合规接入的5项强制配置

更多请点击: https://intelliparadigm.com 第一章:Kimi代码解释器安全红线警告概述 Kimi代码解释器在提供强大代码执行能力的同时,内置了严格的安全沙箱机制,旨在防止恶意操作、系统渗透与数据泄露。所有用户提交的代码均运行于隔…

2026/7/25 18:16:44 阅读更多 →
从误报率42%到准确率91.6%,AI离职预测系统调优全路径,含可复用Python特征工程模板

从误报率42%到准确率91.6%,AI离职预测系统调优全路径,含可复用Python特征工程模板

更多请点击: https://kaifayun.com 第一章:从误报率42%到准确率91.6%,AI离职预测系统调优全路径,含可复用Python特征工程模板 离职预测模型上线初期误报率高达42%,导致HR团队频繁干预无效预警,员工信任度下…

2026/7/25 18:16:43 阅读更多 →
Arch Linux异军突起:从极简哲学到AUR生态的技术价值解析

Arch Linux异军突起:从极简哲学到AUR生态的技术价值解析

最近几年,如果你在技术社区里多逛一逛,会发现一个有趣的现象:当新手询问“哪个Linux发行版适合入门”时,评论区里除了经典的Ubuntu、Debian,总会出现一个声音——“Arch Linux”。这个声音往往伴随着“滚动更新”、“极…

2026/7/25 18:15:43 阅读更多 →

日新闻

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存

突破文档下载限制:kill-doc让你看到的都能保存 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档,但是相关网站浏览体验不好各种广告,各种登录验证,需要很多步骤才能下载文档,该脚本就是为了解决您的…

2026/7/25 0:00:35 阅读更多 →
C++ string类模拟实现:从深拷贝到内存管理的完整指南

C++ string类模拟实现:从深拷贝到内存管理的完整指南

1. 项目概述:为什么我们要“手撕”string类?在C的学习道路上,尤其是从C语言过渡到C的“初阶”阶段,string类绝对是一个绕不开的核心。标准库里的std::string用起来太方便了,、find、substr,几个操作符和函数…

2026/7/25 0:00:35 阅读更多 →
三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

三角洲寻宝鼠工具:高效文件搜索与资源管理实战指南

1. 先搞清楚“三角洲寻宝鼠”到底是什么工具从名称来看,“三角洲寻宝鼠”更像是一个资源查找或文件检索类工具,而不是游戏或娱乐软件。这类工具的核心价值在于帮助用户快速定位特定资源,比如文档、图片、压缩包或特定格式的文件。如果你经常需…

2026/7/25 0:00:35 阅读更多 →

周新闻

Go语言静态资源打包方案对比与实践指南

Go语言静态资源打包方案对比与实践指南

1. 项目背景与核心需求在Go语言开发中,我们经常需要处理静态资源文件的打包问题。无论是Web应用的模板文件、前端资源,还是配置文件、证书等,都需要随程序一起分发。传统做法是将这些文件与编译后的二进制文件放在同一目录下,但这…

2026/7/25 5:08:22 阅读更多 →
Go语言实现高性能LDAP认证服务的架构与实践

Go语言实现高性能LDAP认证服务的架构与实践

1. 项目背景与核心价值LDAP(轻量级目录访问协议)作为企业级身份认证的黄金标准,已经服务了超过80%的财富500强公司。我在金融科技领域实施统一认证体系时,发现传统Java方案存在启动慢、内存占用高等痛点。而Go语言凭借其协程并发模…

2026/7/25 5:13:53 阅读更多 →
【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

【AI面试官实战指南】:用ChatGPT模拟10类高频技术岗面试,3天提升应答精准度92%

更多请点击: https://intelliparadigm.com 第一章:AI面试官实战指南的核心价值与适用场景 AI面试官并非替代人类HR的“黑箱工具”,而是以可解释、可审计、可迭代的方式,赋能招聘全链路的关键基础设施。其核心价值在于将主观经验沉…

2026/7/24 18:52:18 阅读更多 →

月新闻