基于深度学习的推荐(六):CTR预估经典模型NFM

文章目录

    • 公众号
    • 前言
    • NFM模型
    • 代码实战
    • 参考

公众号

关注公众号:推荐算法工程师,输入"进群",加入交流群,和小伙伴们一起讨论机器学习,深度学习,推荐算法.

基于深度学习的推荐(六):CTR预估经典模型NFM_第1张图片

前言

早期做特征工程的时候,采用人工或决策树等来选择特征,然而这些方法无法学习到训练集中没有出现的特征组合.而近几年出现的基于embedding的方法,可以学习到训练集中没有出现的组合,作者将embedding方法归为两类,一类是FM这种线性模型,之前介绍过的FNN就是利用FM作为初始化的embedding;另一类是基于神经网络的非线性模型,NFM(Neural Factorization Machine)则是将两种embedding结合起来.NFM是发表在SIGIR 2017上的文章,出现在深度学习与推荐系统结合的初期,模型相对较为简单,可以拿来练习tensorflow.

论文地址:https://arxiv.org/pdf/1708.05027.pdf

NFM模型

首先来回顾下FM模型:
基于深度学习的推荐(六):CTR预估经典模型NFM_第2张图片
设embedding向量维度为k,其中的二阶交叉项可以进行优化:
基于深度学习的推荐(六):CTR预估经典模型NFM_第3张图片

交叉项得到的是一个值,如果去掉最外面那层求和,得到一个k维的向量.这个k维的向量就是所谓的"Bi-Interaction Layer"的结果:

基于深度学习的推荐(六):CTR预估经典模型NFM_第4张图片
将这个向量输入全连接层,得到预测结果f(x),而最终的预估公式就是:
基于深度学习的推荐(六):CTR预估经典模型NFM_第5张图片
此时再看模型一目了然:
基于深度学习的推荐(六):CTR预估经典模型NFM_第6张图片

代码实战

这部分代码改自之前AFM的代码,有兴趣可以自己改改试一试,挺简单的.其中interaction layer的实现提供了优化前和优化后两种写法,可以运行下比较比较时间,差距蛮大.简单看看几个关键点的实现,首先是embedding layer:

with tf.name_scope('Embedding_Layer'):
    self.embeddings = tf.nn.embedding_lookup(self.weights['feature_embeddings'], self.feature_index)  # [None, field_size, embedding_size]
    feat_value = tf.reshape(self.feature_value, shape=[-1, self.field_size, 1])  # [None, field_size, 1]
    self.embeddings = tf.multiply(self.embeddings, feat_value)  # [None, field_size, embedding_size]

然后是预测公式的线性部分:

with tf.name_scope('linear_part'):
    self.linear_part = tf.nn.embedding_lookup(self.weights['linear_w'],self.feature_index)  # [None, field_size, 1]
    self.linear_part = tf.reduce_sum(tf.multiply(self.linear_part, feat_value), axis=2)  # [None, field_size]
    self.linear_part = tf.nn.dropout(self.linear_part, self.dropout_keep_fm[0])  # [None, field_size]
    self.linear_out = tf.reduce_sum(self.linear_part, axis=1, keep_dims=True) # [None, 1]
    self.w0 = tf.multiply(self.biases['w0'], tf.ones_like(self.linear_out)) # [None, 1]

B-Interaction Layer这一层的实现比较简单:

with tf.variable_scope('interaction_layer'):
    self.sum_square_emb = tf.square(tf.reduce_sum(self.embeddings, axis=1)) # [None, embedding_size]
    self.square_sum_emb = tf.reduce_sum(tf.square(self.embeddings), axis=1) # [None, embedding_size]
    self.fully_out = 0.5 * tf.subtract(self.sum_square_emb, self.square_sum_emb) # [None, embedding_size]

然后就是后面的全连接层和最后的预测结果:

with tf.name_scope('fully_layer'):
    for i in range(len(self.deep_layers)):
        self.fully_out = tf.add(tf.matmul(self.fully_out, self.weights[i]), self.biases[i])
        self.fully_out = self.deep_layers_activation(self.fully_out)
        if(self.batch_norm):
            self.fully_out = self.batch_norm_layer(self.fully_out, self.train_phase)
        self.fully_out = tf.nn.dropout(self.fully_out, keep_prob=self.dropout_fm[i])

with tf.name_scope('out'):
    self.out = tf.add_n([self.w0, self.linear_out, self.fully_out]) # # yAFM = w0 + wx + f(x)

参考代码:

afm代码

nfm如何实现

完整数据和代码:

nfm完整代码和数据链接

参考

[1] https://arxiv.org/pdf/1708.05027.pdf

[2] https://github.com/faychu/nfm/blob/master/NeuralFM.py

你可能感兴趣的:(推荐系统与深度学习)