CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

FM

在计算广告领域,因子分解机(Factorization Machines,FM)是很经典的模型,面对量大且稀疏的数据,此算法仍然可以取得比较优秀的效果。

假设有下面的数据:

Clicked? Country Day Ad_type
1 USA 26/11/15 Movie
0 China 1/7/14 Game
1 China 19/2/15 Game

其中,Clicked? 是label,Country、Day、Ad_type是特征。由于三种特征都是类别型的,需要经过独热编码(One-Hot Encoding)转换成数值型特征:

Clicked? Country=USA Country=China Day=26/11/15 Day=1/7/14 Day=19/2/15 Ad_type=Movie Ad_type=Game
1 1 0 1 0 0 1 0
0 0 1 0 1 0 0 1
1 0 1 0 0 1 0 1

经过编码之后,数据变的非常稀疏,在工业界这也是很难避免的一个问题。在这些稀疏的特征中,如果将其中一些特征加以关联,就可能得到与label管理更紧密的特征。例如对于 China 而言,19/2/15(即2015年2月19日)这天是春节,可能存在大量浏览和购买行为,广告点击率自然也会上升。

为了不错过任何有意义的特征组合,我们将所有特征两两组合起来形成新的特征,比较简单直接的实现方法是使用二阶多项式模式进行特征组合。例如将特征 xi,xjx_i,x_j 的组合可以用 xixjx_ix_j 表示,当且仅当xi,xjx_i,x_j都为1时得到的组合特征才有意义。需要注意的是,原本的特征在onehot编码之后已经很稀疏了,再对特征进行两两组合,那么得到的特征就更稀疏了。

在得到特征之后,假设我们用线性模型进行预测,则预测值的表达式可能是这样的:
y^=w0+i=1nwixi+inj=i+1nwijxixj \hat{y}=w_0+\sum_{i=1}^n{w_ix_i}+\sum_i^n{\sum_{j=i+1}^n{w_{ij}x_ix_j}}
式子中 n 代表特征数量,w0,wi,wijw_0, w_{i}, w_{ij} 是模型的参数。其中组合特征参数 wijw_{ij} 共有n(n1)2\frac{n(n-1)}{2}个,需要大量的非零组合特征xixjx_ix_j才容易学习到合适的参数值。如何解决二次项参数wijw_{ij}的学习问题?

矩阵分解提供了一种解决方法,由于特征组合后的系数可以构成对称矩阵Wn×nW_{n \times n},因此可以对矩阵进行分解为Wn×n=Vn×kVn×kTW_{n\times n}=V_{n\times k}V_{n\times k}^T,即wi,j=<vi,vj>w_{i,j}=<v_i,v_j>,其中knk\ll n。于是,原本需要训练 n×nn \times n 个特征,现在只需要训练 n×kn \times k个:
y^=w0+i=1nwixi+i=1nj=i+1n<vi,vj>xixj<vi,vj>=f=1kvifvjf \hat{y}=w_0+\sum_{i=1}^n{w_ix_i}+\sum_{i=1}^n{\sum_{j=i+1}^n{<v_i,v_j>x_ix_j}} \\ <v_i,v_j>=\sum_{f=1}^k{v_{if}v_{jf}}
次数计算的时间复杂度为 O(kn2)O(kn^2) ,能不能进一步优化一***意到i=1nj=i+1n<vi,vj>xixj\sum_{i=1}^n{\sum_{j=i+1}^n{<v_i,v_j>x_ix_j}} 实际上只是矩阵 Wn×nW_{n \times n} 中不包含对角线的上三角的部分,可以用 Wn×nW_{n \times n} 减去对角线元素后再除以2来得到:
i=1nj=i+1n<vi,vj>xixj=12i=1nj=1n<vi,vj>xixj12i=1n<vi,vi>xixi=12(i=1nj=1nf=1kvifvjfxixji=1nf=1kvifvifxixi)=12(f=1ki=1nvifxij=1nvjfxji=1nf=1kvifvifxixi)=12f=1k((i=1nvifxi)2i=1nvif2xi2) \begin{aligned} & \sum_{i=1}^n{\sum_{j=i+1}^n{<v_i,v_j>x_ix_j}} \\ & = \frac{1}{2}\sum_{i=1}^n{\sum_{j=1}^n{<v_i,v_j>x_ix_j}}-\frac{1}{2}\sum_{i=1}^n{<v_i,v_i>x_ix_i}\\ & = \frac{1}{2}\left(\sum_{i=1}^n{\sum_{j=1}^n{\sum_{f=1}^k{v_{if}v_{jf}x_ix_j}}}-\sum_{i=1}^n{\sum_{f=1}^k{v_{if}v_{if}x_ix_i}}\right) \\ & = \frac{1}{2}\left(\sum_{f=1}^k{\sum_{i=1}^n{v_{if}x_i\sum_{j=1}^n{v_{jf}x_j}}}-\sum_{i=1}^n{\sum_{f=1}^k{v_{if}v_{if}x_ix_i}}\right) \\ &= \frac{1}{2}\sum_{f=1}^k\left(\left(\sum_{i=1}^n{v_{if}x_i}\right)^2-\sum_{i=1}^n{v_{if}^2x_i^2}\right) \end{aligned}
这样一来,是复杂度就降低为: O(kn)O(kn)

引入二次项的FM模型,可以采用不同的损失函数用于解决回归、二元分类等问题,比如可以采用MSE(Mean Square Error)损失函数来求解回归问题,也可以采用Hinge/Cross-Entropy损失来求解分类问题。

(1)回归问题loss取最小平方误差
lossR(y^,y)=(y^y)2 loss^R(\hat y,y) = (\hat y - y)^2
所以:
lossR(y^,y)θ=2(y^y)y^θ \frac{\partial loss^R(\hat y,y)}{\partial \theta} = 2 (\hat y - y)\frac{\partial \hat y }{\partial\theta}

(2)二分类问题loss取logit函数
lossC(y^,y)=lnσ(y^y) loss^C(\hat y ,y) = -\ln \sigma(\hat y y)
所以:
lossC(y^,y)θ=[(σ(y^y)1]yy^θ \frac{\partial loss^C(\hat y,y)}{\partial \theta} = [(\sigma(\hat y y) - 1]y \frac{\partial \hat y }{\partial\theta}

其中:
θy^(x)={1,if  θ  is  w0 xi,if  θ  is  wi xij=1nvj,fxjvi,fxi2,if  θ  is  vi,f \frac{\partial}{\partial\theta} \hat y (\mathbf{x}) = \left\{\begin{array}{ll} 1, & \text{if}\; \theta\; \text{is}\; w_0 \\ \ x_i, & \text{if}\; \theta\; \text{is}\; w_i \\ \ x_i \sum_{j=1}^n v_{j, f} x_j - v_{i, f} x_i^2, & \text{if}\; \theta\; \text{is}\; v_{i, f} \end{array}\right.

为了避免过拟合,也引入正则化。所以,FM的最优化问题就变成了:
θ=argminθi=1N(loss(y^(xi),yi)+λθθ2) \theta ^* = \mathop{\arg\min}_{\theta} \sum_{i=1}^N\left(loss(\hat y(x_i) ,y_i)+ \sum \lambda_\theta \theta^2\right)
注:λθ\lambda_\theta是正则化系数。

FFM

在FFM(Field-aware Factorization Machines )中每一维特征(feature)都归属于一个特定的field。对于进行onehot编码后的类别特征都属于同一个field。对于连续特征,一个特征就对应一个Field。例如:

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

当然也可以对连续特征离散化,一个分箱成为一个特征。例如:

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

不论是连续特征还是离散特征,它们都有一个共同点:同一个field下只有一个feature的值不是0,其他feature的值都是0。

FFM模型认为viv_i不仅跟xix_i有关系,还跟与xix_i相乘的xjx_j所属的Field有关系。于是FFM模型的公式如下:
y^=i=1nj=i+1nvi,fjvj,fixixj \hat{y}=\sum_{i=1}^n{\sum_{j=i+1}^n{v_{i,f_j}\cdot v_{j,f_i}x_ix_j}}
与FM的公式相比,它只保留了二次项。如何理解这种二次项系数的变化?可以通过下面的图片来理解 FM 与 FFM 在计算二次项系数时的区别:

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

FM 在计算二次项系数的时候,任意两个特征的组合都需要两个一维的隐含向量(分别对应图中上半部分棕色一维向量 viv_i 和蓝色的一维向量 vjv_j )的内积来表示。

而在FFM中,计算二次项系数的时候,把一维向量扩充了F倍(F表示所有特征对应了F个field,在本例中F取值为3,即field1年龄、field2城市,field3性别),构成“field隐含矩阵”,即图中下半部分棕色的矩阵 vijv_{ij} 和蓝色的矩阵 vjiv_{ji}。当计算 xi,xjx_i, x_j这个二次项的系数时,则需要:

1,从 vijv_{ij} 中取出 xjx_j 特征对应的field所在的行向量vifjv_{if_j}

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

2,从 vjiv_{ji} 中取出 xix_i 特征对应的field所在的行向量vjfiv_{jf_i}

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

然后将取出的向量计算内积作为xixjx_ix_j系数。

总的来说,这个过程可以描述为:每个特征对应了一组隐向量,当 xix_ixjx_j 特征进行组合时,xix_i会从xix_i那组隐向量中选择出与特征xjx_j的域fjf_{j}对应的隐向量vi,fjv_{i, f_{j}} 进行交叉。同理,xjx_j 也会选择与 xix_i 的域 fif_i 对应的隐向量 vj,fiv_{j, f_i} 进行交叉。

如果隐向量的长度为 k,那么FFM的二次参数有 nFknFk 个,远多于FM模型的 nk 个。此外,由于隐向量与field相关,FFM二次项并不能够化简,其预测复杂度是 O(kn2)O(k n^2)

以上文的第一个表格数据为例:

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

计算用户1的y^\hat y过程为:
y^=i=1nj=i+1nvi,fjvj,fixixj=v1,f2v2,f1x1x2+v1,f2v3,f1x1x3+v1,f2v4,f1x1x4+ \begin{aligned} \hat{y}&=\sum_{i=1}^n{\sum_{j=i+1}^n{v_{i,f_j}\cdot v_{j,f_i}x_ix_j}} \\ &=v_{1,f_2}\cdot v_{2,f_1}x_1x_2+v_{1,f_2}\cdot v_{3,f_1}x_1x_3+v_{1,f_2}\cdot v_{4,f_1}x_1x_4+\cdots \end{aligned}
于是 y^\hat yv1,f2v_{1,f2} 的偏导为:
y^v1,f2=v2,f1x1x2+v3,f1x1x3+v4,f1x1x4 \frac{\partial{\hat{y}}}{\partial{v_{1,f_2}}}=v_{2,f1}x_1x_2+v_{3,f1}x_1x_3+v_{4,f1}x_1x_4
注意x2,x3,x4x_2,x_3,x_4是同一个属性的one-hot表示,即x2,x3,x4x_2,x_3,x_4中只有一个为1,其他都为0。在本例中x3=x4=0,x2=1x_3=x_4=0,x_2=1,所以:
y^v1,f2=v2,f1x1x2 \frac{\partial{\hat{y}}}{\partial{v_{1,f_2}}}=v_{2,f_1}x_1x_2
推广到一般情况:
y^vi,fj=vj,fixixj \frac{\partial{\hat{y}}}{\partial{v_{i,f_j}}}=v_{j,f_i}x_ix_j
实际项目中 x 是非常高维的稀疏向量,求导时只关注那些非0项即可。另外,在执行点击率预测时,会在 y^\hat y 外面再套上一层 sigmoid 函数。接下来,我们用 z 来表示 y^\hat y
z=y^=i=1nj=i+1nvi,fjvj,fixixj z=\hat y=\sum_{i=1}^n{\sum_{j=i+1}^n{v_{i,f_j}\cdot v_{j,f_i}x_ix_j}}
用 α 表示对点击率的预测值:
a=σ(z)=11+ez=11+eϕ(v,x) a=\sigma(z)=\frac{1}{1+e^{-z}}=\frac{1}{1+e^{-\phi(v,x)}}
二分类问题常用的交叉熵损失函数:
C=[ylna+(1y)ln(1a)],a=σ(z) C = -[ylna+(1-y)ln(1-a)], a=\sigma(z)
其中,σ 为 sigmoid 函数,则有:
Cz=Caσ(z)=yaσ(z)+1y1aσ(z)=aya(1a)σ(z)=ay \frac{\partial C}{\partial z}=\frac{\partial C}{\partial a}\sigma'(z)=-\frac{y}{a}\sigma'(z)+\frac{1-y}{1-a}\sigma'(z)=\frac{a-y}{a(1-a)}\sigma'(z)=a-y

进而可以得到:
Cz=ay={11+ezif y11+ezif y \frac{\partial C}{\partial z}=a-y=\left\{\begin{matrix}-\frac{1}{1+e^z} & if\ y是正样本 \\ \frac{1}{1+e^{-z}} & if\ y是负样本\end{matrix}\right .
结合上面求出的 y^vi,fj\frac{\partial{\hat{y}}}{\partial{v_{i,f_j}}}Cz\frac{\partial C}{\partial z},代入下面的公式即可求得梯度值:
Cvi,fj=Czzvi,fj \\ \frac{\partial C}{\partial{v_{i,f_j}}}=\frac{\partial C}{\partial z}\frac{\partial{z}}{\partial{v_{i,f_j}}}
然后就可以使用梯度下降算法对参数进行优化了。

双线性 FFM(Bilinear-FFM)

就像前面提到的,FFM 引入了更多的参数,在提升精度的同时也带来了巨大的计算量。国内的微博团队对FFM加以改进,得到了双线性 FFM(Bilinear-FFM)模型。

由于FFM每个特征都需要维护一个 n×Fn \times F 大小的矩阵,如果可以使部分特征共享参数,就能大幅度减少参数,这就是双线性 FFM 的核心思想。如下图所示:

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

具体的参数共享方法又可以分为下面三种方式:

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

就结果而言,改进后的 Bi-FFM 与FFM精度差距不大:

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

但是参数个数少了很多:

CTR经典模型串讲:FM / FFM / 双线性 FFM 相关推导与理解

这意味着以更少的计算量得到近似于FFM的效果,优化还是很明显的。

参考文章:

从 FFM 到 DeepFFM,推荐排序模型到底哪家强?

深入FFM原理与实践

FM在特征组合中的应用

FFM原理及公式推导

分解机(Factorization Machines)推荐算法原理

FFM算法原理及Bi-FFM算法实现