FM系列

在计算广告中,CTR是非常重要的一环。对于特征组合来说,业界通用的做法主要有两大类:FM系列和Tree系列。这里我们来介绍一下FM系列。
在传统的线性模型中,每个特征都是独立的,如果需要考虑特征与特征之间的相互作用,可能需要人工对特征进行交叉组合。非线性SVM可以对特征进行核变换,但是在特征高度稀疏的情况下,并不能很好的进行学习。现在有很多分解模型可以学习到特征之间的交互隐藏关系,基本上每个模型都只适用于特定的输入和场景。推荐系统是一个高度稀疏的数据场景,由此产生了FM系列算法。
本文主要涉及四种FM系列算法:FM,FFM,DeepFM,DeepFFM

因子分解机 (Factorization Machine,简称FM)

FM算法用于解决大规模稀疏数据下的特征组合问题。FM可以看做带特征交叉的LR。
考虑两阶多项式模型,也就是特征两两组合的问题,模型表达如下:

y^(x)=w0+i=1nwixi+i=1nj=i+1nwijxixj

其中n表示样本的特征数量,这里的特征是离散化后的特征。
然而,在数据稀疏性普遍存在的实际应用场景中,二次项参数的训练是很困难的。其原因是,每个参数 wij 的训练需要大量 xixj 都非零的样本;由于样本数据本来就比较稀疏,满足“xixj 都非零”的样本将会非常少。训练样本的不足,很容易导致参数 wij 不准确,最终将严重影响模型的性能。
为了解决二阶交叉项参数的学习问题,把多项式模型中二阶交叉项参数wij组成一个对称矩阵W(对角元素设为正实数),那么这个矩阵就可以分解。

将每个交叉项参数wij用隐向量的内积vi,vj表示,是FM模型的核心思想。

以二阶为例,FM模型表达式:

y^(x)=w0+i=1nwixi+i=1nj=i+1nvi,vjxixj

其中vi表示第i特征的隐向量,<,>表示两个长度为k的向量的内积,计算公式为:

vi,vj:=f=1kvi,fvj,f

参数因子化表示后,使得xhxi的参数与xixj的参数不再相互独立。这样我们就可以在样本稀疏情况下相对合理的估计FM模型交叉项的参数。
FM模型的复杂度为O(kn2),但是通过下面的等价转换,可以将FM的二次项化简,其复杂度可优化到O(kn)。即:

i=1nj=i+1nvi,vjxixj=12f=1k(i=1nvi,fxi)2i=1nvi,f2xi2

详细推导如下:

i=1nj=i+1nvi,vjxixj(1)=12i=1nj=1nvi,vjxixj12i=1nvi,vixixi(2)=12(i=1nj=1nf=1kvi,fvj,fxixji=1nf=1kvi,fvi,fxixi)(3)=12f=1k(i=1nvi,fxi)(j=1nvj,fxj)i=1nvi,f2xi2(4)=12f=1k(i=1nvi,fxi)2i=1nvi,f2xi2(5)

解读第(1)步到第(2)步,这里用A表示系数矩阵V的上三角元素,B表示对角线上的交叉项系数。由于系数矩阵V是一个对称阵,所以下三角与上三角相等,有下式成立:

A=12(2A+B)12B.A=i=1nj=i+1nvi,vjxixj_;B=12i=1nvi,vixixi_

如果用随机梯度下降(Stochastic Gradient Descent)法学习模型参数。那么,模型各个参数的梯度如下:

θy(x)={1,ifθisw0(常数项)xiifθiswi(线性项)xij=1nvj,fxjvi,fxi2,ifθisvi,f(交叉项)

由于j=1nvj,fxj只与f有关,在参数迭代过程中,只需要计算第一次所有fj=1nvj,fxj,就能够方便地得到所有vi,f的梯度。显然,计算所有fj=1nvj,fxj的复杂度是O(kn);已知j=1nvj,fxj时,计算每个参数梯度的复杂度是O(n);得到梯度后,更新每个参数的复杂度是 O(1);模型参数一共有nk+n+1个。因此,FM参数训练的时间复杂度为O(kn)
综上可知,FM算法可以在线性时间内完成模型训练,以及对新样本做出预测,所以说FM是一个非常高效的模型。

损失函数

  • 回归问题
    对于回归问题,损失函数可取为最小平方误差,即

loss(y^,y)=(y^y)2

  • 二分类问题
    对于二分类问题(其中标签y+1,1),损失函数可取为hinge loss函数 或 logit loss函数
  1. hinge loss函数

loss(y^,y)=max{0,1yy^},

y=+1时,

loss(y^,y)=max{0,1y^}={0,            y^1;1y^,     y^<1;

y=1时,

loss(y^,y)=max{0,1+y^}={0,            y^1;1+y^,     y^>1;

模型训练好后,就可以利用y^(x)的正负符号来预测x的分类了。

  1. logit loss函数

loss(y^,y)=lnσ(y^y)

其中σ(x)=11+exsigmoid函数,可见y^y越接近,损失loss(y^,y)就越小。

此外,为了防止过拟合,我们通常会在优化目标函数中加入正则项(如L2正则)。

总结:

  1. FM降低了交叉项参数学习不充分的影响
    one-hot编码后的样本数据非常稀疏,组合特征更是如此。为了解决交叉项参数学习不充分、导致模型有偏或不稳定的问题。作者借鉴矩阵分解的思路:每一维特征用k维的隐向量表示,交叉项的参数wij用对应特征隐向量的内积表示,即vi,vj(也可以理解为平滑技术)。这样参数学习由之前学习交叉项参数wij的过程,转变为学习n个单特征对应k维隐向量的过程。
    很明显,单特征参数(k维隐向量vi)的学习要比交叉项参数wij学习得更充分。

  2. FM提升了模型预估能力
    由于FM学习的参数就是单特征的隐向量,那么交叉项的预估结果可以用隐向量内积得到。这样,即便训练集中没有出现交叉项的样本,FM模型仍然可以用来预估,提升了预估能力。

  3. FM提升了参数学习效率
    这个显而易见,参数个数由(n2+n+1)变为(nk+n+1)个,模型训练复杂度也由O(mn2))变为O(mnk)m为训练样本数。对于训练样本和特征数而言,都是线性复杂度。
    此外,就FM模型本身而言,它是在多项式模型基础上对参数的计算做了调整,因此也有人把FM模型称为多项式的广义线性模型,也是恰如其分的。

FM模型对稀疏数据有更好的学习能力,通过交互项可以学习特征之间的关联关系,并且保证了学习效率和预估能力。

FM vs SVM

SVM和FM的主要区别在于:

  • SVM的二元特征交叉参数是独立的,而FM的二元特征交叉参数是两个k维的向量vivj,交叉参数就不是独立的,而是相互影响的。
  • FM可以在原始形式下进行优化学习,而基于kernel的非线性SVM通常需要在对偶形式下进行
  • FM的模型预测是与训练样本独立,而SVM则与部分训练样本有关,即支持向量

FM vs LR

Fm学习的是特征的隐向量,没有出现的特征也可以通过隐向量内积得到,打破了特征之间的独立性。LR学习的是组合特征的权重,没有出现的组合特征,权重无法学习。简单理解就是数据太稀疏了,xixj的样本不一定存在,LR就无法学习wij

场感知分解机(Field-aware Factorization Machine ,简称FFM)

在CTR预估中,通常会遇到one-hot类型的变量,会导致数据特征的稀疏。未解决这个问题,FFM在FM的基础上进一步改进,在模型中引入类别的概念,即field。将同一个field的特征单独进行one-hot,因此在FFM中,每一维特征都会针对其他特征的每个field,分别学习一个隐变量,该隐变量不仅与特征相关,也与field相关。假设样本的n个特征属于f个field,那么FFM的二次项有nf个隐向量。而在FM模型中,每一维特征的隐向量只有一个。FM可以看做FFM的特例,把所有特征都归属到一个field的FFM模型。通过引入field的概念,FFM把相同性质的特征归于同一个field。
同一个categorical特征可以包括用户属性信息(年龄、性别、职业、收入、地域等),用户行为信息(兴趣、偏好、时间等),上下文信息(位置、内容等)以及其它信息(天气、交通等)。

其模型表达式为:

y^(x):=w0+i=1nwixi+i=1nj=i+1nvi,fj,vj,fixixj

其中,fj是第j个特征所属的field。如果隐向量的长度为k,那么FFM的二交叉项参数就有nfk个,远多于FM模型的nk个。此外,由于隐向量与field相关,FFM的交叉项并不能够像FM那样做化简,其预测复杂度为O(kn2)

FFM应用

在DSP或者推荐场景中,FFM主要用来评估站内的CTR和CVR,即一个用户对一个商品的潜在点击率和点击后的转化率。
CTR和CVR预估模型都是在线下训练,然后线上预测。两个模型采用的特征大同小异,主要分三类:

  • 用户相关的特征
    年龄、性别、职业、兴趣、品类偏好、浏览/购买品类等基本信息,以及用户近期点击量/购买量/消费额等统计信息

  • 商品相关的特征
    商品所属品类、销量、价格、评分、历史CTR/CVR等信息

  • 用户-商品匹配特征
    浏览/购买品类匹配、浏览/购买商家匹配、兴趣偏好匹配等

为了使用FFM方法,所有的特征必须转换成“field_id:feat_id:value”格式,field_id代表特征所属field的编号,feat_id是特征编号,value是特征的值。数值型的特征比较容易处理,只需分配单独的field编号,如用户评论得分、商品的历史CTR/CVR等。categorical特征需要经过One-Hot编码成数值型,编码产生的所有特征同属于一个field,而特征的值只能是0或1,如用户的性别、年龄段,商品的品类id等。除此之外,还有第三类特征,如用户浏览/购买品类,有多个品类id且用一个数值衡量用户浏览或购买每个品类商品的数量。这类特征按照categorical特征处理,不同的只是特征的值不是0或1,而是代表用户浏览或购买数量的数值。按前述方法得到field_id之后,再对转换后特征顺序编号,得到feat_id,特征的值也可以按照之前的方法获得。

实践注意项

  • 样本归一化:FFM默认是进行样本数据的归一化,即 为真;若此参数设置为假,很容易造成数据inf溢出,进而引起梯度计算的nan错误。因此,样本层面的数据是推荐进行归一化的。
  • 特征归一化:CTR/CVR模型采用了多种类型的源特征,包括数值型和categorical类型等。但是,categorical类编码后的特征取值只有0或1,较大的数值型特征会造成样本归一化后categorical类生成特征的值非常小,没有区分性。例如,一条用户-商品记录,用户为“男”性,商品的销量是5000个(假设其它特征的值为零),那么归一化后特征“sex=male”(性别为男)的值略小于0.0002,而“volume”(销量)的值近似为1。特征“sex=male”在这个样本中的作用几乎可以忽略不计,这是相当不合理的。因此,将源数值型特征的值归一化到 是非常必要的。
  • 省略零值特征:从FFM模型的表达式可以看出,零值特征对模型完全没有贡献。包含零值特征的一次项和组合项均为零,对于训练模型参数或者目标值预估是没有作用的。因此,可以省去零值特征,提高FFM模型训练和预测的速度,这也是稀疏样本采用FFM的显著优势。

实现FM & FFM的最流行的python库有:LibFM、LibFFM、xlearn和tffm。其中,xLearn是一款高性能,易于使用且可扩展的机器学习软件包,包括FM和FFM模型,可用于大规模解决机器学习问题。xlearn比libfm和libffm库快得多,并为模型测试和调优提供了更好的功能。

DeepFM

FM通过对于每一位特征的隐变量内积来提取特征组合,最后的结果也不错,虽然理论上FM可以对高阶特征组合进行建模,但实际上因为计算复杂度原因,一般都只用到了二阶特征组合。对于高阶特征组合来说,我们很自然想到多层神经网络DNN。
DeepFM目的是同时学习低阶和高阶的特征交叉,主要由FM和DNN两部分组成,底部共享同样的输入。模型可以表示为:

y^=sigmoid(yFM+yDNN)

DeepFM

  1. FM部分
    数学表达为:

yFM=w0+i=1nwixi+i=1nj=i+1nvi,vjxixj

FM模型可以用神经网络进行表示,模型输入x=[xfield1,xfield2,,xfieldm],这是一个d维的向量,其中xfieldi即为第ifield的特征表示,如果是类别,则为one-hot编码后的向量,连续值则为它本身。然后对每个field分别进行embedding
DeepFM FM部分
值得注意的是,即使各个field的维度是不一样的,但是它们embedding后长度均为k。
接着FM层即为embedding后结果的内积和一次项的和,最后一层sigmoid后再输出结果。

  1. 深度部分
    是一个前馈神经网络,与图像或语音类的输入不同,CTR的输入一般是极其稀疏的,因此需要重新设计网络结构。在第一层隐藏层之前,引入一个嵌入层来完成输入向量压缩到低位稠密向量:

嵌入层的输出为a(0)=[e1,e2,...,em],其中ei是嵌入的第i个filed,m是field的个数,前向过程将嵌入层的输出输入到隐藏层为

a(l+1)=σ(W(l)a(l)+b(l))

其中l是层数,σ是激活函数,W(l)是模型的权重,b(l)l层的偏置
因此,DNN得预测模型表达为:

yDNN=W|H|+1a|H|+b|H|+1

|H|为隐藏层层数

有两个有趣的特性:
1) 尽管不同field的输入长度不同,但是embedding之后向量的长度均为k
2) 在FM中得到的隐变量Vik现在作为嵌入层网络的权重

Embedding层的隐式向量在(残差反向传播)训练时可以同时接受到深度部分和FM部分的信息,从而使Embedding层的信息表达更加准确而最终提升推荐效果。
需要指出的是,FM部分与深度部分共享相同的embedding带来了两个好处:
1.从原始数据中同时学习到了低维与高维特征
2.不再需要特征工程。而Wide&Deep Model需要

DeepFFM

类似于FFM对于FM模型来说,划分了field,对于不同的field内积时采用对应的隐向量。同样可以把DeepFM进行进化为DeepFFM,即将每一个field embedding为m个维度为k的隐向量(m为field的个数)

posted @   Jamest  阅读(2876)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示