深度排序模型概述(一)Wide&Deep/xDeepFM

本文记录几个在广告和推荐里面rank阶段经常使用的模型。
广告领域机器学习问题的输入其实很大程度了影响了模型的选择,由于输入通常维度很是高,稀疏,同时包含连续性特征和离散型特征。模型即便到如今DeepFM类的方法,其实也都很简单。模型的发展主要体现于对特征的充分挖掘上,好比利用低阶和高阶特征、尝试自动学习交叉特征而非手动、尝试更精准地实现高阶特征(bounded-degree)。

广告相关的领域最先大行其道的模型当属LR模型,缘由就是LR模型简单,可解释性好,拓展性高,精心细调以后模型效果也会很是好。人工特征工程的初期,加些交叉特征,不管是离线评估指标仍是线上的业务指标都会很容易提升,固然你们都会很开心。吃掉容易收割的80%以后,基本上就到了瓶颈。这时候就会发现即便深挖业务场景貌似也找不到比较好的特征了,加了一堆特征搞很差效果还降了。继续作得话,除了特征工程,还能够尝试特征选择,改进优化算法(好比加快收敛),在线学习之类的。
随着业务的持续迭代,手动交叉特征被视为脏活累活,那确定要想如何作自动交叉特征。这方面的工做同时也有进展。Rendle在2010年提出的FM模型。FM模型利用特征的隐向量作内积来实现特征的交叉。后续阮毓钦提出了Field-aware FM模型,一个特征对应多个隐向量,在criteo举办的ctr比赛上崭露头角。这些其实都已经算是ctr领域的经常使用套路。FM类模型因为复杂度的缘由通常都只能实现二阶交叉。因此不能利用高阶交叉总会让人感受缺乏点意思,毕竟不少场景高阶交叉的确有意义。另外不得不提的特征组合的工做就是Facebook提出的gbdt+lr的方法,经过gbdt来实现监督式的特征组合。
浅层模型尝试以后势必要引入深层模型,毕竟深度学习很大做用就是做为特征表示学习。大厂引入确定要更早一些,毕竟核心业务都要长时间持续投入人力进行模型优化。至于思路,我以为可能跟现有市面上看到的模型差很少。通常多层感知机mlp认为能够实现特征高阶交叉(high-order feature interactions)。
2016年出现wide&deep、fnn和pnn等工做。wide&deep算影响力比较大的工做了。wide部分是手动特征交叉(负责memorization),deep部分利用mlp来实现高阶特征交叉(负责generalization),wide部分和deep部分joint train。fnn比较暴力,直接使用预训练的fm隐向量传给mlp。PNN则是先作特征交叉而后给mlp处理。fnn和pnn这两种方法的缺点就是忽视了低阶特征交叉。
2017年出现DeepFM、Deep&Cross和NFM等工做。DeepFM模型和Deep&Cross(包含下面要介绍的xDeepFM)均可以认为是Wide&Deep架构输入和wide部分进行改进。DeepFM和以前模型相比优点在于两点,一个是相对于Wide&Deep再也不须要手工构建wide部分,另外一个相对于FNN把FM的隐向量参数直接做为网络参数学习。DeepFM将embedding层结果输入给FM和MLP,二者输出叠加,达到捕捉了低阶和高阶特征交叉的目的。Deep&Cross和DeepFM相似,cross network模块能够实现bounded-degree feature interactions。
总结来讲,涌现了这么模型,到底哪一个好,我以为很难一槌定音。每一个模型都有存在的价值和合适的应用场景。有时候也不必定非得效果提示才行,有时候效果没提高可是能够大大减小特征工程的工做也算有收益。根据实际的场景、业务需求和迭代阶段选择合适的模型,花费合理的成本,取得最大的业务价值才是最重要的。算法

深度排序模型的结构能够分为两种,一种是并行结构,分别作低阶和高阶特征组合;一种是串行结构,如PNN、NFM、AFM等。这也构成了深度排序模型的两条演进路线,如何更有效地捕获特征组合是核心,沿着如下两个演进路线发展:
一:更有效地捕获二阶特征:
Wide&Deep -> DeepFM -> NeuralFFM -> DeepFFM
2、显式建模2阶/3阶/4阶...K阶特征组合:
DeepCross -> xDeepFM数据库

Wide&Deep

Wide&Deep 模型的核心思想是结合线性模型的记忆能力(memorization)和 DNN 模型的泛化能力(generalization),在训练过程当中同时优化 2 个模型的参数,从而达到总体模型的预测能力最优。
记忆(memorization)即从历史数据中发现item或者特征之间的相关性。
泛化(generalization)即相关性的传递,发如今历史数据中不多或者没有出现的新的特征组合。markdown

网络结构

Wide&Deep网络结构

能够认为:Wide&Deep = LR + DNN网络

  • Wide部分
    实际上,Wide模型就是一个广义线性模型:
    架构

    y = w T x + b

    最终在y的基础上增长 S i g m o i d 函数做为最终的输出。

     

  • Deep部分
    实际上,Deep模型是一个前馈神经网络。深度神经网络模型一般须要的输入是连续的稠密特征,对于稀疏,高维的类别特征,一般首先将其转换为低维的向量,这个过程也称为embedding。app

    在训练的时候,首先随机初始化embedding向量,并在模型的训练过程当中逐渐修改该向量的值,即将向量做为参数参与模型的训练。框架

  • Wide & Deep模型的联合训练(joint training)
    联合训练是指同时训练Wide模型和Deep模型,并将两个模型的结果的加权和做为最终的预测结果:
    ( Y = 1 | x ) = σ ( w w i d e T [ x , Φ ( x ) ] + w d e e p T a a ( l f ) + b ) " role="presentation" style="display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; position: relative;"> P ( Y = 1 | x ) = σ ( w w i d e T [ x , Φ ( x ) ] + w d e e p T a a ( l f ) + b )

    训练的方法:
    • Wide模型:FTRL(Follow-the-regularized-leader)
    • Deep模型:AdaGrad

在推荐的场景中,最重要的行为数据是点击(下载/购买)数据,传统的Wide类型的特征能够对肯定性的推荐很好的建模, 若是考虑到多样性,就须要对稀疏数据和"没有直接观测到"的行为数据建模。deep部分能够对多阶的行为传导更好的表达。
值得注意的是,最后一层中Deep和Wide部分是如何合并到一块儿的. 文中的作法是将Wide部分的特征和Deep部分的最后一层的特征对齐,而后统一送入到一个逻辑回归模型中。机器学习

应用

对于推荐系统,其最通常的结构以下图所示:ide

Wide&Deep推荐系统
当一个用户访问app商店时,此时会产生一个请求,请求到达推荐系统后,推荐系统为该用户返回推荐的apps列表。函数

在实际的推荐系统中,一般将推荐的过程分为两个部分,即上图中的Retrieval和Ranking,Retrieval负责从数据库中检索出与用户相关的一些apps,Ranking负责对这些检索出的apps打分,最终,按照分数的高低返回相应的列表给用户。

Deep & Cross Network(DCN)

对比一样来自 google 的工做 Wide & Deep ,DCN 不须要特征工程来得到高阶的交叉特征,对比 FM 系列的模型,DCN 拥有更高的计算效率而且可以提取到更高阶的交叉特征。

DCN

从网络结构上面来看,该模型是很是简单明了的,特征分为类别型与数值型,类别型特征通过 embedding 以后与数值型特征直接拼接做为模型的输入。全部的特征分别通过 cross 和 deep 网络,若是把这两个网络看做特征提取的话,通过提取后的特征向量拼接以后是常规的二分类,若是训练数据是曝光和点击,最后输出的就能够看做点击率了。

  • 离散特征嵌入
    离散特征嵌入这个想法最初来自于 Mikolov 的 word2vec 系列文章。最初解决的问题是词的独热表示过于稀疏,而且不一样词之间的向量形式表示彻底没有联系。具体思路在此不赘述,最终的实现是将一个上万维的词独热表示嵌入到了只有几百维的稠密向量中。而嵌入的本质实际上是构建一张随机初始化的向量查找表,经过咱们的训练目标作有监督学习来获得不一样词在特定目标下,处于向量空间中的位置。
    将词嵌入的思路推广到其它的离散特征处理中,咱们能够用一样的方法将各类类别特征如“用户性别”、“城市”、“日期”嵌入到稠密的向量空间中。通过这样处理以后,天然就解决了本来 FM 遇到的特征稀疏问题。

  • 高阶交叉特征
    在广告场景下,特征交叉的组合与点击率是有显著相关的,例如,“USA”与“Thanksgiving”、“China”与“Chinese New Year”这样的关联特征,对用户的点击有着正向的影响。
    而本文开发了一个新的算子,来获得交叉特征:
    DCN
    即,

    ( x l , w l , b l ) + x l " role="presentation" style="display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; position: relative;"> x l + 1 = x 0 x l T w l + b l + x l = f ( x l , w l , b l ) + x l

    考虑  x  为输入的特征及第一层的输入, x  为 第  L  层的输入,咱们能够看到它的基本思路仍是用矩阵乘法来实现特征的组合。

     

这是个递推形式算子,因此使用它很容易能获得高于二阶的交叉特征;而且该模型还用了残差的思想,解决网络性能退化的问题;此公式还有一个小的优化技巧,三矩阵相乘那个算子,用乘法结合律先计算后面两个矩阵的积,这样能够减小三分之一的计算复杂度。

DCN和同场景模型对比

在deepFM中, 进行了离散特征嵌入的操做,而且还将嵌入前的离散特征加入到了 FM 层;因此该网络能够看做是传统的 FM 、离散特征嵌入以后的 FM 和基本 DNN 三个模型融合的结果。
wide & deep 的思路中,deep 部分的作法和 deepFM 是截然不同的,关键的 wide 部分实际上是离线的特征工程,根据业务场景提早完成了特征交叉等处理,该模型能够看做是 DNN 与离线特征模型的融合结果。
而从 DCN 的网络中咱们能够发现,deep 部分网络除了使用离散嵌入特征外,还拼接了数值型特征;cross 部分网络直接完成了特征组合,对比 FM 层它能够学到更高阶的组合特征,对比 wide 网络它不须要作线下的特征工程。

xDeepFm

传统的推荐系统中,挖掘交叉特征主要依靠人工提取,这种作法主要有如下三种缺点:
1)重要的特征都是与应用场景息息相关的,针对每一种应用场景,工程师们都须要首先花费大量时间和精力深刻了解数据的规律以后才能设计、提取出高效的高阶交叉特征,所以人力成本高昂;
2)原始数据中每每包含大量稀疏的特征,例如用户和物品的ID,交叉特征的维度空间是原始特征维度的乘积,所以很容易带来维度灾难的问题;
3)人工提取的交叉特征没法泛化到不曾在训练样本中出现过的模式中。
所以自动学习特征间的交互关系是十分有意义的。目前大部分相关的研究工做是基于因子分解机的框架,利用多层全链接神经网络去自动学习特征间的高阶交互关系。
xDeepFM主要是针对DeepFM和DCN的改进。例如FNN、PNN和DeepFM,其缺点是模型学习出的是隐式的交互特征,其形式是未知的、不可控的;同时它们的特征交互是发生在元素级(bit-wise)而不是特征向量之间(vector-wise),这一点违背了因子分解机的初衷。DCN模型,旨在显式(explicitly)地学习高阶特征交互,其优势是模型很是轻巧高效,但缺点是最终模型的表现形式是一种很特殊的向量扩张,同时特征交互依旧是发生在元素级上。

  • bit-wise VS vector-wise
    假设隐向量的维度为3维,若是两个特征(对应的向量分别为(a1,b1,c1)和(a2,b2,c2)的话)在进行交互时,交互的形式相似于 ( w 1 a 1 a 2 , w 2 b 1 b 2 , w 3 c 1 c 2 ) " role="presentation" style="display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; position: relative;"> f ( w 1 a 1 a 2 , w 2 b 1 b 2 , w 3 c 1 c 2 )  的话,此时咱们认为特征交互是发生在元素级(bit-wise)上。若是特征交互形式相似于 ( w ( a 1 a 2 , b 1 b 2 , c 1 c 2 ) ) " role="presentation" style="display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; position: relative;"> f ( w ( a 1 a 2 , b 1 b 2 , c 1 c 2 ) ) 的话,那么咱们认为特征交互是发生在特征向量级(vector-wise)。
  • explicitly VS implicitly
    显式的特征交互和隐式的特征交互。以两个特征为例 x i x j ,在通过一系列变换后,咱们能够表示成 ( x i x j ) " role="presentation" style="display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; position: relative;"> w i j ( x i x j )  的形式,就能够认为是显式特征交互,不然的话,是隐式的特征交互。

为了实现自动学习显式的高阶特征交互,同时使得交互发生在向量级上,xDeepFm提出了一种新的名为压缩交互网络(Compressed Interaction Network,简称CIN)的神经模型。在CIN中,隐向量是一个单元对象,所以咱们将输入的原特征和神经网络中的隐层都分别组织成一个矩阵,记为X0和Xk。CIN中每一层的神经元都是根据前一层的隐层以及原特征向量推算而来,其计算公式以下:

( X i , k 1 X j , 0 ) " role="presentation" style="display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; position: relative;"> X h , k = i = 1 H k 1 j = 1 m W i j k , h ( X i , k 1 X j , 0 )

其中点乘的部分计算以下:
< a 1 , a 2 , a 3 > < b 1 , b 2 , b 3 >=< a 1 b 1 , a 2 b 2 , a 3 b 3 >

第k层隐层含有 H k 条神经元向量。隐层的计算能够分红两个步骤:(1)根据前一层隐层的状态Xk和原特征矩阵X0,计算出一个中间结果 Z k + 1 ,它是一个三维的张量,以下图所示:

 

CIN1

CIN的宏观框架能够总结为下图:

在这个中间结果上,咱们用 H k + 1 个尺寸为 m H k 的卷积核生成下一层隐层的状态,该过程如图2所示。这一操做与计算机视觉中最流行的卷积神经网络大致是一致的,惟一的区别在于卷积核的设计。CIN中一个神经元相关的接受域是垂直于特征维度D的整个平面,而CNN中的接受域是当前神经元周围的局部小范围区域,所以CIN中通过卷积操做获得的特征图(Feature Map)是一个向量,而不是一个矩阵。
CIN2
CIN3

CIN的宏观框架能够总结为下图:
CIN宏观框架

能够看出,它的特色是,最终学习出的特征交互的阶数是由网络的层数决定的,每一层隐层都经过一个池化操做链接到输出层,从而保证了输出单元能够见到不一样阶数的特征交互模式。同时不难看出,CIN的结构与循环神经网络RNN是很相似的,即每一层的状态是由前一层隐层的值与一个额外的输入数据计算所得。不一样的是,CIN中不一样层的参数是不同的,而在RNN中是相同的;RNN中每次额外的输入数据是不同的,而CIN中额外的输入数据是固定的,始终是 X 0
能够看到,CIN是经过(vector-wise)来学习特征之间的交互的,还有一个问题,就是它为何是显式的进行学习?咱们先从 X 1 来开始看, X 1 的第 h 个神经元向量能够表示成:

[ m ]     j [ m ] W i , j 1 , h ( X i 0 X j 0 ) " role="presentation" style="display: inline; line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; position: relative;"> X h 1 = i [ m ]     j [ m ] W i , j 1 , h ( X i 0 X j 0 )

进一步, X 2 的第 h 个神经元向量能够表示成:
[ m ]     j [ m ] W i , j k , h ( X i k 1 X j 0 ) = i [ m ]     j [ m ] . . . r [ m ]     t [ m ] l [ m ]     s [ m ] W i , j k , h . . . W l , s 1 , r ( x j 0 . . . x s 0 x l 0 ) " role="presentation" style="line-height: normal; word-spacing: normal; overflow-wrap: normal; white-space: nowrap; float: none; direction: ltr; max-width: none; max-height: none; min-width: 0px; min-height: 0px; border: 0px; padding: 0px; margin: 0px; position: relative; display: table-cell !important; width: 10000em !important;"> X h k = i [ m ]     j [ m ] W i , j k , h ( X i k 1 X j 0 ) = i [ m ]     j [ m ] . . . r [ m ]     t [ m ] l [ m ]     s [ m ] W i , j k , h . . . W l , s 1 , r ( x j 0 . . . x s 0 x l 0 )

所以,咱们可以经过上面的式子对特征交互的形式进行一个很好的表示,它是显式的学习特征交叉。

 

将CIN与线性回归单元、全链接神经网络单元组合在一块儿,获得最终的模型并命名为极深因子分解机xDeepFM,其结构以下图:
xDeepFM集成的CIN和DNN两个模块可以帮助模型同时以显式和隐式的方式学习高阶的特征交互,而集成的线性模块和深度神经模块也让模型兼具记忆与泛化的学习能力。值得一提的是,为了提升模型的通用性,xDeepFM中不一样的模块共享相同的输入数据。而在具体的应用场景下,不一样的模块也能够接入各自不一样的输入数据,例如,线性模块中依旧能够接入不少根据先验知识提取的交叉特征来提升记忆能力,而在CIN或者DNN中,为了减小模型的计算复杂度,能够只导入一部分稀疏的特征子集。

相关文章
相关标签/搜索