DeepFM算法原理及实现

模型解决问题

因为DeepFM模型基本是在Wide&deep的基础上进行改进而来,所有DeepFM主要解决的问题是:

1、Wide&deep 模型需要手动做特征交叉,而DeepFM因为有FM层进行一阶和二阶特征自动组合,所以不需要手动特征工程

2、FM 模块和 Deep 模块共享 Feature Embedding 部分,可以更快的训练,以及更精确的训练学习

3、能同时学习低阶和高阶的组合特征

模型原理

在这里插入图片描述

下面分析原理的过程中结合ChenglongChen的代码进行分析,感谢作者提供了如此完善的代码实现~

数据预处理


因为下文中模型部分用到feat_index, feat_value两个关键变量,故先说明下数据预处理的步骤

  • feat_index中:
    1、如果特征是一个数值特征,所有sample的这个特征都是一个值
    2、如果特征是一个类别特征,每个类别特征值是一个独立的值

  • feat_value中:
    1、如果特征是一个数值特征,保留原值
    2、如果特征是一个类别特征,特征值设置为1

# 生成特征列字典
def gen_feat_dict(self):
    if self.dfTrain is None:
        dfTrain = pd.read_csv(self.trainfile)
    else:
        dfTrain = self.dfTrain
    if self.dfTest is None:
        dfTest = pd.read_csv(self.testfile)
    else:
        dfTest = self.dfTest
    df = pd.concat([dfTrain, dfTest])
    self.feat_dict = {
   }
    tc = 0
    for col in df.columns:
        if col in self.ignore_cols:
            continue
        if col in self.numeric_cols:
            # map to a single index
            self.feat_dict[col] = tc
            tc += 1
        else:
            us = df[col].unique()
            self.feat_dict[col] = dict(zip(us, range(tc, len(us)+tc)))
            tc += len(us)
    self.feat_dim = tc

# 根据特征列字典,对数据进行编码
dfv = dfi.copy()
for col in dfi.columns:
    if col in self.feat_dict.ignore_cols:
        dfi.drop(col, axis=1, inplace=True)
        dfv.drop(col, axis=1, inplace=True)
        continue
    if col in self.feat_dict.numeric_cols:
        dfi[col] = self.feat_dict.feat_dict[col]
    else:
        dfi[col] = dfi[col].map(self.feat_dict.feat_dict[col])
        dfv[col] = 1

EMbedding层

FM层同Deep层共享相同的EMbedding,优点:

  • 训练更快:同wide&deep相比,wide&deep中wide层和deep层分别对特征进行处理,输入特征维度很大;同时wide中包含大量人工设计的组合特征,权重参数多,计算复杂度大
  • 从论文结果看,训练结果更加准确
"""
 理解
 feat_index维度: [None, field_size] 这里传入的是sample的feature编码
 self.weights中feature_embeddings维度:[feature_size, embedding_size]
 Embedding实际等于tf.gather,返回维度为None * field_size * embedding_size
 filed_size: 每一个特征
 embedding_size: 每一个特征embedding后的向量, 针对数据特征来说,所有sample数值特征embedding后完全相同,对sample之间差异没有影响
 """

 self.embeddings = tf.nn.embedding_lookup(self.weights["feature_embeddings"],
                                                  self.feat_index)  # None * F * K
 # feat_value = [None * F] => 将二维tensor转化为三位tensor
 feat_value = tf.reshape(self.feat_value, shape=[-1, self.field_size, 1])
 # feature_value中类别特征为1,此时类别特征即为Embedding weights中的向量
 self.embeddings = tf.multiply(self.embeddings, feat_value)

FM层

y F M = < w , x > + ∑ i n ∑ j = i + 1 n < v i , v j > x i x j x i , x j 为 特 征 值 v i , v j 为 特 征

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值