DeepFM And FM

本文详细介绍了Factorization Machines(FM)的工作原理及其在处理稀疏数据方面的优势,并通过实例展示了FM的数学表达和代码实现过程。此外,还探讨了结合深度学习的DeepFM模型如何有效利用FM来挖掘低阶特征,而通过深层神经网络来捕捉高阶特征。

背景

Rendle S. Factorization machines[C]//2010 IEEE International Conference on Data Mining. IEEE, 2010: 995-1000.

FM 原理

W=[143283277208206]{\bf{W}} = \left[ {\begin{matrix}{} {14}&{32}&8\\ {32}&{77}&{20}\\ 8&{20}&6 \end{matrix}} \right]W=143283277208206

在这里插入图片描述
在这里插入图片描述
这种写法可以直接用下述代码中的two写法。

#######one#######
X=np.matrix([1,2,3])
V=np.matrix([[1,2,3],[4,5,6],[1,2,1]])
XX=X.T*X
W=V*V.T
#减号后面的部分相当于取W对角线元素与x相乘,numpy的取法.diagonal()
res = np.multiply(XX,W).sum() - np.multiply(sum(np.multiply(V,V).T),np.multiply(X,X)).sum()
print(res)
#######two#######
dataMatrix=np.matrix([1,2,3])
v=np.matrix([[1,2,3],[4,5,6],[1,2,1]])
inter_1 = dataMatrix * v
inter_2 = np.multiply(dataMatrix, dataMatrix) * np.multiply(v, v)  #二阶交叉项的计算
interaction = sum(np.multiply(inter_1, inter_1) - inter_2).sum()
print(interaction)
one表示的写法和two表示的写法是一样的。

这里的xix_ixi表示单个一行元素中的一个值。

为什么用FM, 例如豆瓣上有20000部电影,但是小王只看了200部,那么如果对小王所看的电影进行构建一行向量,那么将有很多是0,也就是one-hot编码。所以通过引入隐向量可以进行更少的编码。

数据集描述

https://blog.youkuaiyun.com/weixin_33669611/article/details/112111571

对于上述公式,通过和的形式表现为三项,第一项可以看做为bais(用来防止过拟合),第二项和第一项合起来可以看做一个线性模型,第三项包含了特征与特征之间的关系。

对第三项进行化简,然后得到:

在这里插入图片描述

代码实现
  1. 数据归一化处理
  2. 初始化偏置,一维向量,二维向量V(n,k)k的维度可以自己设定,这也是为什么使用FM的原因, nnn表示单个样本特征的个数。
  3. 进行for循环迭代,设置迭代次数
  4. 在for循环里面计算损失,并依据损失求导计算偏执
参考资料

https://www.cnblogs.com/wkang/p/9588360.html
可以使用的代码:
https://www.jianshu.com/p/610dff83f709

代码实现

https://github.com/ChenaniahMe/codes/tree/main/FM

DeepFM

https://blog.youkuaiyun.com/qq_15111861/article/details/94194240

论文来源:

Guo H, Tang R, Ye Y, et al. DeepFM: a factorization-machine based neural network for CTR prediction[J]. arXiv preprint arXiv:1703.04247, 2017.

算法实现和代码讲解

https://github.com/princewen/tensorflow_practice/blob/master/recommendation/Basic-DeepFM-model/DeepFM-StepByStep.ipynb

实现代码:

import torch
import torch.nn as nn
import torch.nn.functional as F

class DeepFM(nn.Module):
    def __init__(self, field_dims, embed_dim, mlp_dims, dropout):
        super(DeepFM, self).__init__()
        self.num_fields = len(field_dims)
        self.embedding = nn.Embedding(sum(field_dims), embed_dim)
        
        # Initialize FM component
        self.linear = nn.Embedding(sum(field_dims), 1)
        self.bias = nn.Parameter(torch.zeros((1,)))
        
        # Initialize DNN component
        input_dim = self.num_fields * embed_dim
        layers = []
        for dim in mlp_dims:
            layers.append(nn.Linear(input_dim, dim))
            layers.append(nn.ReLU())
            layers.append(nn.Dropout(dropout))
            input_dim = dim
        layers.append(nn.Linear(input_dim, 1))
        self.mlp = nn.Sequential(*layers)
        
        # Field offsets for embedding lookup
        self.offsets = torch.tensor((0, *torch.cumsum(torch.tensor(field_dims[:-1]), dim=0)), dtype=torch.long)

    def forward(self, x):
        # FM component
        x = x + self.offsets.to(x.device)
        linear_part = torch.sum(self.linear(x), dim=1) + self.bias
        
        # Embedding lookup
        embeddings = self.embedding(x)
        
        # FM interaction term
        square_of_sum = torch.sum(embeddings, dim=1) ** 2
        sum_of_square = torch.sum(embeddings ** 2, dim=1)
        fm_part = 0.5 * torch.sum(square_of_sum - sum_of_square, dim=1, keepdim=True)
        
        # DNN component
        dnn_input = embeddings.view(-1, self.num_fields * embeddings.size(2))
        dnn_part = self.mlp(dnn_input)
        
        # Final output
        output = linear_part + fm_part + dnn_part
        return torch.sigmoid(output.squeeze(1))

# Example usage:
# field_dims = [3, 4, 5]  # Example field dimensions
# model = DeepFM(field_dims, embed_dim=10, mlp_dims=[32, 16], dropout=0.2)
# x = torch.randint(0, 3, (2, len(field_dims)))  # Example input
# output = model(x)
# print(output)

Embedding Layer: 用于将每个特征字段映射到一个密集的向量空间。nn.Embedding用于创建嵌入矩阵。

FM Component:

Linear Term: 使用nn.Embedding来实现线性部分。
Interaction Term: 用于计算特征之间的二阶交互,公式为0.5 * (square_of_sum - sum_of_square)。
DNN Component:

使用多层感知机(MLP)来捕捉高阶特征交互。
nn.Sequential用于堆叠全连接层、激活函数和Dropout。
Forward Method: 将输入数据通过FM组件和DNN组件,最后将结果相加并通过sigmoid激活函数输出。

请根据您的数据集和任务需求调整模型参数和结构。

总结

DeepFM中,FM用来挖掘低阶特征,Deep用来挖掘高阶特征。所谓的低阶特征和高阶特征。

在这里插入图片描述

https://blog.youkuaiyun.com/renzhentinghai/article/details/81204169

代码实现

https://github.com/ChenaniahMe/codes/tree/main/DeepFM

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值