FM模型的原理(上) | 推荐系统

七月在线实验室

共 9623字,需浏览 20分钟

 · 2021-04-08

文 | 七月在线
编 | 小七


解析:


既然你点开这篇文章了,我假设你是在某司做推荐系统的算法工程师。这个假设的正确率我估计大约在20%左右,因为根据我的经验,80%的算法工程师是很博爱的,只要标题里带有“模型/算法/深度学习/震惊/美女….”等词汇,他们都会好奇地点开看三秒,然后失望地关掉,技术性越强的反而越容易被关掉,很可能撑不过三秒。我说得没错吧?嘿嘿。为了骗点击,关于本文标题,其实我内心冲动里最想写下的震惊部风格标题是这样的:“连女神级美女程序媛看了都震惊!FM模型居然能够做这么大规模推荐系统的召回!”,然后打开文章后,文章配上的背景音乐缓缓地传来“路灯下昏黄的剪影,越走越漫长的林径…….”


嗯,好吧,我承认连我自己也忍不了上面的场景,主要是这首歌我还挺喜欢的,单曲循环快半个月了,标题风格比较毁歌的意境。请收拾好您此刻看到上述标题后接近崩溃的心情,不开玩笑了。让我再次活回到幻想中,就勉强假设你是位推荐算法工程师吧,您坚持说您不是?别谦虚,您很快就是了,请立即辞职去申请相关工作……如果您真的是推荐工程师,那么首先我想揪住您问个问题:一说起推荐模型或者推荐场景下的排序模型,您脑子里第一个念头冒出的模型是哪个或哪几个?

如果你第一念头冒出来的仍然是SVD/矩阵分解啥的,那么明显你还停留在啃书本的阶段,实践经验不足;


如果你第一念头是LR模型或者GBDT模型,这说明你是具备一定实践经验的算法工程师,但是知识更新不足。现在都9102年了,我们暂且把Wide&Deep/DeepFM这些模型抛开不提,因为在大规模场景下想要把深度推荐模型高性价比地用好发挥作用其实并不容易。我们退而求其次,如果现在您仍然不能在日常工作中至少尝试着用FM模型来搞事情,那只能说明一定概率下(30%到90%?),您是在技术方面对自我没有太高要求的算法工程师,未来您的技术之路走起来,我猜可能会比较辛苦和坎坷,这里先向身处2025年的另一位您道声辛苦啦。这是我对您的算法工程师之路的一个预测,至于这个预测准不准,往后若干年的经历以及时间会告诉您正确答案,当然我个人觉得付出的这个代价可能有点高。

假设你第一念头是在排序阶段使用FM模型、GBDT+LR模型、DNN模型,这说明你算是紧追技术时代发展脉络的技术人员,很好。那么,单独给你准备的更专业的新问题来了,请问:树上七只猴…..嗯,跑偏了,其实我想问的是:我们日常看到的推荐系统长什么样子,我相信你脑子里很清楚,但是能否打破常规?

比如下列两个不太符合常规做法的技术问题,您可以考虑考虑:


第一个问题:我们知道在个性化推荐系统里,第一个环节一般是召回阶段,而召回阶段工业界目前常规的做法是多路召回,每一路召回可能采取一个不同的策略。那么打破常规的思考之一是:是否我们能够使用一个统一的模型,将多路召回改造成单模型单路召回策略?如果不能,那是为什么?如果能,怎么做才可以?这样做有什么好处和坏处?

第二个问题:我们同样知道,目前实用化的工业界的推荐系统通常由两个环节构成,召回阶段和排序阶段,那么为什么要这么划分?它们各自的职责是什么?打破常规的另外一个思考是:是否存在一个模型,这个模型可以将召回阶段和排序阶段统一起来,就是把两阶段推荐环节改成单模型单环节推荐流程?就是说靠一个模型一个阶段把传统的两阶段推荐系统做的事情一步到位做完?如果不能,为什么不能?如果能,怎么做才可以?什么样的模型才能担当起这种重任呢?而在现实世界里是否存在这个模型?这个思路真的可行吗?

上面列的两个非常规问题,18年年末我自己也一直在思考,有些初步的思考结论,所以计划写四篇文章形成一个专题,主题集中在推荐系统的统一召回模型方面,也就是第一个问题,同时兼谈下第二个问题,每篇文章会介绍一个或者一类模型,本文介绍的是FM模型。这个系列,我春节期间写完了3篇,等我四篇都写完后,会陆续发出来,供感兴趣的“点开看三秒”同学参考。

不过这里需要强调一点:关于这两个问题,因为非常规,网上也也没有见到过类似的问题,说法及解决方案,所以没什么依据,文章写的只是我个人的思考结果,是否真能顺利落地以及落地效果存疑,还请谨慎参考。不过,我觉得从目前算法的发展趋势以及硬件条件的快速发展情况来看,单阶段推荐模型从理论上是可行的。我会陆续给出几个方案,建议从事中小型推荐业务的同学可以快速尝试一下。

下面进入正题,我会先简单介绍下推荐系统整体架构以及多路召回的基本模式,然后说明下FM模型,之后探讨FM模型是否能够解决上面提到的两个非常规问题。

工业推荐系统整体架构是怎样的



一个典型的工业级推荐系统整体架构可以参考上图,一般分为在线部分,近线部分和离线部分。

对于在线部分来说,一般要经历几个阶段。


首先通过召回环节,将给用户推荐的物品降到千以下规模;


如果召回阶段返回的物品还是太多,可以加入粗排阶段,这个阶段是可选的,粗排可以通过一些简单排序模型进一步减少往后续环节传递的物品;


再往后是精排阶段,这里可以使用复杂的模型来对少量物品精准排序。对某个用户来说,即使精排推荐结果出来了,一般并不会直接展示给用户,可能还要上一些业务策略,比如去已读,推荐多样化,加入广告等各种业务策略。之后形成最终推荐结果,将结果展示给用户。

对于近线部分来说,主要目的是实时收集用户行为反馈,并选择训练实例,实时抽取拼接特征,并近乎实时地更新在线推荐模型。这样做的好处是用户的最新兴趣能够近乎实时地体现到推荐结果里。

对于离线部分而言,通过对线上用户点击日志的存储和清理,整理离线训练数据,并周期性地更新推荐模型。对于超大规模数据和机器学习模型来说,往往需要高效地分布式机器学习平台来对离线训练进行支持。

因为粗排是可选的,对于大多数推荐系统来说,通常在线部分的主体分为两个阶段就够,第一个阶段是召回,第二个阶段是排序。因为个性化推荐需要给每个用户展现不同的信息流或者物品流,而对于每个用户来说,可供推荐的物品,在具备一定规模的公司里,是百万到千万级别,甚至上亿。所以对于每一个用户,如果对于千万级别物品都使用先进的模型挨个进行排序打分,明显速度上是算不过来的,资源投入考虑这么做也不划算。

从这里可以看出,召回阶段的主要职责是:从千万量级的候选物品里,采取简单模型将推荐物品候选集合快速筛减到千级别甚至百级别,这样将候选集合数量降下来,之后在排序阶段就可以上一些复杂模型,细致地对候选集进行个性化排序。

从上面在线推荐两阶段任务的划分,我们可以看出,召回阶段因为需要计算的候选集合太大,所以要想速度快,就只能上简单模型,使用少量特征,保证泛化能力,尽量让用户感兴趣的物品在这个阶段能够找回来;而排序阶段核心目标是要精准,因为它处理的物品数据量小,所以可以采用尽可能多的特征,使用比较复杂的模型,一切以精准为目标。

多路召回怎么做


目前工业界推荐系统的召回阶段一般是怎么做的呢?可以用一句江湖气很重的话来总结,请您系好安全带坐稳,怕吓到您,这句话就是:“一只穿云箭,千军万马来相见”。听起来霸气十足是吧?我估计看过古惑仔电影的都熟悉这句话,黑帮集结打群架的时候喜欢引用这句名言,以增加气势,自己给自己打气。如果和推荐系统对应起来理解,这里的“穿云箭”就是召回系统,而千军万马就是各路花式召回策略。



目前工业界的推荐系统,在召回阶段,一般都采取多路召回策略。上图展示了一个简化版本的例子,以微博信息流排序为例,不同业务召回路数不太一样,但是常用的召回策略,基本都会包含,比如兴趣标签,兴趣Topic,兴趣实体,协同过滤,热门,相同地域等,多者几十路召回,少者也有7/8路召回。

对于每一路召回,会拉回K条相关物料,这个K值是个超参,需要通过线上AB测试来确定合理的取值范围。如果你对算法敏感的话,会发现这里有个潜在的问题,如果召回路数太多,对应的超参就多,这些超参组合空间很大,如何设定合理的各路召回数量是个问题。另外,如果是多路召回,这个超参往往不太可能是用户个性化的,而是对于所有用户,每一路拉回的数量都是固定的,这里明显有优化空间。按理说,不同用户也许对于每一路内容感兴趣程度是不一样的,更感兴趣的那一路就应该多召回一些,所以如果能把这些超参改为个性化配置是很好的,但是多路召回策略下,虽然也不是不能做,但是即使做,看起来还是很Trick的。有什么好办法能解决这个问题吗?有,本文后面会讲。

什么是FM模型


什么是FM模型呢?我隐约意识到这个问题在很多人看起来好像有点过于简单,因为一说起FM,开车的朋友们估计都熟悉,比如FM1039交通台家喻户晓,最近应该经常听到交通台这么提醒大家吧:“…春节返程高峰,北京市第三交通委提醒您:道路千万条,安全第一条……”

一想到有可能很多人这么理解FM,我的眼泪就不由自主流了下来,同时对他们在心理上有种莫名的亲切感,为什么呢?不是说“缩写不规范,亲人两行泪”么。下面我郑重地给各位介绍下,FM英文全称是“Factorization Machine”,简称FM模型,中文名“因子分解机”。

FM模型其实有些年头了,是2010年由Rendle提出的,但是真正在各大厂大规模在CTR预估和推荐领域广泛使用,其实也就是最近几年的事。

FM模型比较简单,网上介绍的内容也比较多(比如这篇《FM模型理论和实践》:https://www.jianshu.com/p/152ae633fb00 ),细节不展开说它了。不过我给个个人判断:我觉得FM是推荐系统工程师应该熟练掌握和应用的必备算法,即使你看很多DNN版本的排序模型,你应该大多数情况会看到它的影子,原因其实很简单:特征组合对于推荐排序是非常非常重要的,而FM这个思路已经很简洁优雅地体现了这个思想了(主要是二阶特征组合)。

DNN模型一样离不开这个特点,而MLP结构是种低效率地捕获特征组合的结构,所以即使是深度模型,目前一样还离不开类似FM这个能够直白地直接去组合特征的部分。这是你会反复发现它的原因所在,当然也许是它本人,也许不一定是它本人,但是一定是它的变体。

既然谈到这里了,那顺手再多谈谈推荐排序模型。目前具备实用化价值的DNN版本的CTR模型一般采用MLP结构,看着远远落后CV/NLP的特征抽取器的发展水平,很容易让人产生如下感觉:CTR的DNN模型还处于深度学习原始社会阶段。那这又是为什么呢?因为CNN的特性天然不太适合推荐排序这个场景(为什么?您可以思考一下。为了预防某些具备某种独特个性特征的同学拿个别例子说事情,我先提一句:请不要跟我说某个已有的看上去比较深的CNN CTR模型,你自己试过效果如何再来说。这算是我的预防性回怼或者是假设性回怼,哈哈)。

RNN作为捕捉用户行为序列,利用时间信息的辅助结构还行,但是也不太适合作为CTR预估或者推荐排序的主模型(为什么?您可以思考一下,关于这点,我的看法以后有机会会提)。好像剩下的选择不多了(Transformer是很有希望的,去年年中左右,我觉得Self attention应该是个能很好地捕捉特征组合(包括二阶/三阶…多阶)的工具,于是,我们微博也尝试过用self attention和transformer作为CTR的主体排序模型,非业务数据测试的,当时测试效果和DeepFM等主流模型效果差不太多。

我现在回头看,很可能是哪些细节没做对,当时觉得没有特别的效果优势,于是没再继续尝试这个思路。当然貌似18年下半年已经冒出几篇用Transformer做CTR排序模型的论文了,我个人非常看好这个CTR模型进化方向),于是剩下的选择貌似只有MLP了,意思是:对于CTR或者推荐排序领域来说,不是它不想进入模型共产主义阶段,是大门关得太紧,它进不去,于是只能在MLP这个门槛徘徊。

在深度学习大潮下,从模型角度看,确实跟很多领域比,貌似推荐领域远远落后,这个是事实。我觉得主要原因是它自身的领域特点造成的,它可能需要打造适合自身特点的DNN排序模型。就像图像领域里有Resnet时刻,NLP里面有Bert时刻,我觉得推荐排序深度模型目前还没有,现在和未来也需要这个类似的高光时刻,而这需要一个针对它特性改造出的新结构,对此我是比较乐观的,我预感这个时刻一年之内还无法出现,但是很可能已经在路上,距离我们不远了。

又说远了,本来我们主题是召回,说到排序模型里去了,我往主车道走走。上面本来是要强调好好学好好用FM模型的。下面我从两个角度来简单介绍下FM模型,一个角度是从特征组合模型的进化角度来讲;另外一个角度从协同过滤模型的进化角度来讲。FM模型就处于这两类模型进化的交汇口。

从LR到SVM再到FM模型



LR模型是CTR预估领域早期最成功的模型,大多工业推荐排序系统采取LR这种“线性模型+人工特征组合引入非线性”的模式。因为LR模型具有简单方便易解释容易上规模等诸多好处,所以目前仍然有不少实际系统仍然采取这种模式。但是,LR模型最大的缺陷就是人工特征工程,耗时费力费人力资源,那么能否将特征组合的能力体现在模型层面呢?


其实想达到这一点并不难,如上图在计算公式里加入二阶特征组合即可,任意两个特征进行组合,可以将这个组合出的特征看作一个新特征,融入线性模型中。而组合特征的权重可以用来表示,和一阶特征权重一样,这个组合特征权重在训练阶段学习获得。其实这种二阶特征组合的使用方式,和多项式核SVM是等价的。虽然这个模型看上去貌似解决了二阶特征组合问题了,但是它有个潜在的问题:它对组合特征建模,泛化能力比较弱,尤其是在大规模稀疏特征存在的场景下,这个毛病尤其突出,比如CTR预估和推荐排序,这些场景的最大特点就是特征的大规模稀疏。所以上述模型并未在工业界广泛采用。那么,有什么办法能够解决这个问题吗?

于是,FM模型此刻可以闪亮登场了。如上图所示,FM模型也直接引入任意两个特征的二阶特征组合,和SVM模型最大的不同,在于特征组合权重的计算方法。FM对于每个特征,学习一个大小为k的一维向量,于是,两个特征 xi 和 xj 的特征组合的权重值,通过特征对应的向量 vi 和 vj 的内积< vi,vj>来表示。这本质上是在对特征进行embedding化表征,和目前非常常见的各种实体embedding本质思想是一脉相承的,但是很明显在FM这么做的年代(2010年),还没有现在能看到的各种眼花缭乱的embedding的形式与概念。所以FM作为特征embedding,可以看作当前深度学习里各种embedding方法的老前辈。

当然,FM这种模式有它的前辈模型吗?有,等会会谈。其实,和目前的各种深度DNN排序模型比,它仅仅是少了2层或者3层MLP隐层,用来直接对多阶特征非线性组合建模而已,其它方面基本相同。

那么为什么说FM的这种特征embedding模式,在大规模稀疏特征应用环境下比较好用?为什么说它的泛化能力强呢?参考上图说明。即使在训练数据里两个特征并未同时在训练实例里见到过,意味着 xi 和 xj一起出现的次数为0,如果换做SVM的模式,是无法学会这个特征组合的权重的。但是因为FM是学习单个特征的embedding,并不依赖某个特定的特征组合是否出现过,所以只要特征 xi 和其它任意特征组合出现过,那么就可以学习自己对应的embedding向量。于是,尽管 xi和xj 这个特征组合没有看到过,但是在预测的时候,如果看到这个新的特征组合,因为 xi 和 xj 都能学会自己对应的embedding,所以可以通过内积算出这个新特征组合的权重。这是为何说FM模型泛化能力强的根本原因。

其实本质上,这也是目前很多花样的embedding的最核心特点,就是从0/1这种二值硬核匹配,切换为向量软匹配,使得原先匹配不上的,现在能在一定程度上算密切程度了,具备很好的泛化性能。

从MF到FM模型


FM我们大致应该知道是怎么个意思了,这里又突然冒出个MF,长得跟FM貌似还有点像,那么MF又是什么呢?它跟FM又有什么关系?

请跟我念:“打东边来了个FM,手里提着一斤挞嘛;打西边来了个MF,腰里别着一个喇叭;提着一斤挞嘛的FM想要别着喇叭的MF腰里的喇叭……..”你要是能不打磕绊一遍念下来的话………你以为你就理解它们的错综复杂的关系了是吗?不,你就可以去学说相声了……



MF(Matrix Factorization,矩阵分解)模型是个在推荐系统领域里资格很深的老前辈协同过滤模型了。核心思想是通过两个低维小矩阵(一个代表用户embedding矩阵,一个代表物品embedding矩阵)的乘积计算,来模拟真实用户点击或评分产生的大的协同信息稀疏矩阵,本质上是编码了用户和物品协同信息的降维模型。

当训练完成,每个用户和物品得到对应的低维embedding表达后,如果要预测某个的评分的时候,只要它们做个内积计算,这个得分就是预测得分。看到这里,让你想起了什么吗?身为推荐算法工程师,我假设你对它还是比较熟悉的,更多的就不展开说了,相关资料很多,我们重点说MF和FM的关系问题。MF和FM不仅在名字简称上看着有点像,其实他们本质思想上也有很多相同点。那么,MF和FM究竟是怎样的关系呢?

本质上,MF模型是FM模型的特例,MF可以被认为是只有User ID 和Item ID这两个特征Fields的FM模型,MF将这两类特征通过矩阵分解,来达到将这两类特征embedding化表达的目的。而FM则可以看作是MF模型的进一步拓展,除了User ID和Item ID这两类特征外,很多其它类型的特征,都可以进一步融入FM模型里,它将所有这些特征转化为embedding低维向量表达,并计算任意两个特征embedding的内积,就是特征组合的权重,如果FM只使用User ID 和Item ID,你套到FM公式里,看看它的预测过程和MF的预测过程一样吗?

从谁更早使用特征embedding表达这个角度来看的话,很明显,和FM比起来,MF才是真正的前辈,无非是特征类型比较少而已。而FM继承了MF的特征embedding化表达这个优点,同时引入了更多Side information作为特征,将更多特征及Side information embedding化融入FM模型中。所以很明显FM模型更灵活,能适应更多场合的应用范围。

鉴于MF和FM以上错综复杂剪不断理还乱的关系,我推论出下面的观点(个人意见):
其一:在你有使用MF做协同过滤的想法的时候,暂时压抑一下这种冲动,可以优先考虑引入FM来做的,而非传统的MF,因为可以在实现等价功能的基础上,很方便地融入其它任意你想加入的特征,把手头的事情做得更丰富多彩。

其二:从实际大规模数据场景下的应用来讲,在排序阶段,绝大多数只使用ID信息的模型是不实用的,没有引入Side Information,也就是除了User ID/Item ID外的很多其它可用特征的模型,是不具备实战价值的。原因很简单,大多数真实应用场景中,User/Item有很多信息可用,而协同数据只是其中的一种,引入更多特征明显对于更精准地进行个性化推荐是非常有帮助的。而如果模型不支持更多特征的便捷引入,明显受限严重,很难真正实用,这也是为何矩阵分解类的方法很少看到在Ranking阶段使用,通常是作为一路召回形式存在的原因。

简单谈谈算法的效率问题
从FM的原始数学公式看,因为在进行二阶(2-order)特征组合的时候,假设有n个不同的特征,那么二阶特征组合意味着任意两个特征都要进行交叉组合,所以可以直接推论得出:FM的时间复杂度是n的平方。但是如果故事仅仅讲到这里,FM模型是不太可能如此广泛地被工业界使用的。因为现实生活应用中的n往往是个非常巨大的特征数,如果FM是n平方的时间复杂度,那估计基本就没人带它玩了。

对于一个实用化模型来说,效果是否足够好只是一个方面,计算效率是否够高也很重要,这两点是一个能被广泛使用算法的一枚硬币的两面,缺其中任何一个可能都不能算是优秀的算法。如果在两者之间硬要分出谁更重要的话,怎么选?

这里插入个题外话,是关于如何做选择的。这个话题如果你深入思考的话,会发现很可能是个深奥的哲学问题。在说怎么选之前,我先复述两则关于选择的笑话,有两个版本,男版和女版的。

男版是这样的:“一个兄弟跟我说他最近很困惑,有三个姑娘在追他,一直犹豫不决,到底应该选哪个当女朋友呢?一个温柔贤惠,一个聪明伶俐,另外一个肤白貌美。太难选…..三天后当我再次遇到他的时候,他说他做出了选择,选了那个胸最大的!”

女版是这样的:“一个姐妹跟我说她很困惑,最近有三个优秀的男人在追她,一直犹豫不决,到底应该嫁给谁呢?一个努力上进,一个高大帅气,另外一个脾气好顾家。实在太难选…..三天后当我再次遇到她的时候,她说她做出了选择,选了那个最有钱的!”

参考这个模版,算法选择版应该是这样的:“一个算法工程师一直犹豫不决该选哪个模型去上线,他有三个优秀算法可选,一个算法理论优雅;一个算法效果好;另外一个算法很时髦,实在太难做决定…..三天后当我再遇见他的时候,他说他们算法总监让他上了那个跑得最快的!”

怎么样?生活或者工作中的选择确实是个很玄妙的哲学问题吧?这个算法版的关于选择的笑话,应该已经回答了上面那个还没给答案的问题了吧?在数据量特别大的情况下,如果在效果好和速度快之间做选择,很多时候跑得快的简单模型会胜出,这是为何LR模型在CTR预估领域一直被广泛使用的原因。

而FFM模型则是反例,我们在几个数据集合上测试过,FFM模型作为排序模型,效果确实是要优于FM模型的,但是FFM模型对参数存储量要求太多,以及无法能做到FM的运行效率,如果中小数据规模做排序没什么问题,但是数据量一旦大起来,对资源和效率的要求会急剧升高,这是严重阻碍FFM模型大规模数据场景实用化的重要因素。

再顺手谈谈DNN排序模型,现在貌似看着有很多版本的DNN排序模型,但是考虑到上面讲的运算效率问题,你会发现太多所谓效果好的模型,其实不具备实用价值,算起来太复杂了,效果好得又很有限,超大规模训练或者在线 Serving速度根本跟不上。除非,你们公司有具备相当强悍实力的工程团队,能够进行超大数据规模下的大规模性能优化,那当我上面这句话没说。

我对排序模型,如果你打算推上线真用起来的话,建议是,沿着这个序列尝试:FM-->DeepFM。你看着路径有点短是吗?确实比较短。如果DeepFM做不出效果,别再试着去尝试更复杂的模型了,还是多从其它方面考虑考虑优化方案为好。有些复杂些的模型,也许效果确实好一些,在个别大公司也许真做上线了,但是很可能效果好不是算法的功劳,是工程能力强等多个因素共同导致的,人家能做,你未必做的了。至于被广泛尝试的Wide &Deep,我个人对它有偏见,所以直接被我跳过了。当然,如果你原始线上版本是LR,是可以直接先尝试Wide&Deep的,但是即使如此,要我做升级方案,我给的建议会是这个序列:LR—>FM-->DeepFM—>干点其他的。



限时1元秒杀


两大实战项目:基于FM的电影推荐系统 + 基于libfm的电商CTR预估

配套课程服务:共学社群答疑 + 全套课件代码 + CPU云平台

理论和实践完美结合,每个算法配套项目实战代码完全学会深度学习的本质和应用。

浏览 3
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报