作者:Wei
搜索推荐系统实战篇-上半篇
1. 前言
一切源于炼丹笔记,我只是敲了敲代码。
背景
在电商搜索中,例如淘宝,拼多多,京东等的搜索的场景往往是:用户A通过搜索框Query找到他/她想要购买的东西,然后搜索引擎通过某些算法策略返回一系列商品,用户再决定是否进行点击购买。
要做好这样一个问题,我们需要抓住问题的核心。那么搜索引擎的核心是什么呢?至少有两点。
从上面看,我们的核心至少有两个,一个是构建Query与Item的关系(保证Query下返回的商品至少是强相关的),第二个就是构建User和Item的关系(在强相关的商品中,找到用户大概率会点击购买的商品)。
上面两点是很多电商搜索引擎需要做到的,依据平台的不同,可能还会有些许不一致。
问题定义
在电商搜索背景下,我们的目标依据大佬们对于平台当前的发展定位以及未来规划达到的目标往往会有些许不同,优化的指标也会有较大的不同,常见的一些热门指标如下:
上面几个指标是电商平时较为关注的,当然还有非常多其它重要的评估指标,例如:总体运营指标,网站流量指标,销售转化指标,客户价值指标,商品及供应链指标,营销活动指标,风险控制指标,市场竞争指标等等,想要深入理解的话可以阅读参考文献[7]。
本文重点
本文我们重点关注精排侧提升曝光到转化的优化问题,即从曝光到被购买的概率优化问题。
2. 建模
和许多数据建模问题类似,在我们的问题初步确定之后,接下来需要考虑的问题就是设计评估指标并针对问题进行指标的优化。
评估指标设计
线下评估指标对比
在很多情况下,我们一开始会选用AUC(Area Under Curve)指标来对线下模型进行评估。ROCAUC被定义为ROC曲线下与坐标轴围成的面积,一般我们以TPR为y轴,以FPR为x轴,就可以得到ROC曲线。
其中,、分别为正、负样本数。
AUC的数值都不会大于1。又由于ROC曲线一般都处于这条直线的上方,所以AUC的取值范围在0.5和1之间。AUC越接近1.0,检测方法真实性越高;等于0.5时,一般就无太多应用价值了。其中关于:FPR(False Positive Rate)以及 TPR(True Positive Rate)的数学计算公式为:
在数据量非常大的情况下计算AUC是比较耗时的,有时为了快速迭代,我们会对验证样本进行随机采样然后计算AUC的值进行比较,这在KDD2020 Best Paper中也有讨论,采样之后的AUC一般是没有问题的,所以还是相对稳定的。
AUC指标在诸多问题中是一个非常不错的指标,但是在电商搜索的问题上可能会有些许不一致。举个简单的例子,假设我们每次曝光3个商品,
场景1:
场景2:
这个时候,场景1得到的AUC是0.75,而场景2得到的AUC则是1;这么看这个指标好像并不是非常合理,同样的购买情况,但是得到的结果却是不一样的,因而AUC指标把所有的预测结果都放在了一起考虑,所以对于电商搜索等场景该指标有些粗犷了,我们需要一些更加精细的评估指标。
from sklearn.metrics import roc_auc_score
## 场景1
pred_A = [0.8,0.7,0.6]
pred_B = [0.5,0.4,0.3]
label_A = [1,0,0]
label_B = [1,0,0]
roc_auc_score(y_score=pred_A + pred_B, y_true=label_A + label_B)
0.75
## 场景2
pred_A = [0.8,0.7,0.6]
pred_B = [0.8,0.7,0.6]
label_A = [1,0,0]
label_B = [1,0,0]
roc_auc_score(y_score=pred_A + pred_B, y_true=label_A + label_B)
1.0
GAUC的数学形式如下:
此处的可以表示很多东西,例如带有点击的页面的权重,那么GAUC就是每个展示页面中,用户的对于排序的商品的满意度。
在电商搜索中,我们也可以令表示单个用户单条query的权重,那么此时GAUC就是用户在query下对于得到的排序商品的满意度,在有些场景下也可以表示是某个用户,在计算GAUC的时候,我们一般会删除全部为0的情况。如果我们采用GAUC为评估指标,在上面的两个场景中,我们的GAUC都是1,这其实就比较符合我们的预期了。
但正如大家所看到的,GAUC也存在一些问题,
从众多的文章博客和论文中的实验记录,以及我们自己的评测指标来看,目前大家都还是主要看GAUC指标,本文剩下的内容也会以PV的GAUC为主要观测指标。
从我们平时的实践情况来看,在90%的情况下AUC和GAUC是一致的,也就是说AUC上涨的话,那么GAUC基本都是涨的,但这并不是绝对的。但平时线下90%的情况下对比AUC的实验也是合理的。
3. Loss&整体框架设计
问题背景
目前绝大部分传统机器学习框架都是基于下面的形式进行的,我们将训练数据输入到某个深度的模型框架,最后通过设计的某种Loss进行模型的训练,
因为我们的目标是提升模型从曝光到被购买的转化率,这看起来和非常多的二分类问题类似,我们只需要将曝光且被用户购买的记录标记为1,而将曝光但是用户却没有购买的商品标记为0,然后使用Logloss/Binary cross entropy作为损失函数进行模型训练和设计即可。
其中是样本的个数,是标签(曝光且被点击就是1,反之为0),是关于第个样本的预测概率。
初看,好像没有太大的问题,在之前的IJCAI2018年的”阿里妈妈搜索广告转化预测“的诸多Top方案基本是类似的,只需要直接使用上面的Loss进行优化即可,但是实际情况和我们理想情况下还是相差较大的。
在几乎现在90%的电商搜索领域,大家使用的模型都是基于多个模型的Cotrain,也就是大家经常听到的DeepMTL(DeepMTL:Deep Multi-Task Learning,深度多任务学习)。如下图就是一种常见CTR+CVR Cotrain的框架:
CTR+CVR Cotrain的框架,就是两个网络分支,一个对应CTR, 一个对应CVR。最后我们采用的形式表示我们从曝光到购买的概率。而此时我们优化的Loss如下:
其中:
刚开始对于这类设定我们还是非常怀疑的,明明可以直接优化的Loss,为什么还要加个CTR的Loss进行辅助?于是我们做了个线下的对比实验,直接训练曝光到转化以及早期的CTR和CVR Cotrain的模型,结果发现:
这和平时实践中直接优化Loss的直觉是相反的,甚至有些怀疑人生,但是我们实践经验却时刻提醒我们要做好问题的优化,一个好的Loss至关重要。所以我们便去调研如下问题:
在和一些搞精排模型的朋友交流之后, 大家关于CTR和CVR进行Cotrain方式的解释大致可以归纳为:
为了更好地了解采用DeepMTL方案的原因,我们进行了较为深入的调研。
DeepMTL有效性理解的调研
从网上的诸多资料的调研之后,我们发现一般采用DeepMTL的场景有下面6个大类。
进行多任务建模,意味着我们需要有多个任务,而多个任务,这也意味着每个任务都可能拥有不同的数据,所以每个任务都可以从其他任务的数据集里面吸收额外的有用的信息,获得额外的增益。我们在模型训练的时候其实是加入了额外(其他任务的信息)的信息,这个时候原先的任务效果得到提升也是大概率的事情。其实如果从第二个任务中抽取特征等加入到主任务中,可能也会有提升。DeppMTL则是通过梯度回传的方式将其它任务的信息加入了进来。
经典的工作有:
这些论文的工作都是通过寻找相关的任务,例如第一篇论文的工作就是通过加入评论信息来辅助用户商品的协同过滤效果, 第二个工作则通过使用context-aware ranking信息来辅助提升实体推荐的效果。
多任务学习, 任务之间共享的特征表示因为需要同时满足多个任务, 这就意味着这些特征表示需要拥有不错的泛化性,所以多任务学习可以降低因为单个任务数据脏而带有较多噪音的问题。因为DeepMTL最终优化的Loss是由多个任务的Loss结合起来的, 对于每个单独的任务,其他的任务对应的Loss可以当做是正则项。
有些信息较为难学,但又是主任务(核心任务)的重要特征,可以另外起一个任务对其进行学习,再将学习到的信息传递给主任务。
一些特征对于某些特定任务是非常易于学习的,但是对于另外一个任务A可能却很难学,而这种难学可能是由于特征和任务A的关系较为复杂等原因造成的,通过多任务学习,我们可以令任务B去学习,而最简单的方式就是通过hints去做这件事。还常见于一些图像问题中,单独分出一个任务识别小的物体信息;
经典的工作有:
第一篇文章通过预测输入句中是否含有积极或消极的情绪词,作为情绪分析的辅助任务; 第二篇则通过模型输出前面任务的预测结果作为Hints信息传递给后续的模型当中。
此处说的决策过程最典型的例子就是在电商的购物流程中, 消费者购物需要经历:exposure -> click -> pay的过程。
1. 缓解SSB/DS,调优中间结果
这在电商搜索和广告问题里面最为经典的就是CVR预估问题,CVR预估在整个决策的中间阶段,直接使用中间阶段的数据则会出现较多的问题,例如SSB(Sample Selection Bias),DS(Data Sparsity)等,那么怎么办呢?用多任务学习将整个决策过程串联起来。最为典型的工作就是:
这样我们建模的时候就可以利用到丰富的点击数据,从而使得我们神经网络中的Embedding得到更为充分的训练,缓解Data Sparsity的问题,此外,我们的建模目前是直接基于曝光建模的,也可以缓解SSB问题。
那为什么我们说还可以修正中间结果呢?我们以第一篇ESMM为例,我们看用户的购物过程是下面这样一个过程:用户先进行了搜索,然后得到了搜索引擎的反馈X1, 用户对自己相对感兴趣的商品进行点击, 进入了详情页X2, 然后通过在X1看到的信息并结合X2的信息以及自身的需求确定是不是购买。如下图所示, 此处我们先不考虑加购收藏等情况,
CVR就是在求,
这边表示详情页的信息以及一些上下文信息,例如从曝光页带过来的信息,用户在曝光页面看到了很多感兴趣的商品,这些也会影响他进入详情页之后是否最终购买的决定。
我们看ESMM论文中给出的公式是:
这在数学上成立的,但是却忽略了一个比较大的问题,点击页面给出的和详情页的是不一样的,此处我们的以及可以认为是无偏的,我们强行用相乘的形式来表示二者的关系,所以修正了在相乘关系下的情况。
2. 利用前一决策的信息
在用户决策的过程中,存在先后顺序,在后续的决策过程中,我们可以通过利用前一阶段的信息来辅助后续的建模。典型的案例有:
这几个工作都会将前一阶段的信息作为特征输入输入到后续的模块当中,而且都取得了不错的效果。我们在实践中也验证了这一点。
一个模型,中间多次相同任务的优化,中间表示层拼接然后做CF,可以做到类似集成效果;典型的工作有:
多任务学习用于多个不同任务的建模也就意味着模型会拥有这些不同任务的功能。除了能辅助提升模型效果之外, 还可以扩展模型的功能性。达到一个模型多个功能的效果。典型的作品有:
这两个工作将原任务和知识图谱等信息结合并利用知识图谱部分的任务对原模型赋能,使得模型还具有了一定的可解释性。
小结
从我们关于DeepMTL有效性的调研情况来看,电商搜索中采用DeepMTL模型建模能带来收益的原因主要有下面几点:
在明确了DeepMTL的建模有效性之后,下一步要做的就是去细化它。
3.1 DeepMTL常见的两种建模方式探讨
虽然确立了DeepMTL的建模框架,但其实还存在非常多需要细化的地方,和一些做该方向的朋友交流之后,我们发现目前大家采用的DeepMTL框架大致可以按照对于数据流的使用方式不同而划分为两类。当然不管是哪种方式,都是有很多可以提升的地方的,下面我们将两种建模策略的诸多问题以及可能潜在的提升策略进行汇总。
CTR数据流+CVR数据流的大致流程如下图所示:
下面我们介绍这种策略的几个问题,以及对应的处理策略;
1.CTR/CVR数据流浪费问题:
2.CTR&CVR网络数据层面的关联性丢失:
其中,,是超参数,可以自己调整,是辅助Loss,用来加强数据之间的联系。
3.CTR&CVR网络数据Cotrain的问题:
基于对CTR数据流和CVR数据流Cotrain的讨论,我们发现既然CVR的数据是全部被包含在CTR数据中的,分开训练又浪费数据又没法直接关联关系,既然所有的CVR数据流都来源于CTR数据流,那为什么不只使用CTR数据流呢?于是便有了基于CTR数据流的建模。
1.CTR&CVR网络数据层面的优点:
2. 可待继续改进的地方:
3.2 DeepMTL挑战&提升角度&应用场景
在上面小节的讨论中,我们确定了我们模型大致框架,即使用单CTR数据流的DBMTL形式的建模策略,其实本质还是DeepMTL,所以关于DeepMTL中的挑战的处理往往可以为我们的模型带来不错的提升。
如何寻找能信息共用的问题, 即相关任务, 然后再对相关任务的建模辅助提升主任务的效果;目前比较成功的一些案例就是使用知识图谱提升协同过滤的效果;使用搜索log中context-aware ranking提升实体推荐的效果等。
这块最具代表性的工作就是MMOE,RecSys2020的Best Paper提出的PLE等算法了。不同任务的共享不可避免要讨论的就是共享层特征的公用问题,目前看PLE算法已经较好地解决了多任务特征层信息共享出现的跷跷板现象。但是有没有其他更好的策略仍然值得研究。
MMOE之前在CTR+CVR Cotrain的框架下得到了不错的提升,这块是非常值得参考的。
该挑战最为常见的使用场景就是视频推荐任务, 在视频推荐任务中,我们经常会使用视频观看时长百分比,是否观看完,是否点击等信息来共同建模,而这个时候就不可避免的发现下面这样的问题:视频观看的百分比是回归问题;是否点击是二分类问题;量纲不一致,直接loss相加调整权重的话,会出现比较多的问题,这一块的经典工作是:
在实践中,我们发现,对于不同的任务使用不同的优化方式进行优化可以给模型带来一定的帮助。在Taboola工程师的实践经验分享中也发现了这样的问题,如何对不同的任务进行优化也是一个值得探索的问题。
It’s a common convention that learning rate is one of the most important hyperparameters for tuning neural networks. So we tried tuning, and found a learning rate that looked really good for task A, and another one that was really good for task B. -- By Zohar Komarovsky
这个目前大家还是基于经验来做的,暂时没有完美的理论支撑。
小结
通过这一章的调研与实验,我们初步决定使用下面的框架:
该框架的诸多优点:
4. 数据收集&理解&数据预处理
关于我们的数据收集形式对我们进行后续数据的使用和预处理起到非常关键的作用,我承认这块我做得不是很好,导致在实验的过程中无脑的把数据直接丢入模型,看上去模型的效果变差了,带来了非常多错误的结论。从而使得后期又不得不重复进行实验。
注:公司的数据一般非常大,做大模型的话,在机器资源不够的情况下,跑一轮得到的结果是极其浪费时间的,关于这块,个人最大的建议就是在直接将数据丢到模型之前,至少检查以下几点东西。
这边不想吐槽太多,目测很多公司很多业务都是类似的,尤其是当业务发展多年的情况下,会遗留下一大堆数据表,这些表有非常多的字段,但是表的负责人已经离职了,很多数据字段也都没有写备注,但是这张表又和后面的很多关键表相关联,这是非常头疼的事情。
为什么说字段的理解非常重要呢?举个例子来说,商品ID(ItemID),比如iphone12的ID,
这样两种不同的数据字段携带的信息量是完全不一样的,
我们知道,不同国家的iphone12的销量可能是完全不一样的,在贫穷的国家可能销量就低;在富有的国家则销量很高,所以说数据字段的理解是至关重要的,相同的字段在不同设计情况下统计的特征可能完全是两码事。
数据清洗:我们的数据中,存在非常多的脏数据,这些数据的处理可以帮助我们更好地提效,使得模型训练得到的结果更为良性;这一块没有做太多的工作,可能反欺诈等团队做的工作会多一些,典型的就是:
对这些数据的清洗可以更为真实的反映用户的习惯。
数据采样:因为大模型这块数据量非常大,很多时候数据经过各种merge操作之后,都可以达到上PB级别,所以模型的训练经常需要有合理的采样策略;而目前最为常见的采样策略是基于随机的,基于启发式的(也就是大家经常会使用的基于规则的),也有一些基于最新的一些论文的方式:
这个基本所有的公司和数据竞赛中在样本规模达到一定比例的时候都会有碰到,将全部的负样本全部丢入到模型中进行训练,会浪费非常多的资源,而且常常因为类别不平衡等原因经常获得的效果往往还不如经过随机采样来的效果好。在我们的实验中,我们发现:
注意,这边仅仅是对负样本进行随机采样,正样本的量非常少,一般都是全部保留的。
在电商等应用中,很多用户对于position位置可能比较敏感,而这些position也具有非常大的参考价值,很多用户可能就只浏览了前面部分的商品,后面的曝光商品根本就没有看,尤其是末尾的商品,但是这些信息我们又没法捕捉,这块很多时候需要和工程讨论数据埋点的问题;而我们经常会使用下面的策略去进行尝试,几个典型的例子:
上面的这三种策略基本都是可以尝试的,但是别指望可以带来巨大的提升,不过微弱的提升还是可以期待一下的。除此之外,我看到还有非常多其它值得尝试的,此处仅列举在下方,并没有什么具体的结论。(下面这两个来源于引文[31])
好像也有听说最新的论文有使用一些最新的技术,来自动选择好的负样本,这块没有继续研究下去了。
一本有仙气的笔记,记录了AI的不凡
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有