一、背景
FFM算法,全称是Field-aware Factorization Machines,是FM(Factorization Machines)的改进版。FFM由Yu-Chin Juan与其比赛队员提出,他们借鉴了field(域)概念提出了FM的升级版模型。简单来说,通过引入field的概念,FFM把相同性质的特征归于同一个field。
本文主要介绍FFM的理论,由于其算法复杂度比较高,在现在或许不是线上推荐系统的第一选择,但其理论意义和思想仍然很值得我们学习。
本文需要有FM的背景知识,详细请参考《(一)因式分解机(Factorization Machine,FM)原理及实践》
二、FFM模型表达
我们知道,在FM中,将每个交叉项参数 w i j w_{ij} wij用隐向量的内积 ⟨ v i , v j ⟩ \langle \mathbf{v}_i, \mathbf{v}_j\rangle ⟨vi,vj⟩表示,即每个特征的参数都有一个 k k k维的特征来描述。而在FFM中,会对“类型”相同的特征归到一个filed中,也就是说,如果有多个特征来描述一个事情,那么这些特征自然可以归到一个filed。
举例,同一个categorical特征经过One-Hot编码生成的数值特征都可以放到同一个field,包括用户性别、职业、品类偏好等。在FFM中,每一维特征 x i x_i xi,针对其它特征的每一种field f j f_j fj,都会学习一个隐向量 v i , f j \mathbf{v}_{i, f_j} vi,fj。因此,隐向量不仅与特征相关,也与field相关。
我们继续从FM的文章续起,不妨假设样本的 n n n 个特征属于 f f f 个field,那么FFM的二次项有 n f nf nf个隐向量。而在FM模型中,每一个特征的隐向量只有一个。FM可以看作FFM的特例,是把所有特征都归属到一个field时的FFM模型。根据FFM的field特性,可以导出其模型方程,如下:
y ( x ) = w 0 + ∑ i = 1 n w i x i + ∑ i = 1 n ∑ j = i + 1 n ⟨ v i , f j , v j , f i ⟩ x i x j (1) y(\mathbf{x}) = w_0 + \sum_{i=1}^n w_i x_i + \sum_{i=1}^n \sum_{j=i+1}^n \langle \mathbf{v}_{i, f_j}, \mathbf{v}_{j, f_i} \rangle x_i x_j \qquad \text{(1)} y(x)=w0+i=1∑nwixi+i=1∑nj=i+1∑n⟨vi,fj,vj,fi⟩xixj(1)
其中, f j f_j fj 是第 j j j 个特征所属的field。如果隐向量的长度为 k k k,那么FFM的二次参数有 n f k nfk nfk 个( n n n为特征维度, f f f为field个数),远多于FM模型的 n k nk nk 个。此外,由于隐向量与field相关,FFM二次项并不能够化简,其预测复杂度是 O ( k n 2 ) O(kn^2) O(kn2)。
与FM的模型方程对比:
y ( x ) = w 0 + ∑ i = 1 n w i x i + ∑ i = 1 n ∑ j = i + 1 n ⟨ v i , v j ⟩ x i x j (2) y(\mathbf{x}) = w_0 + \sum_{i=1}^{n} w_i x_i + \sum_{i=1}^{n} \sum_{j=i+1}^{n} \langle \mathbf{v}_i, \mathbf{v}_j \rangle x_i x_j \qquad \text{(2)} y(x)=w0+i=1∑nwixi+i=1∑nj=i+1∑n⟨vi,vj⟩xixj(2)
对比(1)和(2),我们可以很清楚的看到,FFM假设了特征会属于field(当然,1个filed会有多个特征)。
我们可以总结:
- FFM优点:细化隐向量的表示,同一特征针对不同field使用不同隐向量,模型建模更加准确
- FFM缺点:计算复杂度比较高,参数个数为 n f k nfk nfk,计算复杂度为 O ( k n 2 ) O(kn^2) O(kn2)
三、举例
作者在参考文献【2】中举了一个FFM特征组合方式的例子:
可以看到,这个样本有4个特征,其中User, Moive, Genre是类别型特征,Price是连续性特征。如果做了one-hot处理后,我们将所有的特征和对应的field映射成整数编号。
对应的FFM有10项(4*5/2)输出为:
下标中,蓝色对应feature编号,红色对应field编号。绿色是特征取值。
Yu-Chin Juan实现了一个C++版的FFM模型,源码可从Github下载。这个版本的FFM省略了常数项和一次项,模型方程如下:
ϕ
(
w
,
x
)
=
∑
j
1
,
j
2
∈
C
2
⟨
w
j
1
,
f
2
,
w
j
2
,
f
1
⟩
x
j
1
x
j
2
(3)
\phi(\mathbf{w}, \mathbf{x}) = \sum_{j_1, j_2 \in \mathcal{C}_2} \langle \mathbf{w}_{j_1, f_2}, \mathbf{w}_{j_2, f_1} \rangle x_{j_1} x_{j_2} \qquad \text{(3)}
ϕ(w,x)=j1,j2∈C2∑⟨wj1,f2,wj2,f1⟩xj1xj2(3)
其中,
C
2
\mathcal{C}_2
C2 是非零特征的二元组合,
j
1
j_1
j1 是特征,属于field
f
1
f_1
f1,
w
j
1
,
f
2
\mathbf{w}_{j_1, f_2}
wj1,f2 是特征
j
1
j_1
j1 对field
f
2
f_2
f2 的隐向量。此FFM模型采用logistic loss作为损失函数,和L2惩罚项,因此只能用于二元分类问题。
min
w
∑
i
=
1
L
log
(
1
+
exp
{
−
y
i
ϕ
(
w
,
x
i
)
}
)
+
λ
2
∥
w
∥
2
\min_{\mathbf{w}} \sum_{i=1}^L \log \big( 1 + \exp\{ -y_i \phi (\mathbf{w}, \mathbf{x}_i ) \} \big) + \frac{\lambda}{2} \| \mathbf{w} \|^2
wmini=1∑Llog(1+exp{−yiϕ(w,xi)})+2λ∥w∥2
其中, y i ∈ { − 1 , 1 } y_i \in \{-1, 1\} yi∈{−1,1} 是第 i i i 个样本的label, L L L 是训练样本数量,λ 是惩罚项系数。模型采用SGD优化,优化流程如下:
参考 Algorithm1, 下面简单解释一下FFM的SGD优化过程。 算法的输入
t
r
tr
tr、
v
a
va
va、
p
a
pa
pa 分别是训练样本集、验证样本集和训练参数设置。
-
(1)根据样本特征数量 ( t r . n ) (tr.n) (tr.n)、field的个数 ( t r . m ) (tr.m) (tr.m)和训练参数 ( p a ) (pa) (pa),生成初始化模型,即随机生成模型的参数;
-
(2)如果归一化参数 p a . n o r m pa.norm pa.norm 为真,计算训练和验证样本的归一化系数,样本 i i i 的归一化系数为
R [ i ] = 1 ∥ X [ i ] ∥ R[i] = \frac{1}{\| \mathbf{X}[i] \|} R[i]=∥X[i]∥1 -
(3)对每一轮迭代,如果随机更新参数 p a . r a n d pa.rand pa.rand 为真,随机打乱训练样本的顺序;
-
(4)对每一个训练样本,执行如下操作
-
计算每一个样本的FFM项,即公式(3)中的输出 ϕ \phi ϕ;
-
计算每一个样本的训练误差,如算法所示,这里采用的是交叉熵损失函数 log ( 1 + e ϕ ) \log ( 1 + e\phi ) log(1+eϕ);
-
利用单个样本的损失函数计算梯度 g Φ g_\Phi gΦ,再根据梯度更新模型参数;
-
-
(5)对每一个验证样本,计算样本的FFM输出,计算验证误差;
-
(6)重复步骤3~5,直到迭代结束或验证误差达到最小。
在实际中,也有许多优化的地方,详细可以参考文献【3】.
四、代码实践
参考文献【4】给了一个FFM的demo,有兴趣的读者可以follow一下。
参考文献
【1】Field-aware Factorization Machines for CTR Prediction
【2】Field-aware Factorization Machines
PPT,详细介绍了文中的例子。
【3】深入FFM原理与实践
【4】https://github.com/princewen/tensorflow_practice/blob/master/recommendation/recommendation-FFM-Demo/FFM_model.py