题外话
我为什么要将我的论文笔记发出来?现在绝大多数论文都能够免费下载,既然人家能够读到原文,又为什么要花时间看你的读书笔记这种“二手货”?
打个比方,除了相声,我也非常爱听郭德纲的评书。以前,大家喜欢听书,是因为大多数老百姓不识字。那么现在,大多数年轻听众的文化水平要比郭先生高多了,为什么不买本书自己看故事,反而还要花钱、花时间听他说书?郭先生说的好,「听书听得就是说书人的阅历和见识」。阅历和见识,都需要时间的积累和打磨,它们不等同于知识,更不等同于学历,是书本上没有的,也是大多数年轻人所稀缺的,所以“说书”这门艺术会长久不衰(可能会换个包装,比如“晓说”之类的脱口秀)。
回到我自己身上,论对业界的贡献,我不及那些作者的万分之一,毕竟人家是原创,我是拾人牙慧。那大家看我点评论文的意义在哪里?
「现在的论文太多了,多到我们根本读不过来,多到我们不知道那篇文章才是能够解决我们面临问题的“灵丹妙药”」,因为每篇文章都是“王婆卖瓜”,宣称自己的实验结果远超基线好几个点。而且「绝大多数论文都像八股文一样,通篇读下来,才发现干货只有那么一点点」。曾经的我,遇到问题找论文时,看每篇都爱不释手,茫然不知道该拿哪篇来复现。只好看网上哪篇的呼声最高,看哪篇最新,看哪篇作者的来头大,就拿过来,照猫画虎地复现一遍。看看,这场景像不像在股市里听小道消息,跟风买股票。好在如果选论文选错了 ,只不过错付了几个不眠之夜,后果不像被割韭菜那么严重。
所以,我希望我的论文点评,能够起到帮初学者快速筛选论文的目的,节省他们的时间与精力。就像听书听的是说书人的阅历一样,我的点评正来源于,我过去趟过的雷、踩过的坑。
对于论文的作者,我表达我的敬意,如果发表的观点有谬误,也是本人才疏学浅所致,无意冒犯;对于我的读者,我希望我的点评能提供一个不同于原作者的视角,能让你快速了解一篇论文的优点与缺点,如果你感觉对你有帮助,请再移步原文仔细阅读之。
前言
今天点评的论文是阿里发表于SIGIR ’20的论文《ESAM: Discriminative Domain Adaptation with Non-Displayed Items to Improve Long-Tail Performance》,主要解决召回中如何处理“未曝光”item的问题。
读过我的《负样本为王》一文的同学,都已经明确了一个基本概念,“「不能照搬排序模型做召回」”。这是因为排序模型,是用“曝光过的样本”训练出来的,而召回所面对的百万、千万级的候选item,绝大多数是从未被曝光过的。这二者之间存在Sample Selection Bias (SSB)。
所以,训练召回模型时,最重要的事是让召回模型“开眼界、见世面”,所以绝对不能(只)拿“曝光未点击”做负样本,绝大多数的负样本是通过随机采样得到的。另外,在所有候选item之间平均采样得到的是easy negative,训练模型时没有“挑战性”。所以,增加hard negative已经成为业界的共识,像百度的Mobius, Facebook的EBR, Pinterest的PinSAGE, 阿里的IntentGC中都特别强调了hard negative的重要性。
痛点
到目前为止,这种通过优化负样本的生成策略来优化召回性能的方式,so far so good。但是,在我看来,这种方式还有两个问题,尚未解决:
hard negative怎么选?
无论哪种生成策略,hard negative的基本思路就是要选那些“「能够契合用户兴趣,但是契合程度不太强」”的item作为hard negative。但是你不觉得这是一个悖论吗?既然它们能够契合用户的兴趣,那又为什么拿它们当负样本呢?所以「难点就在于'契合程度不太强'这个标准太模棱两可,难于把握」。比如Facebook EBR是拿上一次的模型对所有候选item打分,排名太靠前的属于正样本,太靠后的属于easy negative,只有排名中间的才属于 hard negative。但是我们怎么知道哪个区间属于“中间”,是300~500,还是1000~2000。弄不好,就可能将本来能够讨用户喜欢的item当成 hard negative,对于模型反而有害。
另外,像Facebook EBR,需要用上一步训练出的模型对所有候选item打分,好选取排名中间的那些item作为hard negative,计算量太大了。
"曝光未点击"怎么处理?在《负样本为王》一文中,我根据我做过的实验,将“曝光未点击”样本称之于鸡肋,建议弃之不用。对于这一观点,就有很多同学在留言中表示反对,声称在他们的实验中,增加“曝光未点击”做负样本,对于模型性能有正向使用。唉,“曝光未点击“变成了“薛定谔的样本”,我该拿你如何是好?
ESAM:迁移学习的新视角
我们先将以上痛点放一放,让我们先看看阿里的Entire Space Adaptation Model (ESAM)是怎么做召回的。ESAM从迁移学习的新视角来看待Sample Selection Bias,它将所有候选item划分成两个域:
Source Domain:由曝光过的item组成,它们有label(e.g., 点击与否)
Target Domain:未曝光过的item,占候选集的绝大部分,它们没有label,我们不知道用户是否喜欢它们
Base Model
因为只在曝光过的item上才有label,所以BaseModel也只在source domain上训练
用q代表用户输入,在推荐系统中q表示用户画像、用户历史,在搜索中q表示用户输入的关键词。有一个映射函数 将q映射成向量,
用d代表item,有映射函数 将其映射成向量,
评分函数 来评估q与d之间的匹配程度, 。因为是做召回,所以 一般是两个输入向量的dot product或cosine,方便线上在FAISS里面做近邻检索。
拿q与d之间的匹配得分 与label就可以计算point-wise cross-entropy loss " "
注意,这个模型是在source domain上训练出来的,效果如下图所示:
图中的方块、三角、圆点是三类拥有不同的user feedback的item,比如被忽略、点击、购买的商品
图中的"Y"字就是学习出来的召回模型,可以发现它将蓝色的方块、三角、圆点划分得非常好,说明它能够区分不同的user feedback,但是只是在“曝光过的样本”上
这就与Y的真实目的,“区分绝大多数未曝光item”,即划分图中红色的方块、三角、圆点,南辕北辙。
图中的每个方块、三角、圆点代表映射后的item embedding,即 。因为 是只用“曝光数据”训练得到的,因此当 套用于“未曝光数据”上时,发现“曝光item”embedding空间(蓝圈)与“未曝光item”embedding空间 (红圈)相差太远。
这种分布空间上的差距(蓝圈与红圈的不重合)造成了在“曝光item”上训练出来的召回模型,上线后,作用于大量的“未曝光数据”后,表现得一塌糊涂。
Domain Adaptation with Attribute Correlation Alignment
ESAM作者认为,问题在于:「因为只有曝光item才有label,所以只能在曝光item上训练“item映射函数” ,导致学习出来的 会将“曝光item”和“未曝光item”映射到向量空间中相距较远的两个区域,使训练出来的召回模型在面对大量“未曝光item”时失效」。所以,当务之急是学习一个新的 可以将"曝光item"与“未曝光item”映射到同一片向量区域。
ESAM的思路是:
“曝光item”与“未曝光item”的特征之间的关系是一致的。比如,无论曝光与否,奢侈品牌的价格都要比普通品牌的价格要贵。如下图左所示。
以上举例是发生在原始特征之间,ESAM认为经过 的映射,“曝光item”与“未曝光item”的高阶特征(embedding的不同维度)之间的关系,也应该保持不变。所下图右所示。
【偏题小扛一下:“曝光item”与“未曝光item”相比,不同特征之间的关系一定一致吗?可能也不尽然。
因为“曝光与否”是由线上已有的推荐系统决定的。而线上系统是为了达成某一业务目标(比如促进成交)而设计的
比如,有曝光机会的商品,价格与质量之间的关系,大多数应该是“物美价廉”
而那些没有曝光机会的商品,不排除有些商品就是“价高质差”,与曝光item不同特征之间的关系截然相反。
所以“attribute correlation”能否成立,未必放之四海而皆准,需要读者实践时再仔细斟酌。】
回到Attribute Correlation Alignment,假设对于每个query "q"
我们收集了n个“曝光item”(来自source domain)和用户对它们的反馈。这n个item经过 映射,映射成 ,L是embedding的维度
我们再随机抽样n个“未曝光item”(来自target domain),它们经过 映射,映射成
我们要求: 的L维高阶特征的两两之间( 和 )的协方差,与 的L维高阶特征的两两之间( 和 )的协方差,两者之间的差值尽可能小
当我们的优化目标是 (source domain上的point-wise cross-entropy loss)+ 时,优化效果如下图所示
我们发现,相比只有 时,增加了 辅助task,学习到的映射函数 的确能够将“曝光item”与“未曝光item”都映射到同一篇区域,即图中的蓝圈与红圈重合
学到的召回模型,仍然能够将不同feedback的“曝光item”区分开。即图中的Y,能够区分蓝色的方块、三角、圆点。
但是"未曝光item"经过 映射,红色的方块、三角、圆点却没有蓝色方块、三角、圆点那么清晰的区域性,红色的方块、三角、圆点杂乱分布在圈内
这是因为 只是不同特征的协方差在source/target两域的差值的总和,这个限制还是太粗粒度了。假如,只有一对特征之间的协方差在两个域之间相差比较大,但是其他对的协方差减值都比较小,最终的 仍然会比较小,但是却足以导致红色方块、三角、圆点之间的相对位置与蓝色方块、三角、圆点之间的相对位置,截然不同。
Center-Wise Clustering for Source Clustering
为了弥补 的限制太粗粒度的不足,ESAM的第一个方法就是「改善source domain中不同feedback的item的分布,使之”高内聚、低耦合“」。因为target domain中item embedding的分布,通过 模仿source domain,所以我们“期待”target domain中item embedding的分布也能够”高内聚、低耦合“。
为实现以上目标,增加 的辅助task,注意这个task是针对source domain的。具体公式细节请参见原文中的公式(5)和公式(6)
公式中的第1项是为了达到“同一类feedback中的item embedding”要“高内聚”的目标,其中 代表属于某个feedback的所有item embedding的平均,作为这一类feedback的item embedding的中心
公式中的第2项是为了达到“不同类feedback的item embedding”要“低耦合”的目标,表现在不同feedback的item embedding的中心要尽可能远
增加了 作为辅助task之后,效果如下图(c)所示
可以发现在source domain,不同feedback的item(蓝色的方块、三角、圆点)分离得更加清晰了
因为target domain模仿source domain,所以在红色方块、三角、圆点在空间上也分离得更加清晰了
可惜的是,不像蓝色,红色方块、三角、圆点并不是按照feedback分离的,红色方块、三角、圆点混杂在一起。所以召回模型(图中的Y)还是无法将不同feedback的“未曝光item”(红色方块、三角、圆点)区分开
Self-Training for Target Clustering
「如果我们能够在target domain中也像source domain中一样根据feedback进行聚类就好了,但是难点在于,在target domain中的item,没有曝光机会,我们压根就不知道用户对它们的feedback。」
ESAM想出了一个非常巧妙的方法来解决这一难题,就是增加“「伪label」”:
训练中,如果根据当前模型,query "q"已经与某“未曝光item”的匹配得分相当低了(小于阈值 ),我们就认为这对< >是负样本,接下来的训练中,< >得分要变得越来越小,趋近0
训练中,如果根据当前模型,query "q"已经与某“未曝光item”的匹配得分相当高了(大于阈值 ),我们就认为这对< >是正样本,接下来的训练中,< >得分要变得越来越大,趋近1
第二个巧妙的地方在于,「具体实现时,ESAM并不需要动态修改label。因为修改label的目的,仅仅是为了接下来的优化指明方向」,所以ESAM使用如下辅助task达到同样的效果
是当前模型预估query与某“未曝光item”的匹配得分
是condition function,表示「这种"伪label"只在预估的匹配得分太高或太低,即模型有充分自信时,才添加」
公式的主体是 的形式。这是因为-plogp具备如下形状,「当p过高时,其梯度能够使之快速趋近于1,而在p过低时,其梯度能够使之快速趋近于0。正是我们所希望的添加"伪label"的效果。」
至此,所有辅助任务添加完毕,(预期)效果如下图(d)所示。
“未曝光”item,即图中的红色三角、方块、圆点,也按照它们unknown but ground-truth的feedback聚类在一起,聚类位置与蓝色的三角、方块、圆点的位置重合
从而保证了,用“曝光”item训练出来的召回模型(图中的Y),既能区分不同user feedback的“曝光”item(蓝色),更重要的是,也能够区分不同feedback的"未曝光"item(红色)
总体方案
将以上介绍的各task组合起来,总体公式如下所示
算法流程示意图如下所示:
q代表用户(e.g., 用户画像或者用户输入的关键词),通过函数 映射成向量
代表source item, 即“曝光过”item,通过函数 映射成
代表target item,即“未曝光过”item,通过函数 映射成
: 先由用户输入q、"曝光样本" 计算出匹配得分 ,再和用户feedback计算出来的loss
:用来实现Attribute Correlation Alignment,即,item的高阶特征(item embedding的不同维度)之间的相对关系,应该在source domain和target domain保持一致
:在source domain根据用户feedback聚类,目的是为了使属于同一类feedback的item embedding实现“高内聚、低耦合”,从而间接实现在target domain内item embedding的“高内聚、低耦合”
:在target domain也希望能够根据feedback聚类,但是因为"未曝光"item根本没有feedback,所以通过self-training的方式给高置信度的item添加"伪label",从而在target domain也实现item embedding的“高内聚、低耦合”
点评
我赞同作者的作法,但是不认同作者的立论
作者认为之所以拿“曝光”item训练出来的模型不能用召回,是因为曝光的都是热门item,使训练出来的"item特征映射函数" ,在“未曝光”item上水土不服。「所以,“错”只在 身上,最初添加的Attribute Correlation Alignment任务 也只涉及 」。只不过发现只有 达不到效果,才添加了 和 作为“正则”。换句话说, 为主, 和 为辅。
这个观点,我是不敢苟同的。如我在《负样本为王》中说过,训练召回模型最重要的就是让其“开眼界,见世面”,其中就包括“user映射函数” 。在BaseModel中,通过计算 ,让 见识过“曝光”item了。所以「最重要的是让 多见识一些“未曝光”item」。如果ESAM止步于只添加了 ,那么 就无缘见识那些“未曝光”item了。好在作者添加的 涉及到计算 ,弥补了这一缺陷。
买椟还珠
综上所述,我赞同作者的作法,但是认识的重点不同。
作者认为ESAM中贡献最大的是,基于Attribute Correlation Alignment实现的辅助任务
而我认为贡献最大的、让我眼前一亮的是「通过Self-Training给“未曝光”item打上“伪标签”的作法」,以及作者「通过-plogp(i.e., entropy regularization)的巧妙实现方式」。
为什么self-training这个ESAM中的配角,让我觉得如此重要?还记得我在文章的一开始据说的,训练召回模型时的hard negative采样策略是一大痛点吗?这个痛点来源于两方面:
hard negative本来就是那些“能够契合用户兴趣,但是契合程度不太强”的item,“不太强”这个标准太模棱两可了
某些比较精细的hard negative策略,需要给全部候选item打分,以选取得分居中的那些样本当hard negative,这个计算最太大了(实际工程实现时会有所优化)。
而ESAM中通过self-training给“未曝光”item打上“伪标签”的作法,恰恰解决了以下两个痛点:
我们「不再需要制订一个硬规则决定哪些item属于hard negative」(比如排名在400~600之间的?为什么不是500~700?),而是「让模型自己去学习那些“未曝光”item的label」。
训练中,如果根据当前模型,query "q"已经与某“未曝光item”的匹配得分相当低了,给这对< >打上"伪负"标签,接下来的训练中,< >得分会变得越来越小,趋近0;
训练中,如果根据当前模型,query "q"已经与某“未曝光item”的匹配得分相当高了,给这对< >打上"伪正"标签,接下来的训练中,< >得分会变得越来越大,趋近1。
我们「不需要在训练之外,额外将“所有”候选item都打一遍分。筛选出那些可信的item,并给它们打上"伪负"或"伪正"标签,作为一个辅助task,是与主目标同步进行」。这个辅助task是-plogp形式的,公式非常简单,计算开销非常小。
所以,在我看来,「通过self-training给“未曝光”item打上“伪标签”的作法,属于一种自适应的hard negative采样策略,才是这篇文章最大的亮点」。我计划在我的召回项目中也实现self-training,相当于留下ESAM的“盒子”,把作者认为的ESAM的“珍珠”—Attribute Correlation Alignment还给作者。