网站建设新的技术方案,网站建设联雅,电商网站开发文字教程,互联网下的网络营销简介#xff1a;本文介绍的是阿里巴巴团队发表在 SIGIR’2018 的论文《Entire Space Multi-Task Model: An Effective Approach for Estimating Post-Click Conversion Rate》。文章基于 Multi-Task Learning (MTL) 的思路#xff0c;提出一种名为ESMM的CVR预估模型#xff…简介本文介绍的是阿里巴巴团队发表在 SIGIR’2018 的论文《Entire Space Multi-Task Model: An Effective Approach for Estimating Post-Click Conversion Rate》。文章基于 Multi-Task Learning (MTL) 的思路提出一种名为ESMM的CVR预估模型有效解决了真实场景中CVR预估面临的数据稀疏以及样本选择偏差这两个关键问题。后续还会陆续介绍MMoEPLEDBMTL等多任务学习模型。
多任务学习背景
目前工业中使用的推荐算法已不只局限在单目标ctr任务上还需要关注后续的转换链路如是否评论、收藏、加购、购买、观看时长等目标。
本文介绍的是阿里巴巴团队发表在 SIGIR’2018 的论文《Entire Space Multi-Task Model: An Effective Approach for Estimating Post-Click Conversion Rate》。文章基于 Multi-Task Learning (MTL) 的思路提出一种名为ESMM的CVR预估模型有效解决了真实场景中CVR预估面临的数据稀疏以及样本选择偏差这两个关键问题。后续还会陆续介绍MMoEPLEDBMTL等多任务学习模型。
论文介绍
CVR预估面临两个关键问题
1. Sample Selection Bias (SSB)
转化是在点击之后才“有可能”发生的动作传统CVR模型通常以点击数据为训练集其中点击未转化为负例点击并转化为正例。但是训练好的模型实际使用时则是对整个空间的样本进行预估而非只对点击样本进行预估。即训练数据与实际要预测的数据来自不同分布这个偏差对模型的泛化能力构成了很大挑战导致模型上线后线上业务效果往往一般。 2. Data Sparsity (DS)
CVR预估任务的使用的训练数据即点击样本远小于CTR预估训练使用的曝光样本。仅使用数量较小的样本进行训练会导致深度模型拟合困难。
一些策略可以缓解这两个问题例如从曝光集中对unclicked样本抽样做负例缓解SSB对转化样本过采样缓解DS等。但无论哪种方法都没有从实质上解决上面任一个问题。
由于点击转化本身是两个强相关的连续行为作者希望在模型结构中显示考虑这种“行为链关系”从而可以在整个空间上进行训练及预测。这涉及到CTR与CVR两个任务因此使用多任务学习MTL是一个自然的选择论文的关键亮点正在于“如何搭建”这个MTL。
首先需要重点区分下CVR预估任务与CTCVR预估任务。
CVR 转化数/点击数。是预测“假设item被点击那么它被转化”的概率。CVR预估任务与CTR没有绝对的关系。一个item的ctr高cvr不一定同样会高如标题党文章的浏览时长往往较低。这也是不能直接使用全部样本训练CVR模型的原因因为无法确定那些曝光未点击的样本假设他们被点击了是否会被转化。如果直接使用0作为它们的label会很大程度上误导CVR模型的学习。CTCVR 转换数/曝光数。是预测“item被点击然后被转化”的概率。其中x,y,z分别表示曝光点击转换。注意到在全部样本空间中CTR对应的label为click而CTCVR对应的label为click conversion这两个任务是可以使用全部样本的。因此ESMM通过学习CTRCTCVR两个任务再根据上式隐式地学习CVR任务。具体结构如下 网络结构上有两点值得强调
共享Embedding。 CVR-task和CTR-task使用相同的特征和特征embedding即两者从Concatenate之后才学习各自独享的参数隐式学习pCVR。这里pCVR 仅是网络中的一个variable没有显示的监督信号。
具体地反映在目标函数中 代码实现
基于EasyRec推荐算法框架我们实现了ESMM算法具体实现可移步至githubEasyRec-ESMM。
EasyRec介绍EasyRec是阿里云计算平台机器学习PAI团队开源的大规模分布式推荐算法框架EasyRec 正如其名字一样简单易用集成了诸多优秀前沿的推荐系统论文思想并且有在实际工业落地中取得优良效果的特征工程方法集成训练、评估、部署与阿里云产品无缝衔接可以借助 EasyRec 在短时间内搭建起一套前沿的推荐系统。作为阿里云的拳头产品现已稳定服务于数百个企业客户。
模型前馈网络 def build_predict_graph(self):Forward function.Returns:self._prediction_dict: Prediction result of two tasks.# 此处从Concatenate后的tensorall_fea开始省略其生成逻辑cvr_tower_name self._cvr_tower_cfg.tower_namednn_model dnn.DNN(self._cvr_tower_cfg.dnn,self._l2_reg,namecvr_tower_name,is_trainingself._is_training)cvr_tower_output dnn_model(all_fea)cvr_tower_output tf.layers.dense(inputscvr_tower_output,units1,kernel_regularizerself._l2_reg,name%s/dnn_output % cvr_tower_name)ctr_tower_name self._ctr_tower_cfg.tower_namednn_model dnn.DNN(self._ctr_tower_cfg.dnn,self._l2_reg,namectr_tower_name,is_trainingself._is_training)ctr_tower_output dnn_model(all_fea)ctr_tower_output tf.layers.dense(inputsctr_tower_output,units1,kernel_regularizerself._l2_reg,name%s/dnn_output % ctr_tower_name)tower_outputs {cvr_tower_name: cvr_tower_output,ctr_tower_name: ctr_tower_output}self._add_to_prediction_dict(tower_outputs)return self._prediction_dict
loss计算
注意计算CVR的指标时需要mask掉曝光数据。 def build_loss_graph(self):Build loss graph.Returns:self._loss_dict: Weighted loss of ctr and cvr.cvr_tower_name self._cvr_tower_cfg.tower_namectr_tower_name self._ctr_tower_cfg.tower_namecvr_label_name self._label_name_dict[cvr_tower_name]ctr_label_name self._label_name_dict[ctr_tower_name]ctcvr_label tf.cast(self._labels[cvr_label_name] * self._labels[ctr_label_name], tf.float32)cvr_loss tf.keras.backend.binary_crossentropy(ctcvr_label, self._prediction_dict[probs_ctcvr])cvr_loss tf.reduce_sum(cvr_losses, namectcvr_loss)# The weight defaults to 1.self._loss_dict[weighted_cross_entropy_loss_%s %cvr_tower_name] self._cvr_tower_cfg.weight * cvr_lossctr_loss tf.reduce_sum(tf.nn.sigmoid_cross_entropy_with_logits(labelstf.cast(self._labels[ctr_label_name], tf.float32),logitsself._prediction_dict[logits_%s % ctr_tower_name]), namectr_loss)self._loss_dict[weighted_cross_entropy_loss_%s %ctr_tower_name] self._ctr_tower_cfg.weight * ctr_lossreturn self._loss_dict
note: 这里loss是 weighted_cross_entropy_loss_ctr weighted_cross_entropy_loss_cvr, EasyRec框架会自动对self._loss_dict中的内容进行加和。
metric计算
注意计算CVR的指标时需要mask掉曝光数据。 def build_metric_graph(self, eval_config):Build metric graph.Args:eval_config: Evaluation configuration.Returns:metric_dict: Calculate AUC of ctr, cvr and ctrvr.metric_dict {}cvr_tower_name self._cvr_tower_cfg.tower_namectr_tower_name self._ctr_tower_cfg.tower_namecvr_label_name self._label_name_dict[cvr_tower_name]ctr_label_name self._label_name_dict[ctr_tower_name]for metric in self._cvr_tower_cfg.metrics_set:# CTCVR metricctcvr_label_name cvr_label_name _ctcvrcvr_dtype self._labels[cvr_label_name].dtypeself._labels[ctcvr_label_name] self._labels[cvr_label_name] * tf.cast(self._labels[ctr_label_name], cvr_dtype)metric_dict.update(self._build_metric_impl(metric,loss_typeself._cvr_tower_cfg.loss_type,label_namectcvr_label_name,num_classself._cvr_tower_cfg.num_class,suffix_ctcvr))# CVR metriccvr_label_masked_name cvr_label_name _maskedctr_mask self._labels[ctr_label_name] 0self._labels[cvr_label_masked_name] tf.boolean_mask(self._labels[cvr_label_name], ctr_mask)pred_prefix probs if self._cvr_tower_cfg.loss_type LossType.CLASSIFICATION else ypred_name %s_%s % (pred_prefix, cvr_tower_name)self._prediction_dict[pred_name _masked] tf.boolean_mask(self._prediction_dict[pred_name], ctr_mask)metric_dict.update(self._build_metric_impl(metric,loss_typeself._cvr_tower_cfg.loss_type,label_namecvr_label_masked_name,num_classself._cvr_tower_cfg.num_class,suffix_%s_masked % cvr_tower_name))for metric in self._ctr_tower_cfg.metrics_set:# CTR metricmetric_dict.update(self._build_metric_impl(metric,loss_typeself._ctr_tower_cfg.loss_type,label_namectr_label_name,num_classself._ctr_tower_cfg.num_class,suffix_%s % ctr_tower_name))return metric_dict
实验及不足
我们基于开源AliCCP数据进行了大量实验实验部分请期待下一篇文章。实验发现ESMM的跷跷板现象较为明显CTR与CVR任务的效果较难同时提升。
参考文献
Entire Space Multi-Task Model: An Effective Approach for Estimating Post-Click Conversion Rate阿里CVR预估模型之ESMMEasyRec-ESMM使用介绍多任务学习模型之ESMM介绍与实现
原文链接
本文为阿里云原创内容未经允许不得转载。