Weiguo's Station

  • 博客首页

  • 文章归档

  • 分类专栏

  • 各种标签

  • 站点搜索

Field-aware Factorization Machines for CTR Prediction笔记

发表于 2019-10-06 更新于 2021-03-22 分类于 推荐系统

FFM(Field Factorization Machine)是在FM的基础上引入了场(Field)的概念而形成的新模型。 在FM中计算特征 $x_i$ 与其他特征的交叉影响时, 使用的都是同一个隐向量 $v_i$ 。 而FFM将特征按照事先的规则分为多个场(Field), 特征 $x_i$ 属于某个特定的场$f$。 每个特征将被映射为多个隐向量 $v_{i,1}, v_{i,2}, \cdots, v_{i,f}$ , 每个隐向量对应一个场。 当两个特征 $x_i, x_j$ 组合时, 用对方对应的场对应的隐向量做内积:

FFM 由于引入了场, 使得每两组特征交叉的隐向量都是独立的, 可以取得更好的组合效果, FM 可以看做只有一个场的 FFM。 在FFM中,每一维特征 $x_i$,针对其它特征的每一种field $f_j$,都会学习一个隐向量 $v_{i, f_j}$。 这比FM增加了隐向量的数量。

FFM 预测公式:

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

Yu-Chin Juan实现了一个C++版的FFM模型,源码可从Github下载。这个版本的FFM省略了常数项和一次项,模型方程如下:

其中,$\mathcal{C}_2$是非零特征的二元组合,$j_1$ 是特征,属于field $f_1$,$w_{j_1,f_2}$ 是特征 $j_1$ 对field $f_2$ 的隐向量。 此FFM模型采用logistic loss作为损失函数,和L2惩罚项,因此只能用于二元分类问题。

其中,$y_i \in {−1,1}$ 是第 $i$ 个样本的label,$L$ 是训练样本数量,$\lambda$ 是惩罚项系数。

FFM_TensorFlow实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# this is code
with tf.variable_scope('linear_layer'):
w0 = tf.get_variable('w0', shape=[self.num_classes],
initializer=tf.zeros_initializer())
self.w = tf.get_variable('w', shape=[self.p, num_classes],
initializer=tf.truncated_normal_initializer(mean=0, stddev=0.01))
self.linear_terms = tf.add(tf.matmul(self.X, self.w), w0)

with tf.variable_scope('interaction_layer'):
self.v = tf.get_variable('v', shape=[self.p, self.field, self.k],
initializer=tf.truncated_normal_initializer(mean=0, stddev=0.01))
self.interaction_terms = tf.constant(0, dtype='float32')
for i in range(self.p):
for j in range(i + 1, self.p):
self.interaction_terms += tf.multiply(
tf.reduce_sum(tf.multiply(self.v[i, self.feature2field[i]], self.v[j, self.feature2field[j]])),
tf.multiply(self.X[:, i], self.X[:, j]))
self.interaction_terms = tf.reshape(self.interaction_terms, [-1, 1])
self.y_out = tf.math.add(self.linear_terms, self.interaction_terms)
if self.num_classes == 2:
self.y_out_prob = tf.nn.sigmoid(self.y_out)
elif self.num_classes > 2:
self.y_out_prob = tf.nn.softmax(self.y_out)

算法流程及工程实现的trick,详细阅读 参考文献[1]。

  1. 深入FFM原理与实践
  2. Field-aware Factorization Machine
  3. LLSean/data-mining
# 模型算法
Factorization Machines笔记
Neural Factorization Machines for Sparse Predictive Analytics笔记
WeiguoZHAO

WeiguoZHAO

Welcome to my blog~
87 日志
13 分类
49 标签
GitHub E-Mail
大牛们
  • colah's blog
  • 王喆的Github
  • 刘建平的Github
  • 美团技术团队
© 2021 WeiguoZHAO
0%