一般国内涉及到推荐模型的公司,发展历程为传统机器学习LR-->FM到深度学习wide&deep、deepfm、DCN...这些。目前我所在的公司采用的是online fm模型,准备向深度学习进军,所以最近也是在调研一些工业界用的比较多的模型,以此记录一下学习历程,因为自己本身对tensorflow不是很熟悉,一些看似简单的模型架构实现起来很困难(说到底就是线性代数学的差,矩阵维度傻傻算不清楚),所以博主准备从模型维度出发全面瓦解模型思想。
如果你足够了解fm模型,那么deepfm也就非常简单了,他主要分为两部分
模型所需的参数
构建的原始权重参数
首先要弄清楚field size和feature size的概念和区别,在对于category特征时,例如特征sex列,有(man,woman,null)三个特征值,那么我们一般要先将特征one-hot一下为三个特征列,若某个用户性别时男,那么他的表示就是(1,0,0),女就是(0,1,0),以此递推null就是(0,0,1),那么性别这个特征就是一个field,他的feature size就是3个(男,女,null)。所以说可能存在每个filed内部长度不一样的问题,但是embedding这层的长度就是一样的了(F*K)(每个field从embedding矩阵中选出一行拼接成dense embedding)
上模型架构图如下
这个模型架构其实完全符合fm的本身计算公式,之所以会提到这个是因为我们最开始实现的是非稀疏数据作为输入,然后直接利用fm的化简公式进行构建,后来考虑到公司都是libsvm数据,故考虑这个fm layer,最开始我看github上deepfm的源码一度是以为二者有差别的,后来和同时争论一番发现我被完美说服,最重要的就是我忽略了上图中weight-1 connection部分,我以为权重还是参数需要训练的,所以希望大家阅读一些新的模型的论文时,能仔仔细细的摸清模型的架构图,一般描绘的都是非常详细的,然后掌握好维度问题,复现就没啥问题了。
二层交叉一般是通过化简公式求,即
# FM layer
self.embeddings = tf.nn.embedding_lookup(self.weights['feature_embeddings'], self.train_features) # None * F * K
# ---------- first order term ----------
self.y_first_order = tf.nn.embedding_lookup(self.weights['feature_bias'], self.train_features) # None * F * 1
self.y_first_order = tf.reduce_sum(self.y_first_order,2) # None * F
# ---------- second order term ---------------
# 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
# square_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) # None * K
如果之时fm,那么将y_first_order和y_second_layer拼接成[None,K+F],在第一维度求和[B,1]即为fm的输出
deep层非常简单,就是一个简单的DNN模型,架构如下
从图可以看出,dense embedding就是他的input层了,那么input layer维度是[B,F*K]
之后全连接层就可以随便定义了,比较简单,不细说了
最后一层yDNN输出维度就是[B,1]
和yFM想加,再过一下sigmoid函数就是我们模型预测的y_hat了
y_hat = sigmoid(yDNN+yFM)
思考?:
1. 如果存在multi-hot问题怎么办,也就是说一个field里面为0的因子不止有1个?
可以考虑加池化,可参考https://zhuanlan.zhihu.com/p/48057256
2. 工业界公司如果线上已经是fm模型了,那要实现deepfm还需要重新搭吗?
我个人觉得是如果是想从fm转型至deepfm,那么可以直接用现有的embedding矩阵,再做个dnn,两者融合就ok。
本文仅代表自己一些看法观点,如有错误或者不足欢迎指正,在此附上个人微信,欢迎共同探讨!