自从我上次在知乎回答了问题《机器学习中较为简单的算法有哪些?》,很多同学私信我询问我FM算法在推荐系统中的应用细节,索性今天就专门写一篇文章,仔细聊一聊FM这把“推荐算法中的瑞士军刀”。正文开始之前,我说几句题外话。
第一,谈谈本文的标题。机器学习算法中的瑞士军刀,可不是随便起的。以前Xgboost因为方便易用、功能广泛、性能优异,被誉为Kaggle比赛中的瑞士军刀。因为同样的优点,我将FM称作“推荐算法中的瑞士军刀”,其中有两个含意:
第二,本文主要介绍FM应用于推荐系统中的一些实战经验,需要读者对FM有一定的基础。对FM还不太了解的同学,我推荐以下参考资料:
减少为
),更像是为了Kaggle专门训练的比赛型选手。这就好比,奥运会上的射击冠军,未必能够胜任当狙击手一样。
接下来的文字中,我首先梳理一下FM的特点,再按照精排、召回、解释模型的顺序,介绍FM在各个业务中的技术细节,比如:如何无偏地收集样本、如何设计模型、如何部署上线。细心的读者可能注意到,这里面没有“粗排”的内容。我们尝试过粗排模型(并非FM,而是双塔+蒸馏),线上收益并不明显,所以在就里就不详细叙述了,感兴趣的同学可以参考阿里的论文《Privileged Features Distillation at Taobao Recommendations》。
众所周知,推荐算法有三个应用领域:召回、粗排、精排。推荐算法千千万,但是有的算法只能用于召回,有的算法只能用于排序(吐槽一下,有本“著名”的书《Deep learning for matching in search and Recommendation》,其中的很多算法,比如DIEN之类的,其计算复杂度只能用于排序,但是很多人在翻译的时候将matching翻译成召回,简直是开玩笑)。像FM这样实现三个领域全覆盖的多面手,目前为止,孤陋寡闻的我尚不知道有第二个。
特别是FM用做召回时,表现更加优秀。FM召回的主流作法,是用生成的user embedding直接查找最相近的item embedding。除此之外,利用已经生成了的user/item embedding,还有更多的玩法,比如,查找相似item的“看了又看”功能、用户聚类推荐功能、根据item找潜在用户的Push功能。而且,FM对新用户、新物料也非常友好。实现一个FM召回,就能够完成u2i, i2i, i2u, u2u2i四种召回方式,还包括对新用户、新物料的冷启动。性价比如此之高,即使在很多大厂,FM也是主力召回模型,果然是很香了。
另外,虽然DNN这样的屠龙刀,威力强大,但是有一个缺点,就是模型黑盒化比较严重,可解释性非常差。这方面,FM的优势就非常明显了。FM能够将模型的最终打分拆解到每个特征和特征组合上,从而能够让我们分析出到底是哪些因素提高或拉低了模型的打分。最重要的是,区别于GBDT那种只能提供特征的全局重要性,FM提供的重要性是针对某一个、某一群样本的,使我们能够做更加精细化的特征分析。
对于推荐系统的两大永恒主题,“记忆”与“扩展”,FM也能实现全覆盖。
现在DNN是推荐领域的宠儿,LR/FM/GBDT这样的传统机器学习算法,被打入冷宫,不招人待见。
DNN这样的屠龙刀,虽然性能优异,但是它有一个致命缺点,就是上线困难。训练的时候,各位调参侠,把各种酷炫的结构,什么attention, transformer, capsule,能加上的都给它加上,看着离线指标一路上涨,心里和脸上都乐开了花,却全然无视旁边的后端工程师恨得咬紧了牙根。模型越复杂,离线和线上指标未必就更好,但是线上的时间开销肯定会增加,超时严重的时候,你那离线指标完美的模型压根没有上线的机会。虽说,目前已经有TF Serving这样的线上serving框架,但是它也不是开箱即用的,也需要一系列的性能调优,才能满足线上的实时性要求。
所以,如果你身处一个小团队,后端工程人员的技术能力不强,DNN的线上实时预测,就会成为一个难题,这个时候,FM这样的传统机器学习算法,就凸显出其优势。
如果只做CTR预估,不涉及CVR这样的级联目标,精排样本的选择是比较清晰的,拿“曝光点击做正样本,曝光未点击做负样本”是业界的共识。
精排能够利用的特征是最丰富的,需要分为三大类
正如我在《推荐算法的"五环之歌"》一文中所论述的,ID特征才是推荐系统中的一等公民,在离线训练、线上服务时都具备一系列优势,所以FM中所有特征都ID化。
由于我们使用的都是ID类特征,所以FM的预测公式可以简化为
代表第i个特征的一阶权重
分别是i-th/j-th特征的隐向量,
是两向量的点积
以上公式又可以继续推导如下,其中
代表两向量按位相乘,ReduceSum
表示将一个向量所有位置上的元素相加
=
=
这个公式避免了原始公式中两两特征交叉,将时间复杂度由
降低为O(n),而且n还是样本中的非零特征数。虽然算法的整体特征空间是上亿级别,但是由于推荐场景中特征非常稀疏,每个样本的n都是非常有限的,因此训练与预测的速度都非常快 。
得到logit之后,我们就可以与样本的label(i.e., 是否点击)计算binary cross-entropy loss,并通过SGD优化,从而得到各特征的一阶权重
和隐向量
。
精排打分时,也采用logit=
的公式,时间复杂度只有O(n),n是有限的非零特征的数目,能保证线上预测的实时性。
但是,我们还可以继续优化。由于线上打分时,是将某个用户与一批候选item,喂入ranker,因此那一个用户的特征只需要抽取、计算一遍,在给多个item打分时复用。
logit=
、
、
,是对所有user特征的处理,只需要计算一遍。
、
、
,是对所有item特征的处理,需要针对每个候选item计算一遍。但是给一批item打分时,这部分计算可能通过多线程并行完成。
我曾经提出一个观点,“排序是特征的意义,而召回是样本,特别是负样本的艺术”,足见样本选择对召回算法的重要性。
在遵循“随机采样负样本”这一基本原则之外,还需要注意两点。
任何一个推荐系统,都难逃“2-8”定律的影响,即20%的热门item占据了80%的曝光量或点击量,因此正样本中,绝大部分是热门item。如果不加以打压,将导致每个用户的召回结果,都集中于少数热门item,从而失去个性化。为了打压热门item,需要我们在生成正负样本时,针对热门item采取截然相反的采样策略
" 成为正样本的概率=
,
)=
,
)是点击过第i个item的用户总数
以上对热门item成为正、负样本时的采样加权公式,是从word2vec中借鉴而来。因为,Language Model中根据“上下文”预测“缺失词”的问题,其实就可以看成一个召回问题。所以,word2vec中处理高频词的方式,也可以拿来为我们所用,在召回中打压高热item。具体细节,可以参考我的知乎回答《推荐系统传统召回是怎么实现热门item的打压》。
<user,item>的匹配度可以分成三个档次
如何选取hard negative,业界有不同的做法。Airbnb是根据业务逻辑来选取hard negative
当业务逻辑没有那么明显的信号时,就只能依靠模型自己来挖掘。Facebook的EBR与百度Mobius的作法非常相似,都是用上一版本的召回模型筛选出"相似度没那么高"的<user,item>对,作为额外负样本,来增强训练下一版本召回模型。具体做法上,又分online和offline两个版本
在线筛选
假如一个batch有n个正样本对,<
>,那么
的hard negative是利用上一轮迭代得到的召回模型,评估
与同一个batch的除
之外的所有
的匹配度,再选择一个与
最相似的作为hard negative。
离线筛选
接下来会说到,线上部署FM召回模型时,需要周期地在线下计算好几百万候选item的embedding,然后灌入FAISS建立索引,等待user embedding来检索。因为user embedding是在线生成,而item embedding是离线生成,二者分离造成我们在训练、预测时,不能使用任何user与候选item之间的统计交叉特征。这一点与FM精排视“统计交叉特征”为最重要特征,有着显著不同。
如前文所述,由于召回中的负样本大部分是通过随机采样得到的,它们的"negative label"是含有噪声的。在这种情况下,再照搬精排使用binary cross-entropy loss追求“预估值”与“label”之间的“绝对准确性”,就有点强人所难了。所以,召回算法往往采用Pairwise LearningToRank(LTR),建模排序的“相对准确性”。即模型优化的目的,不是为了拟合"user与负样本item的匹配程度越低越好",而是追求“user与正样本item的匹配程度,要远远高于,user与负样本item的匹配程度”。
所以,与精排模型中的每个训练样本为<user, item, label>的形式不同,训练召回模型时的每个训练样本为一个三元组,即<user, item+, item->。而模型设计,又拆分成两个子问题:(1)如何定义user与item的匹配程度?(2)如何定义“远远高于”?
对于第一个问题,FM召回当然是采用FM公式了。
MatchScore(user, item)=
、
、
,是对所有user特征的处理。因为每条样本中,user是共享的,所以只需要计算一遍。
、
、
,是对所有item特征的处理。每条样本中,需要分别代入item+和item-进行计算。
细心的同学会发现,常见的召回模型中采用“user embedding与item embedding做点积或cosine”来计算匹配度,以方便利用FAISS进行快速近邻检索,担心以上公式训练出来的模型无法与FAISS兼容。不用担心,接下来讲线上服务的时候,我们会发现以上完整的FM公式也可以转变成两个向量点积的形式,同样可以利用FAISS快速检索。
一种是采用margin hinge loss,即user与正样本item的匹配程度,要比,user与负样本item的匹配程度,高出一定的阈值。写成公式,就是
=
但是,这个公式里面又多出一个超参margin需要调节,因此我主要使用如下的BPR Loss。
BPR Loss的思想是计算"给user召回时,将item+排在item-前面的概率",
。因为一个三元组<user, item+, item->的ground-truth label永远是1,所以将
喂入binary cross-entropy loss的公式,则有
=
上文已经提到,训练时,我们用完整的FM公式来描述User与Item之间的匹配度。但是,在线上服务时,我们必须将匹配度描述成点积或cosine的形式,才能利用FAISS完成在百万、千万级物料库中的快速召回。这个"FM→点积"的公式转化如下图所示。
这时还可以做两个简化:
这时,有一种方案就是,忽略公式中的蓝色部分,线上服务时只保留user embedding与item embedding的点积。这样做,也不是不行,但是效果不是特别好。因为用户喜欢的,未必一定是与自身最匹配的,也包括一些自身性质极佳的item(e.g.,热门item),所以,非常有必要将"所有Item特征一阶权重之和"和“所有Item特征隐向量两两点积之和”考虑进去,但是也还必须写成点积的形式。
解决方法是将user/item embedding都增广一维,如下图公式所示。
除了以上最常用的u2i召回,在我们得到user embedding和item embedding之后,还有很多其他玩法
需要特别指出的是,很多召回,比如基于ALS的矩阵分解、Item CF等,都有冷启动问题,尽管单路召回性能很好,但是由于能够覆盖的用户、物料有限,对大盘指标的影响也很有限。而FM召回的优势在于,它对新用户、新物料都非常友好。
如果说,如果要追求模型的表达能力,还要靠DNN这样的大杀器,FM只能算“模型能力+工程复杂度”综合考虑下一个不错的折中方案。但是,如果论模型的可解释性,DNN模型就难望FM的项背了。不仅如此,FM在解释性上最大优点,是能够提供针对一个或一群样本上的“局部特征重要性”。
首先,先解释一下“全局特征重要性”与“局部特征重要性”两个概念。
为什么“局部特征重要性”更重要?因为数据分析的精髓就在于指标的拆解、下钻。
FM允许我们将最终预测得分,拆解到各feature和feature组合上,从而能够提供“局部特征重要性”。但是,推荐场景下,feature空间有上亿维,而且高度稀疏,拆解到feature与feature组合级别,计算量太大,而且即便能够拆解成功,拆解后的信息也太琐碎,让人无从分析。因此,更合理的解决方案是拆解到field级别,因为field最多几百个,算上field组合也不过几万个,无论是计算规模,还是分析规模,还是可以接受的。(有些同学对field的概念不太熟悉,这里做一下简单说明。比如“一级分类”算是field,而“军事”、“历史”这样的具体的分类值是这个field下的feature。)
拆解方法也很简单:针对每一个样本,将这个样本的feature embedding按所属field分组,同一field下所有feature embedding相加得到field embedding,然后两两field embedding做点积,这样就将样本得分拆解到了field和field pair的维度上。以上算法可以在Spark中分布式运行。
单独看一个样本上的拆解结果,可能有很多噪声。我们可以选取一组样本进行得分拆解,然后将这组样本在各个field pair上的得分进行统计,比如绘制热力图,就能看出哪些field pair对这组样本至关重要。
现在线上主力排序模型一般都已经是DNN了,基于FM的特征重要性分析方法,还有用吗?
我们认为,特征重要性是客观存在的,不同模型对重要特征的发掘、利用,只有量上的不同,没有本质上的不同。如果通过FM得分拆解,发现一组field对某个样本非常重要,DNN大概率与会同意这一判断。
反之,如果一组我们认为非常重要的field,FM拆解结果却显示不重要,大概率应该是样本、特征的处理上出了问题,同样也会对DNN造成负面影响。我们就曾经遇到过这样的现象,发现一组field的得分不如预期,经查是特征分桶不太合适。修复之后,DNN的性能也得到提升。由此可见,FM解释模型,也同样适用于DNN。
虽然如今不如DNN、GNN那般受人关注,但是FM凭借其功能齐全、性能优异、便于上线和解释的优点,可称得上是推荐算法界中的瑞士军刀。正如同,虽然核武器、航母、坦克、隐身飞机这样的大杀器才是各国武库中的明星,但是瑞士军刀仍然被很多国家的军队采购为制式装备。各位炼丹调参侠们,在苦练倚天剑、屠龙刀的同时,一把小巧的瑞士军刀,相信我,你值得拥有。