发布于:2019 年 4 月 24 日 08:00
推荐系统几乎已经深入到人们生活的方方面面,其背后的算法也在不断地迭代更新。FM 和 FFM 模型是最近几年提出的模型,拥有在数据量较大并且特征稀疏的情况下,仍然能够得到优秀的性能和效果的特性。
新浪微博 AI Lab 资深算法专家张俊林,在 2018 年全球人工智能与机器学习大会 AICon 的演讲中,着重探讨了几种排序模型的发展及原理。AI 前线将本场演讲内容进行了整理,希望能够对读者有所帮助。
今天我们主要介绍一下,FFM 和它的深度学习模型版本。今天我要跟大家分享的一个大的提纲。
首先,我会给大家介绍一下大规模推荐系统的整个流程框架和其中一些比较核心的技术点是什么。
第二,因为我们知道,做推荐系统模型会面临两个选择,就是说传统的线性排序模型,所以我会简单地介绍一下模型的发展历程,包括它们各自的特点。
第三,FFM 模型有它的优点,也有它的问题,所以针对它的问题,我会介绍一个改进的版本,叫双线性的 FFM 模型。
另外,我也会大致介绍一下,典型的深度学习模型有哪些,他们各自的特点是什么、使用场景是什么。
最后,我会介绍一下 DeepFFM,可以认为是我们针对 FFM 做的神经网络的改进版本,至于它是怎么做得,效果怎么样,我在后面会重点介绍。
首先进入第一部分,大规模推荐系统的介绍。
推荐系统大家实际都非常熟悉了,因为大家现在都用手机 App,我觉得只要是上网的话,70% 的时间你一定会受到推荐系统的影响,只不过你可能没有意识到它的存在。
举几个典型的例子:网易云音乐的音乐推荐,我个人觉得网易音乐的推荐做得是相当不错的;此外还有豆瓣的电影推荐、阿里商品推荐等等,我这里只列了几个比较典型的,主要是大家可能平常比较关注的一些场景。
因为我来自于微博,所以我简单地介绍一下,在微博有哪些场景是应用推荐、CTR 以及排序任务的。
典型的有三个场景。你如果刷微博就会看到,第一个就是关系流 Feed 排序。从 2013 年开始我就在微博工作,当时的版本是按时间排序,但后来因为国外的 Facebook、Twitter 都陆续上了机器学习的 ranking 机制,所以说现在微博的关系流实际是加了机器学习排序的。可是时间因素在其中还是起着很关键的作用,这种场景对于机器学习模型虽然有使用,但是有限制,限制就是排序对时间权重还是比较高。
另外一个是热门流。这个是比较典型的、完全个性化的一个流,因为它给用户的推荐是不需要用户关注的,只要认为通过用户过去的点击行为,判断其可能对什么感兴趣,就会给用户推荐,这是一个完全个性化的信息流。
此外,还有正文页的推荐。用户点开一个微博进去之后,下面会推荐一个用户可能感兴趣的微博,这是一个附属的推荐场景。
这三个场景在微博上是典型的信息流排序,或者是推荐的使用场景。
我们以微博的推荐系统为例,来简单介绍一下:现在工业级的大规模推荐系统是怎么来做架构和流程的。
尽管我说是以微博为例,但是我可以肯定的说,目前工业界 90% 的推荐系统就是这个结构,只不过可能在有些具体算法和实施方式上有些区别,但是架子大都一个架子。
我简单捋一下这个过程。
首先它分为两大部分,最上面那部分是在线推荐部分,底下这两行是离线部分。
先说在线部分。我们习惯把微博叫做物料库,实际就是 item,物料库的规模会比较大,一般会先走个召回,为什么要走召回?做过推荐的人都很清楚:要给微博的用户认可一个人在热门流推出任何一个个性化的序列,假设一天新发的微博条数以亿计算,再加上历史的条数,任何一个人登上微博去刷热门流,都需要算几亿条给这一个人,如果不部署召回,直接部署模型,这个计算量是很巨大的,速度根本提升不起来。
召回是很简单,就是为了把个性化推荐 item 数目降下来。召回等于说把用户可能感兴趣的物料进行一些缩减,缩到一定的范围里面,如果用户觉得还比较多,部署一个粗排序,把简单的排序模型再筛选一下,数量就可以往下减一减,然后进入精排。因为到这一步已经经过两轮筛选,对于某个用户来说,剩下的物料已经不多了,所以精排的意思就是:在此基础上可以加一些复杂模型,精制地给用户排一排序,把用户真正感兴趣的内容排到前面去。
之后还有业务逻辑。比如说要把已读的微博内容过滤掉,怎么考虑推荐结果的多样性以及各方面的业务逻辑?我们会捕捉用户行为,举个例子,用户看过哪些微博、反馈过哪些微博、互动过哪些微博,这些行为就被收集起来,对于实时的用户行为,我们一般会部署一个实时的模型,可以实时地更新实时模型,体现在了召回可以改成实时的模式,包括 ranking 可以改造成实时的模式。
所谓实时的意思就是:用户刷了一条微博,或者互动了一条微博,立刻就在刷出下一条微博的时候,体现出用户刚才这个行为了。当然还可以往后发展,比如我们会计算一个离线模型,因为这个模型它的训练数据更充分、更精准。通过这种方式,我们会定期地更新线上的这三个模型,这就是典型的工业界做大规模推荐系统的整体流程。
正如我上面所讲的,这个框架是所有做推荐的公司的基本框架,只不过方法不同而已。
现在我们来细致地看一下在线部分。
我刚才说了三个过程:召回、粗排、精排,但是最常见的还是两个阶段的,就这张图展示的。
第一阶段,召回,第二阶段,排序。我再重复一下:召回是用来做什么的,它的特点是什么,ranking 在干什么,我觉得搞推荐系统,先要把这些事搞明白。
召回阶段
我刚刚也提到了,首先是因为面临的侯选数据集非常大,而最根本的要求是速度快,因为要求速度快,所以就不能部署太复杂的模型。另外要使用少量的特征。这两个特征是怎么演示出来的,是因为我为了速度快的目的,做的一些妥协,这是召回阶段的特性。召回阶段要掌握一点:怎么快怎么来。简单来说,召回会把大量的物料减到几百的量级,然后扔给后面的 ranking 阶段。
排序阶段
它的召回特性完全不一样,ranking 阶段只有一点需要记住:模型要够准,这是它的根本。此外,因为这一阶段处理的数据量比较少了,所以就可以部署复杂模型,就可以使用我能想到的特征,但归根结底是为了一件事:怎么排的准?
CTR 模型、推荐模型发展的历史很久了,举个例子,百度搜索部署广告系统,同时也部署了 CTR 的预估系统,到目前为止应该有十几到二十年的经验了。那么我们要归纳一下,公司做推荐的话,模型是按照一个什么样的轨迹发展的。
举个例子,什么叫规则?这个规则可能和你想的规则不太一样,比如说给用户推荐最热门的内容,这是一种规则,此外还可以添加很多其他的规则。规则的好处是什么?特别简单,如果想通过一个规则去做推荐,三天就能上线,效果也不会特别差,训练速度快,而且还可能不需要有监督地去训练。但是如果后来的规则越来越多的话,问题就出现了,它们会相互冲突,系统的综合效果,很难往上提升,因为对于系统来说,很难有个明确的优化目标,这是问题所在。
除了规则以外,业内一般会用 LR,也就是逻辑回归。LR 之后,一般就是 LR 加 GBDT。所有的 CTR 模型,它的核心就是特征组合,是怎么解决特征组合的问题,它的发展路径就按照这个方向发展。
LR 的特性是可以人工做特征组合,但是人工做特征组合有个问题:需要靠相当大的团队人力才可以做。那么 LR 跟 GBDT 比有什么好处?GBDT 可以半自动化地做一些特征组合,这就从特征组合进化的角度来讲这个模型。
再往后发展就是 FM。FM 跟 LGBDT 区别又是什么?它可以全自动化地做特征组合。目前行业都在讲用 DNN 深度学习来做同样的事,那么从特征组合的角度讲,又有什么新的特点呢?很简单,我们用 FM 的时候,因为一般计算量的问题,只做二级特征组合,那么什么叫二级特征组合?很好理解,举个例子,比如两个特征,一个特征是性别,假设“性别 = 女”,另外一个特征是时间,假设“时间 = 双十一”,这两个特征如果组合到一起,你会发现是一个非常强的指示,是用户会不会买东西的一个特征,这就叫二阶组合特征,因为有两个特征进行组合。
那么 DNN 相对 FM 有什么好处?它可以捕获三阶特征、四阶特征、五阶特征;它也包含信息,FM 一般来说很难捕获高阶的特征,DNN 典型的特点是可以捕获更高阶的特征。按照这个路线往后捋,你要把握核心的一点是:特征组合自动化,包括更高阶的特征怎么融合进去,这是 CTR 模型进化的总体方向。
我再把后面要讲的内容捋一捋:
第一部分我会讲线性的排序模型;
第二部分会介绍一下经典的线性模型有哪些,特性是什么;
第三部分会讲我们针对 FFM 提出了改进的模型;
第四部分,我们讲一下地图 ranking 模型,目前来说,有两种演化的分支,一个就是以 W&D 为起点的演化分支,另外一个以 DeepCross 为起点的演化分支;
第五部分,也是最后一部分,我们对第一个演化分支也做了一个改进模型,核心思想是,FFM 模型怎么做成深度网络版本的,我们给出了一个新的版本。
我先介绍一下线性模型。大家可能都有些机器学习的基础,这应该是有监督模型中最简单的一个。
所谓线性模型,比如说要做 CTR,很好理解,看这个公式:
xi 就是某个特征值,意思要给每个特征给个权重;wi 给它个权重,最终的预测值就是所有的特征值乘以这个权重,加起来求和,这就是线性。
一般我们做 LR,会套一个 sigma 的函数,也就是上图中黄色的曲线,因为线性模型取值范围已经不可控,可以无限大,所以没法用。通过 S 形函数把它压到 0 和 1 之间,我就可以判断,是正面的结果还是负面的结果,LR 就是这样的过程。
那么线性模型有什么优点和缺点呢?因为它简单,所以好理解,上线快,速度快,这是它典型的优点。尽管我们到了深度学习时代了,但事实上,很多公司还在用 LR,因为它确实很好用。但它也有问题,我刚才讲了一句话:所有的 CTR 模型,核心是特征组合,但是上图的公式里看不到任何特征组合的迹象:单个特征配置权重,特征间的关系没有被发现,这就是 LR 最大的一个缺点。线性模型有这个问题,它不能够捕获特征组合,所以要改造一下这个公式,把特征组合揉进来。
特征组合要怎么组合?任意两个特征的组合,可以把一个特征组合当作一个新特征,但既然它是新特征,它也要学个权重,下图公式中标红的wi,j就是这个特征组合的权重。
我们把特征组合显式的,简单的揉进了这个公式,所以它的好处是:现在能够捕获两两特征组合。那么它也有问题吗?刚才我们改进的模型本质是 SVM,所以应该再改一改,它的问题是特征组合的泛化能力弱,于是我们进一步进行了修改。
前面还是一样,就是 LR 模型,后面的也是任意两个特征组合,和刚才公式唯一的区别在:原先的 wi,j,换成了 vi 和 vj 的点积。vi 和 vj 又是什么含义呢?vi 的意思:对于 xi 这个特征来说它会学到一个 embedding 向量,特征组合权重是通过各自的 embedding 的内积呈现的,因为它内积完就是个数值,可以代表它的权重,这就是 FM 模型。
SVM 泛化能力弱,FM 的泛化能力强。如果要使用 SVM 的算法,因为 wi,j 没有见过新的组合,要是在应用场景里面碰见 xi,xj 组合,这个 wi,j 一定是 0,意思处理不了这个组合,这叫泛化能力弱。
但是换成 FM 模型就可以解决这个问题。在训练集里面没有见过 xi,xj 的组合,没有关系,xi 要学一个 embedding,不需要依赖 xj 的存在,它自己可以学出 embedding 来。在现实场景中遇见了这个特征组合,用那两个点积不会是 0,这就代表有效地赋予它权重,同时也说明了为什么 FM 泛化能力更强。
在 FM 之后,我们再改进一个新版本,就是 FFM 模型。我先定性地说下这个模型:它的效果比 FM 好,但是问题在于,参数量太大。
首先, FFM 模型的特性是什么?
举例来说,有三个特征 fields,这是一个在线投广告的应用场景,比如说我要往 ESPN 这个网站投广告,第一个特征 Publisher 是一个网站,第二个特征是这个广告主(Advertisor)是谁?本例中假设是 Nike;第三个特征,阅读者(Gender)是谁?阅读者的性别是男性(male);那么他会不会点击?这个案例中是会点击;那么我们在这个例子上再想,FFM 在做什么事?
首先这个公式做了任意两个特征组合,它的特性是要把任意一个特征学成 embedding,这就是刚才讲的 FM 的做法,那么 FFM 是怎么做的呢?
FFM 是 FM 的一个特例,它更细致地刻画了这个特征。首先它做了任意两个特征组合,但是区别在于,怎么刻划这个特征?FM 只有一个向量,但 FFM 现在有两个向量,也就意味着同一个特征,要和不同的 fields 进行组合的时候,会用不同的 embedding 去组合,它的参数量更多。对于一个特征来说,原先是一个 vector,现在会拓成 F 个 vector,F 是特征 fields 的个数,只要有跟它任意组合,就有一个 vector 来代表,这就是 FFM 的基本思想。
对于 FFM 的某个特征来说,会构造 F 个 vector,来和任意其他的 fields 组合的时候,各自用各自的。它有什么特点呢?首先,FFM 相对 FM 来说,参数量扩大了 F 倍,效果比 FM 好,但是要真的想把它用到现实场景中是有问题的,而问题同样在于参数量太大。参数量太大导致做起来特别耗内存,特别慢,所以目标是把参数量降下来,并且效果又能达到 FFM 的效果。于是我们改了一个新模型出来,叫双线性 FFM 模型。
下面我们介绍一下双线性 FFM 怎么做的。这个图基本就显示原理了:
因为每个特征现在有 F 个 vector 来表示它的参数空间,因为 F 个 vector 是跟随每个特征增长的,由于特征数是非常大的,所以它的参数量很大。能不能把跟特征走的抽出来,大家一起用这个参数,如果你一起用的话,能够共享这个参数,你就能把参数量降下来,这就是我们讲的双线性 FFM 的核心思想。vi,vj 还是跟 FM 一样,还是用一个 vector 来表达,但是把两个交互的复杂特性放在大家共享参数里面去学,这就是双线性 FFM 的核心思想。
我刚才讲了一个简单的思路,理论上里面还有些变化点,比如这个 W 怎么设计?这是有些学问在里面的。
类型 1,不论有多少个特征,都用同一个 W,这是参数量最小的一种形式。它的参数量是 K×K,K 就是这个 embedding 的 Size。
还有什么改进的方法吗?能不能每个 fields 给一个不同的 W 用呢?应该是可以的,我们在类型 2 就用到了这个方法,有 12 个 Fields,就有 12 个 W,各自学各自的。
类型 3,Fields 还有组合,有 12 个 Fields,就有 12×12 种组合,每个组合给一个 W,这就更加细化了,有三种不同的 W 定义。此外还可以有一个变化点,即可以加入 Layer Norm。
我们看一下结果。
暂时不说刚才几个改进模型,先说几个基础模型:LR、FM、FFM。这是我们在 Criteo 和 Avazu 两个数据集上做的实验,这两个数据集是工业级,大约在四千到四千五百万的 CTR。
先说 LR 和 FM,可以从数据里面看出来,FM 是显著优于 LR 的,这两个数据都是这样。首先要确认一点,不要期望太高。提了五个点、十个点,在 CTR 里是见不到这种现象的,在 CTR 能升一个点就是非常显著的一个增加。FM 跟 FFM 比,AUC 从 0.7923 到 0.8001,也是显著提升的,这是这三个模型的特性。
至于这三个类型中哪个效果好?双线性 FFM 达到了 0.7995,Fields 组合效果是最好的,接近于 FFM,但稍微低一点。还有个变化点,可以加入 Layer Norm,同样加到了那三个模型里面去,最好的效果也达到了 0.8035,超过 FFM,而且效果比较显著。
所以我们可以下结论:双线性效果是可以达到 FFM 相当,或者说超过性能的,Layer Norm 有提升作用。我们现在正在大规模工程化这个模型。
估算一下改进的模型它的参数量跟 FFM 比是什么情况?如果说我们用 Criteo 这个 4500 万的数据集,它有 230 万个特征,39 个 Fields,假设 embedding size 是 10,如果用 FFM 就会有 8.97 亿的参数量,而用双线性 FFM,FM 部分是大概 2300 万的参数,刚才三个改进模型中,类型一 100 个参数,类型二 3900 个参数,类型三 15 万参数,与 FFM 相比,参数差了 38 倍,但性能两者是相当的,这就是这个模型的价值所在。
总结一下双线性 FFM 模型:它的性能接近于 FFM,但是参数量是 FFM 模型的 2.6%,这是它的优点所在。
下面我介绍一下深度模型,首先介绍一下它的发展历程。
所有的深度学习,做 CTR 的模型时都会有 DNN 的部分,没有例外。什么含义呢?特征输进去,然后把它转换成 embedding,上面套两个隐层进行预测,这是所有模型公有的一部分。
我把现在这个深度 CTR 模型会分成了两大类。从结构来说,第一类我把它叫并行结构,它有另外一个结构,我管它叫 FM Function,它捕捉特征的两两组合,两者关系看上去是个并行的,叫并行结构。
除了并行还能怎么修改这个结构?可以把它搞成串行的,前面一样到 embedding 特征,然后做二阶特征组合捕获,上面套两个隐层做多阶特征捕获,这是串行结构。典型的有一类模型:PNN、NFM、AFM 都属于这种结构。
如果再归纳一下,你会发现深度排序模型,现在有朝两个研究路线在走。所有的模型在干什么?捕获特征组合是它的核心,这两条演进路线怎么走的呢?
第一条路线,新型的 FM Function,就是怎么能够设计一个新的结构,FM Function 更有效地捕获二阶特征组合,比如说典型的 Wide&Deep,DeepFM,NeuralFFM 就是用来做这个的。
第二条路线,显式地对二阶、三阶、四阶···K 阶组合进行建模。目前的研究结论是这样的:对 CTR 捕获二、三、四阶都有正向收益,再捕获五阶以上才没用。典型的代表是 DeepCross、xDeepFM。
针对这两条演进路线,我会各自介绍两到三个代表系统。
第一个代表系统:Wide&Deep,这个系统我相信大家都听说过。
Wide&Deep 的结构是什么呢?实际上就是我画的并行结构,右边就是 DNN 部分,左边的 FM Function 用的是线性回归。我个人认为,Wide&Deep 是相对原始的模型,LR 有的问题它也有,特征组合需要人去设计,Wide&Deep 也有这样的问题。
我们可以改进一下。DeepFM 相对做出什么改进呢?把 LR 换成 FM,不就能自动做特征组合了,这就是 DeepFM。如果想部署深度模型,我建议可以考虑这个模型,这是目前效果最好的模型之一。
第二条路线的两个代表是这样的:Deep&Cross 用来做什么?显式地做高阶特征组合。就是说设计几层神经网络结构,每一层代表其不同阶的组合,最下面是二阶组合,再套一层,三阶组合,四阶组合,一层一层往上套,这就叫显式地捕获高阶特征组合,Deep&Cross 是最开始做这个的。
xDeepFM 是微软 2018 年发的一篇新论文,它是用来把二阶、三阶、四阶组合一层一层做出来,但无非它用的是类 CNN 的方式来做这个事的。这是第二个路线的两个代表。
接着来讲一下,我对深度 CTR 模型的个人看法。
首先可以看到,现在所有的模型结构趋同,要么并行,要么串行,没有例外;第二,输入问题基本解决了,都是 onehot 和 embedding。核心所在是二阶特征组合怎么设计网络?所有的方法,或者大多数方法变化在这。另外就是多层,显式地做二、三、四阶,这是目前的一个趋势。
最后介绍一个改进版本 DeepFFM。
首先我抛给大家一个问题:刚才我们讲了,FFM 模型有它的对应版本,是 DeepFM 模型,那么问题来了:能不能设计一个 DeepFFM 模型神经网络版的?答案肯定是可以的。
我先给出一个前导模型:NeuralFFM,这是 2017 年南京大学杨毅等人提的,他们在参加一个比赛中提出了这个模型,这个模型效果比较好,是单模型的第三名。我们对这个模型做了一个改进,把它叫做 DeepFFM。
先说一下 NeuralFFM 模型怎么做的,这是我刚才抛给大家问题的解答。
要做一个神经网络版的 FFM 模型该怎么做?先把它想成 DeepFM,再想怎么改成 FFM。如果是 DeepFM,一个特征、一个 vector,然后在上面做两两特征组合,这就是 DeepFM 的思路。FFM 区别在哪里?一个特征现在不是一个 vector,是 F 个 vector,在两两做特征组合的时候,需要做特征交叉,这不就是深度的 FFM 模型吗?很简单,NeuralFFM 就是这个思想。
但是这里有个变化点。两个特征进行组合的时候,可以用内积做,也可以用哈达马积做,这是有区别的。什么是内积呢?就是两个向量,每个位置对应的相乘求和,表示一个数值;哈达马积怎么做的呢?它比内积少做了一步,把对应的位置相乘,乘完之后不进行求和。
我们这个 DeepFFM 是怎么改进的呢?在特征交互层,也就是两两特征在这组合,我们加了一个 Attention,也就是一个注意力模型进去。我认识两两特征组合,但是有的组合特征比较重要,有的没那么重要,怎么体现这个思想?给每个特征组加个权重就可以。怎么给权重?加个 Attention 就可以了。这就是我们 DeepFFM 的核心思想。
至于什么是 Attention,不懂的人可以自己去查。
再回头讲,我们是怎么改进的。在特征交互层,我们先给出个内积版,这是一个特征组合,组合完是一个值,我给每个两两特征组合的值都加个权重 a1-an,加完权重之后,再把权重乘到值里,再加上 Layer Norm,往上面引层去走,这是第一个改进版本。
有没有新的改进版本?肯定有,不仅有内积,还有哈达马积。哈达马积是说两个特征组合完之后是个向量,这是一个特征组合,里面有若干个神经元,但它整体代表一个特征组合。我给组合完的 vector 整体加个权重 a1-an,每个都加权重,一样再乘回来,上面再套 LN,这就是哈达马积版本。
那么,能不能继续改进?我刚才是把它当作一个整体求 Attention,还可以把每一位拆开,每个位都加 Attention,每个位上面套层 LN,这就是第三个版本。
来看一看实验结果。先看刚才讲的几个深度典型模型代表是什么效果?
DeepFM,我们实际测过,想做高是不容易的;xDeepFM 是 3 个技术模型中最好的,所以新模型想比原模型高很多是很难的;NeuralFM 和 DeepFM 在这个数据集上并没有很大提高,比原来稍有提升一点,但是在 Avazu 上是有明显提升的;DeepFFM 什么效果呢?下面标红这三个,尤其是第二个模型做到 0.8091,也就是说在所有的模型里面效果最好的,在 Avazu 来说也是效果最好的。
最后总结一下。
今天讲了大规模系统是怎么构成的:包括召回加 ranking,我们的主要内容放在 ranking 阶段;之后,我回顾了一下线性模型,重点提到了双线性模型,它的特点是可以在参数量极小的情况下,性能达到类似于 FFM 的效果;然后,我给大家分享两个深度模型的演进路线,一样的改进版本,效果目前来看还是比较好的。
张俊林,中国中文信息学会理事,中科院软件所博士,目前在新浪微博 AI Lab 担任资深算法专家。在此之前,张俊林曾经在阿里巴巴任资深技术专家并负责新技术团队,以及在百度和用友担任技术经理及技术总监等职务。他是技术书籍《这就是搜索引擎:核心技术详解》(该书荣获全国第十二届优秀图书奖)、《大数据日知录:架构与算法》的作者。