【推荐系统】DeepFM

DeepFM包含两部分:神经网络部分与因子分解机部分,分别负责低阶特征的提取和高阶特征的提取。这两部分共享同样的输入。DeepFM的预测结果可以写为:

背景

对于一个基于CTR预估的推荐系统,最重要的是学习到用户点击行为背后隐含的特征组合。在不同的推荐场景中,低阶组合特征或者高阶组合特征可能都会对最终的CTR产生影响。

之前介绍的因子分解机(Factorization Machines, FM)通过对于每一维特征的隐变量内积来提取特征组合。最终的结果也非常好。但是,虽然理论上来讲FM可以对高阶特征组合进行建模,但实际上因为计算复杂度的原因一般都只用到了二阶特征组合。

那么对于高阶的特征组合来说,我们很自然的想法,通过多层的神经网络即DNN去解决。

为了同时学习高阶和低阶的组合特征,Deep FM集成了因子分解机(FM)和深度神经网络(DNN)的体系结构。 FM算法负责对一阶特征以及二阶特征(由一阶特征交叉组合得到的)进行特征的提取; DNN算法负责对高阶特征进行特征的提取。

DNN的局限

对于离散特征的处理,我们使用的是将特征转换成为one-hot的形式,但是将One-hot类型的特征输入到DNN中,会导致网络参数太多:

如何解决这个问题呢,类似于FFM中的思想,将特征分为不同的field:(!!!!!!!!!代码)

再加两层的全链接层,让Dense Vector进行组合,那么高阶特征的组合就出来了

但是低阶和高阶特征组合隐含地体现在隐藏层中,如果我们希望把低阶特征组合单独建模,然后融合高阶特征组合。即将DNN与FM进行一个合理的融合:二者的融合总的来说有两种形式,一是串行结构,二是并行结构,DeepFM,就是并行结构中的一种典型代表。

DeepFM模型

DeepFM结构:

  • FM部分

FM部分的详细结构如下:

因为引入了隐变量的原因,对于几乎不出现或者很少出现的隐变量,FM也可以很好的学习。

FM的输出公式为:

Dense Embeddings层的神经元个数是由embedding vector和field_size共同确定:神经元的个数为embedding vector*field_size。

  • 深度部分

深度部分是一个前馈神经网络。与图像或者语音这类输入不同,图像语音的输入一般是连续而且密集的,然而用于CTR的输入一般是及其稀疏的。因此需要重新设计网络结构。具体实现中为,在第一层隐含层之前,引入一个嵌入层来完成将输入向量压缩到低维稠密向量。

嵌入层(embedding layer)的结构如上图所示。当前网络结构有两个特性,1)尽管不同field的输入长度不同,但是embedding之后向量的长度均为K2)在FM里得到的隐变量 v_{ik} 现在作为了嵌入层网络的权重。

这里的第二点如何理解呢?假设 k=5,首先,对于输入的一条记录,同一个 field 只有一个位置是1,那么在由输入得到dense vector的过程中,输入层只有一个神经元起作用,得到的dense vector其实就是输入层到embedding层该神经元相连的五条线的权重,即 v_{i1} ,v_{i2} , v_{i3} ,v_{i4} ,v_{i5}。这5个值组合起来就是我们在FM中所提到的 v_{i} 。在FM部分和DNN部分,这一块是共享权重的,对同一个特征来说,得到的 v_{i} 是相同的。

每个特征有一个自己的embedding;在同一个field中,每次只有一个特征是1,其余全是0;

注:embedding还需要再了解。

Tensorflow 实现

  • FM 一阶部分:
def first_order_part(self, sparse_id, sparse_value):
     with tf.variable_scope("first-order"):
         W = tf.get_variable("weight",(self.feature_size, 1), \
                  initializer=tf.random_normal_initializer(0.0, 0.01))
         y_first_order = tf.nn.embedding_lookup(W, sparse_id) # None * F * 1
         y_first_order = tf.reduce_sum(tf.multiply(y_first_order, \
                               sparse_value), 1)  # None * 1
         return y_first_order
  • FM 二阶交叉部分:

def second_order_part(self, sparse_id, sparse_value):
    with tf.variable_scope("second-order"):
        V = tf.get_variable("weight",(self.feature_size, self.factor_size),
                initializer=tf.random_normal_initializer(0.0, 0.01))
        self.embeddings = tf.nn.embedding_lookup(V, sparse_id)
        # None * F * K
        self.embeddings = tf.multiply(self.embeddings, sparse_value) 

        # 平方和:None * K
        sum_squared_part = tf.square(tf.reduce_sum(self.embeddings, 1)) 
        # 和平方:None * K
        squared_sum_part = tf.reduce_sum(tf.square(self.embeddings), 1) 

        y_second_order = 0.5 * tf.subtract(sum_squared_part, \
                                    squared_sum_part)
        return y_second_order
  • Deep 部分
def deep_part(self):
    with tf.variable_scope("deep-part"):
        y_deep = tf.reshape(self.embeddings, shape=[-1, \
                        self.field_size * self.factor_size]) # None * (F*K)
        for i in range(0, len(self.deep_layers)):
            y_deep = tf.contrib.layers.fully_connected(y_deep, \ 
                         self.deep_layers[i], activation_fn= \
                         self.deep_layers_activation, scope = 'fc%d' % i)
        return y_deep
  • Deep + FM:
def forward(self, sparse_id, sparse_value):
    sparse_value   = tf.expand_dims(sparse_value, -1)

    y_first_order  = self.first_order_part(sparse_id, sparse_value)
    y_second_order = self.second_order_part(sparse_id, sparse_value)
    y_deep         = self.deep_part()

    with tf.variable_scope("deep-fm"):
        deep_out    = tf.concat([y_first_order, y_second_order, \
                         y_deep], axis=1)
        deep_out    = tf.contrib.layers.fully_connected(deep_out, 1, \
            activation_fn=tf.nn.sigmoid, scope = 'deepfm_out')

        return tf.reduce_sum(deep_out, axis=1)

参考:

推荐系统遇上深度学习(三)--DeepFM模型理论和实践

DeepFM算法解析及Python实现

CTR预估模型FM、FFM、DeepFM

ctr预估之DeepFM - Charles Xiao的文章 - 知乎

如何用keras实现deepFM

发布了316 篇原创文章 · 获赞 96 · 访问量 11万+

猜你喜欢

转载自blog.csdn.net/weixin_31866177/article/details/105298503