一、前言
介绍DeepFM顺便就可以把FM部分也一起介绍了,就不用单独再来介绍FM因子分解了,另外我是个菜鸟,刚刚入门推荐系统,如果文中有什么问题欢迎大家指出来,我再进行修改,希望和各位同学共同进步。
文章发表于2017年IJCAI,论文地址:DeepFM: A Factorization-Machine based Neural Network for CTR Prediction
二、算法原理
(1)DeepFM中就是DNN和FM的并行结构,最后将两部分得到的输出进行Add则再通过一个全连接层得到最后的输出,首先看一下整体的结构:
(2)首先介绍FM部分,FM部分输入是稀疏矩阵通过词嵌入之后再进行合并,一般使用在一阶和二阶特征之间的组合,如果阶数再高一点,那么计算复杂度也会变得很大,所以作者很好的将FM和DNN进行并行组合来提取特征;
FM的输出公式如下:这个结果是推导之后的结果,刚看到这个肯定会不是很理解;
FM的公式推导:可以看到Xi代表的是第i个特征,n代表的是第i个特征中特征数量;
其实二阶部分就是通过下面的公式来表示的,使用辅助向量Vi和Vj;
没事的同学可以把上面的部分自己手动推导一遍,还是很有意义的。
(3)DNN部分就不用介绍太多了,毕竟还是比较简单的,结构如下图,但是有一点需要注意的是DNN部分的输入是包含了连续特征和embedding之后的稀疏特征,两者进行了拼接之后作为DNN部分的输入;
(4)最终的输出部分:就是将线性部分,FM部分和DNN部分进行组合求和然后再输入给全连接层和sigmoid激活函数得到输出的结果。
三、作者对以下几种模型进行了比较,效果如下
四、代码实现
代码实现部分依然是只写出关键(FM)的部分,其他部分的东西还是得自己慢慢补充,线性部分简单来说其实也就是个全连接层而已,这里不知道理解的对不对;
import tensorflow as tf
from tensorflow.python.keras.layers import Layer
class fm(Layer):
def __init__(self, **kwargs):
super(fm, self).__init__(**kwargs)
def call(self, inputs, **kwargs):
concat_embed = inputs#(batch, filed_size, embedding)
square_of_sum = tf.square(tf.reduce_sum(concat_embed, axis=1, keep_dims=True))#(batch, 1, embedding)
sum_of_square = tf.reduce_sum(concat_embed * concat_embed, axis=1, keep_dims=True)#(batch, 1, embedding)
cross_out = square_of_sum - sum_of_square
cross_out = 0.5 * tf.reduce_sum(cross_out, axis=2, keep_dims=False)#(batch, 1)
return cross_out