美文网首页
因子分解机(FM)系列总结

因子分解机(FM)系列总结

作者: 小透明苞谷 | 来源:发表于2019-05-03 17:40 被阅读0次

背景

  • 特征之间是关联的,线性模型中需要人工的特征组合,表达能力受限

  • one-hot编码带来特征空间暴增,数据稀疏,需要的参数量暴增


  • 在数据很稀疏的情况下,满足xi,xj都不为0的情况非常少,这样将导致wij无法通过训练得出。

FM

特点:

  • 可以自动进行特征组合

  • 数据稀疏的情况下表现依然良好

做法:

  • 利用矩阵分解的思想,引入辅助V矩阵,对W进行建模​


实现:

w0 = tf.Variable(tf.zeros([1]))
w = tf.Variable(tf.zeros([p]))
v = tf.Variable(tf.random_normal([k, p], mean=0, stddev=0.01))


linear_terms = tf.add(w0, tf.reduce_sum(tf.multiply(w, x), 1, keep_dims=True)) # n * 1

pair_interactions = 0.5 * tf.reduce_sum(
    tf.subtract(
        tf.pow(tf.matmul(x, tf.transpose(v)), 2),
        tf.matmul(tf.pow(x, 2), tf.transpose(tf.pow(v, 2)))
    ), axis=1, keep_dims=True)

y_hat = tf.add(linear_terms, pair_interactions)

lambda_w = tf.constant(0.001, name='lambda_w')
lambda_v = tf.constant(0.001, name='lambda_v')

l2_norm = tf.reduce_sum(
    tf.add(
        tf.multiply(lambda_w, tf.pow(w, 2)),
        tf.multiply(lambda_v, tf.pow(v, 2))
    )
)

error = tf.reduce_mean(tf.square(y - y_hat))
loss = tf.add(error, l2_norm)


注意:线性项和二次项是直接相加的(标量)

FFM

背景:

  • one-hot类型变量会导致严重的数据特征稀疏

做法:

  • 引入field的概念,同一类经过One-Hot编码生成的特征都可以放到同一个field

  • 在FFM中,每一维特征 xi,针对其它特征的每一种field fj,都会学习一个隐向量 ​。因此,隐向量不仅与特征相关,也与field相关。也就是说,“Day=26/11/15”这个特征与“Country”特征和“Ad_type"特征进行关联的时候使用不同的隐向量,这与“Country”和“Ad_type”的内在差异相符。

不足:

  • FFM的二次参数有 nfk 个,远多于FM模型的 nk个。

  • 此外,由于隐向量与field相关,FFM二次项并不能够化简,其预测复杂度是 O(kn^2)。

DeepFM

背景:

  • FM,FFM实际应用中受限于计算复杂度,一般也就只考虑到 2 阶交叉特征

优点/做法:

  • 不需要人工特征工程

  • FM 提取低阶组合特征,Deep 提取高阶组合特征,同时学习低阶和高阶的组合特征

  • FM 模块和 Deep 模块共享 Feature Embedding 部分,参数量少,可以更快的训练

DeepFM
  • one-hot 之前的特征维度,称之为field_size。

  • one-hot 之后的特征维度,称之为feature_size。

Embedding层作用:

  • Embedding 矩阵也就是隐向量 V

  • 输入层是onehot的,特别稀疏,直接全连接的话参数量太大,所以先降维再全连接

FM部分

FM

线性项(Addition Unit反映的是 1 阶的特征):
w_0+\sum_{i=1}^n{w_ix_i}

交叉项(内积单元反映的是 2 阶的组合特征对于预测结果的影响):
\sum_{i=1}^{n-1}\sum_{j=i+1}^{n}w_{ij}x_ix_j = \frac 1 2 \sum_{l=1}^k[(\sum_{i=1}^n v_{i,f}x_i)^2-\sum_{i=1}^n v_{i,f}^2x_i^2)]
注意:此处是向量,fm的输出维度是field_size(一阶) + embedding_size(二阶)

DNN部分

DNN

output部分

\hat y = sigmoid(tf.concat([y_{fm\_first\_order}, y_{fm\_second\_order}, y_{deep}], axis=1))

注意是concat,不是add

# model
self.embeddings = tf.nn.embedding_lookup(self.weights['feature_embeddings'], self.feat_index) # N * F * K
feat_value = tf.reshape(self.feat_value,shape=[-1,self.field_size,1])
self.embeddings = tf.multiply(self.embeddings,feat_value)
​
print(self.embeddings.shape)                #none, field_size, embedding_size
print(self.weights['feature_bias'].shape)  #feature_size, 1
​
# first order term          #none, field_size
self.y_first_order = tf.nn.embedding_lookup(self.weights['feature_bias'],self.feat_index)
self.y_first_order = tf.reduce_sum(tf.multiply(self.y_first_order,feat_value),2)
self.y_first_order = tf.nn.dropout(self.y_first_order,self.dropout_keep_fm[0]) 
​
# second order term                # None * K
# sum-square-part
self.summed_features_emb = tf.reduce_sum(self.embeddings,1) # None * k
self.summed_features_emb_square = tf.square(self.summed_features_emb) # None * K
# squre-sum-part
self.squared_features_emb = tf.square(self.embeddings)
self.squared_sum_features_emb = tf.reduce_sum(self.squared_features_emb, 1)  # None * K
# second order
self.y_second_order = 0.5 * tf.subtract(self.summed_features_emb_square,self.squared_sum_features_emb)
self.y_second_order = tf.nn.dropout(self.y_second_order,self.dropout_keep_fm[1])
​
# Deep component
self.y_deep = tf.reshape(self.embeddings,shape=[-1, self.field_size * self.embedding_size])
self.y_deep = tf.nn.dropout(self.y_deep,self.dropout_keep_deep[0])
​
for i in range(0,len(self.deep_layers)):
 self.y_deep = tf.add(tf.matmul(self.y_deep,self.weights["layer_%d" %i]), self.weights["bias_%d"%i])
 self.y_deep = self.deep_layers_activation(self.y_deep)
 self.y_deep = tf.nn.dropout(self.y_deep,self.dropout_keep_deep[i+1])
 print("y_deep:" + str(self.y_deep.shape))
​
#----DeepFM---------
 self.out = tf.add(tf.matmul(concat_input, self.weights['concat_projection']), self.weights['concat_bias'])

参考:

相关文章

  • 因子分解机(FM)系列总结

    背景 特征之间是关联的,线性模型中需要人工的特征组合,表达能力受限 one-hot编码带来特征空间暴增,数据稀疏,...

  • FM算法

    FM算法(Factorization Machine) 因子分解机(Factorization Machine, ...

  • 推荐系统玩家 之 因子分解机FM(Factorization M

    推荐系统玩家 之 因子分解机FM(Factorization Machines)

  • 聊聊因子分解机(FM)

    说到FM先说一个叫交叉特征的事,因为特征都是相互独立的,我们想要找到一些组合特征,只能两两交叉相乘,所以我们在线性...

  • 推荐算法之—FM

    1、什么是FM算法 FM即Factor Machine,因子分解机 2、为什么需要FM 1)、特征组合是许多机器学...

  • 02-21:FM算法

    FM算法 回头看其实FM算法也是非常简单啊 1、算法原理 因子分解机(Factorization Machine,...

  • FM算法

    因子分解机(Factorization Machine, FM)是由Steffen Rendle提出的一种基于矩阵...

  • FM算法详解(因子分解机)

    什么是FM? FM即Factor Machine,因子分解机。 任意的N×N 实对称矩阵]都有 N 个线性无关的特...

  • 深度学习CTR预估(一)——FM模型numpy和tensorfl

    1、FM的原理 1.1 FM介绍及其优缺点  FM就是因子分解机。通过不同组合不同的特征,解决推荐系统中数据稀疏的...

  • FM,稀疏下的艺术

    最近正好处理一些稀疏数据,抽空看了下FM论文,Factorization Machines,因子分解机。在SVM之...

网友评论

      本文标题:因子分解机(FM)系列总结

      本文链接:https://www.haomeiwen.com/subject/tndznqtx.html