Neural Collaborative Filtering论文笔记

news2024/10/6 18:22:19

ABSTRACT

 

1f3b8f7f157a43ab8e4d65efcdc56bb6.png

        深度神经网络在语音识别、计算机视觉和自然语言处理等方面取得了巨大的成果,但是对于推荐系统尚且缺少。虽然即使有用深度学习作为推荐,但是都是对建模起辅助作用。当涉及到用户和项目之间的交互,都会选择流行的矩阵分解(MF),因此基于上面的情况这篇论文的作者提出了一个基于协同过滤的神经网络通用框架——NCF,其中选择使用MLP来学习用户-项目的交互函数。

1. INTRODUCTION

        个性化推荐主要使用矩阵因子分解,通过用户过去与项目的互动来建模从而得出用户对项目的偏好,同时对于后续的研究也基本都是致力于增强MF,但是提升效果并不是很大。基于此论文做出的主要三点贡献

821e58b95c3b4e8ea03252a9b799efae.jpeg

         (1)提出了一种神经网络结构来建模用户和项目的潜在特征,并设计了一个基于神经网络的协同过滤的通用框架NCF。

        (2)表明,MF可以被解释为NCF的一个专门化,并利用一个多层感知器来赋予NCF模型一个高水平的非线性。

        (3)在两个真实世界的数据集上进行了广泛的实验,证明NCF方法的有效性和对协作过滤的深度学习的前景。

2.PRELIMINARIES

        主要讲述了隐式反馈进行协同过滤的解决方案,简要概括MF

2.1 Learning from Implicit Data

        定义Y是一个M*N的用户-项目交互矩阵,矩阵中的元素根据用户和项目之间是否存在交互关系来定义,即:

a68d18fb65b944e499db7e1f0fb4b653.jpeg

        如下图所示:

c6852747c2cc41c1819c3411338a1149.jpeg

         注意:这里用户i对应项目i的1并不一定是喜欢,同时用户i对应项目i的0不一定是不喜欢,有可能是因为用户完全还不知道有这个项目,从而导致数据的缺失形成的情况,这也是隐式数据的一个特点。

2.2 Matrix Factorization

       将每个用户和物品和一个潜在特征的实值向量联系起来,用gif.latex?p_ugif.latex?q_i分别表示用户和项目,通过内积的方法来预测用户对该项目的爱好程度:

11544a84870946fb87be2ea9b6b07fd3.jpeg

        这里通过Jaccard作为两两用户相似性的计算方法:

gif.latex?S_ij%3D%5Cfrac%7Bp_i%20%5Ccup%20p_j%7D%7Bp_i%5Ccap%20p_j%7D

        这样通过简单的计算内积计算得到复杂的用户与项目直接的关系,可能会使MF存在一定的局限性,同时也很容易导致结果过拟合。

 3. NCF model

 3.1 模型架构图

cd60f6a5bc494d52bfba7be1e15e9f03.jpeg

3.2 模型架构公式

        (1)NCF预测模型

9ac6ca20be4f4e7cbb50b8a65f9ce9e0.png

        (2)上面公式中f()函数定义的多层神经网络,它表示如下:

2a881a2b9e024a509c5070f3a9014156.jpeg

3.3  网络层描述

3.3.1 输入层

         输入的是过了一层one-hot用户矩阵向量和项目矩阵向量

3.3.2 embedding层

         因为经过one-hot出来的用户矩阵和项目矩阵是稀疏矩阵,这里经过embedding层将稀疏矩阵映射成稠密矩阵

3.3.3 Neutral CF层

         网络模型架构这里是经过多层的全连接进行映射,不断的进行维度变化,使得来逼近训练数据的真实概率分布。

      (这里也有点困惑,后面的由Neutral CF的模型架构与这又是否有区别,我的认识是这里就是多层的下面的模型架构堆叠,当然这只是我自己的理解。)

3.3.4 输出层

         通过sigmoid函数将结果映射到输出的维度,得到最后的预测结果。

3.4 损失函数

      (1)一般常用的损失函数是平方损失回归:81da38f2000740edafe6fcc8fb2d5db0.jpg

       (2)论文中提出来一个新关注于隐式数据的损失函数

4f5e68e0fc5e49f3bdb1577bdd3008c0.jpg

3.5 Neutral CF

3.5.1 模型架构图

f69dafe9caa14ea9aa645ee75d045e0b.jpg

3.5.2 GMF

      (1)模型架构在上面就是将用户和项目矩阵做内积,然后通过一层激活函数,进行维度映射。(激活函数选择为sigmoid函数)

      (2)模型公式

ba352b3d88dc48ef9ee270f6c6c63754.jpg

3.5.3 MLP

      (1)和我们平常理解的MLP模型相同,这里主要是对用户和项目做交互,更换了以前的MF的简单不足,当然这里的模型架构也是在上面图中,用户和项目经过多层MLP进行不同维度的全连接,网络层级为塔型,逐级减半,提取更多的隐式特征。(选择的激活函数是ReLU)

      (2)模型公式(n层MLP)

710ff0001bea47ffae510b3a6874e4a9.jpg

3.5.4 GMF和n层MLP的fusion

      (1) 一种简单的方法

b06c80090b504d6ca79a24d493bcd606.jpg

       (2)分开训练,最后连接隐藏层h。

770d91e2cc86401baf67db30168969a5.jpg

 3.4 Pre-training

      将GMF和MLP单独分开训练,然后加载预训练好的权重,通过给出不同的权重值进行组合,从而实现Pre-training(个人理解,不是很清楚)

cd3a56518a804bfe8d92d5bd00f18578.jpg

4.具体案例代码

4.1 NCF实例代码模型架构

        此代码来自Datawhale推荐系统论文组队学习task1中的代码实现,以下主要展示模型的架构。

class NCF(nn.Module):
    def __init__(self,
                # 经过embedding层之后的维度
                embedding_dim = 16,
                # 映射层
                vocab_map = None,
                # 损失函数
                loss_fun = 'torch.nn.BCELoss()'):
        super(NCF, self).__init__()
        
        # 定义各个层的维度变化
        # embedding层
        self.embedding_dim = embedding_dim
        # 映射层
        self.vocab_map = vocab_map
        # 损失函数
        self.loss_fun = eval(loss_fun) # self.loss_fun  = torch.nn.BCELoss()
        
        # 用户矩阵过embedding层
        self.user_emb_layer = nn.Embedding(self.vocab_map['user_id'],
                                          self.embedding_dim)
        # 项目矩阵过embedding层
        self.item_emb_layer = nn.Embedding(self.vocab_map['item_id'],
                                          self.embedding_dim)
        # MLP层
        self.mlp = nn.Sequential(
            nn.Linear(2*self.embedding_dim,self.embedding_dim),
            nn.ReLU(inplace=True),
            nn.BatchNorm1d(self.embedding_dim),
            nn.Linear(self.embedding_dim,1),
            nn.Sigmoid()
        )
        
    def forward(self,data):
        # embedding层
        user_emb = self.user_emb_layer(data['user_id']) # [batch,emb]
        item_emb = self.item_emb_layer(data['item_id']) # [batch,emb]
        
        # 进行全连接
        mlp_input = torch.cat([user_emb, item_emb],axis=-1)
        # 过n层MLP
        y_pred = self.mlp(mlp_input)
        if 'label' in data.keys():
            loss = self.loss_fun(y_pred.squeeze(),data['label'])
            output_dict = {'pred':y_pred,'loss':loss}
        else:
            output_dict = {'pred':y_pred}
        return output_dict

4.2 Neural MF实例代码模型架构

        此代码经过自己修改上面的模型架构得到的Neural MF模型,当然各个网络层的映射与上面原论文中的参数设置并不相同。

class NeuralMF(nn.Module):
    def __init__(self,
                embedding_dim = 32,
                vocab_map = None,
                loss_fun = 'torch.nn.MSELoss()'):
        super(NeuralMF, self).__init__()
        self.dim_mlp = [64, 256, 128, 64, 32]
        self.embedding_dim = embedding_dim
        self.vocab_map = vocab_map
        self.loss_fun = eval(loss_fun) # self.loss_fun  = torch.nn.BCELoss()
        
        # gmf对用户id和项目id进行编码(输出为16)
        self.user_emb_layer_gmf = nn.Embedding(self.vocab_map['uid'], 32)
        self.item_emb_layer_gmf = nn.Embedding(self.vocab_map['iid'], 32)
        
        # mlp对用户id和项目id进行编码(输出为16)
        self.user_emb_layer_mlp = nn.Embedding(self.vocab_map['uid'], 32)
        
        self.item_emb_layer_mlp = nn.Embedding(self.vocab_map['iid'], 32)
        
        # 过一个线性+激活函数+归一化+(这里线性先不进行)
        self.fc_layers = torch.nn.ModuleList()
        for idx, (in_size, out_size) in enumerate(zip(self.dim_mlp[:-1], self.dim_mlp[1:])):
            self.fc_layers.append(torch.nn.Linear(in_size, out_size))
        
        # 最后过一个线性
        self.affine_output = nn.Linear(2 * 32, 1)
        self.logistic = torch.nn.Sigmoid()
        
    def forward(self,data):
        # gmf_vector进行矩阵相乘
        user_emb_gmf = self.user_emb_layer_gmf(data['uid']) # [batch,emb]
        item_emb_gmf = self.item_emb_layer_gmf(data['iid']) # [batch,emb]
        mf_vector = torch.mul(user_emb_gmf, item_emb_gmf)
        
        # 进行连接并过一层mlp
        user_emb_mlp = self.user_emb_layer_mlp(data['uid']) # [batch,emb]
        item_emb_mlp = self.item_emb_layer_mlp(data['iid']) # [batch,emb]
        mlp_vector = torch.cat([user_emb_mlp, item_emb_mlp], dim=-1) 
        for idx, _ in enumerate(range(len(self.fc_layers))):
            mlp_vector = self.fc_layers[idx](mlp_vector)
            mlp_vector = torch.nn.Dropout(0.8)(mlp_vector)
            mlp_vector = torch.nn.ReLU()(mlp_vector)
        
        # 将上面gmf和mlp进行组合
        vector = torch.cat([mlp_vector, mf_vector], dim=-1)
        y_pred = self.affine_output(vector)

        if 'label' in data.keys():
            loss = self.loss_fun(y_pred.squeeze(),data['label'])
            output_dict = {'pred':y_pred,'loss':loss}
        else:
            output_dict = {'pred':y_pred}
        return output_dict

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/11639.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

三、react组件的生命周期

目标 灵活掌握react组件的生命周期以及组件的活动过程。 能够灵活使用react的生命周期 知识点 react的类组件的生命周期分为三个阶段 实例期存在期销毁期 实例期在组件第一次被实例化的时候触发一次,在这个过程中会执行的生命周期函数如下: construct…

2、CKA-简单搭建K8s集群

基础环境: 主机IP资源系统主机名192.168.100.1104核8GCentos8K8s-master192.168.100.1204核8GCentos8K8s-node1192.168.100.1304核8GCentos8K8s-node2 推荐一个小网站:https://labs.play-with-k8s.com/ 其他的废话不多说,直接部署起来先~~ 部…

[附源码]Python计算机毕业设计 校园疫情防控系统

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

校企合作,人才共育|湖南工程学院第二期万应低代码实训营圆满收官

2022年11月11日,湖南工程学院第二期万应低代码实训营圆满收官,来自湖南工程学院计算机与通信学院(人工智能产业学院)的47位同学经过为期9天、共计51课时的培训课程,用出色的交付成果顺利结业。湖南工程学院计算机与通信…

最简单的git图解(最基本命令)

git clone: 这个命令用于将远程代码仓库克隆到本地,这是对任何项目进行开发前的第一步。 比如你本地本来并没有某个项目的代码仓库,此时随便找一个文件目录并进入cmd命令窗口,执行命令git clone [remote address],[remote addres…

春节静态HTML网页作业模板 传统节日文化网站设计作品 静态学生网页设计作业简单网页制作

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

python计算长方形面积 青少年编程电子学会python编程等级考试一级真题解析2022年6月

目录 python计算长方形面积 一、题目要求 1、编程实现 2、输入输出

TCP粘包和拆包

TCP粘包和拆包 (1)TCP是面向连接的,面向流的,提供可靠性服务。收发两端(客户端和服务端)都要有一一成对的socket,因此,发送端为了将多个发给接收端的包,更有效的发给对方…

【前端】Vue+Element UI案例:通用后台管理系统-代码总结

文章目录前言项目文件目录apimockServehome.jspermission.jsindex.jsmock.jsuser.jsassertcomponentsCommonAside.vueCommonHeader.vueCommonTags.vuedataechartsDataorder.jsuser.jsvideo.jsmockDatatableData.jsuserData.jsvideoData.jsCountData.jsMenuData.jsTableData.jsT…

389. 找不同(简单不一定知道)

问题描述: 给定两个字符串 s 和 t ,它们只包含小写字母。 字符串 t 由字符串 s 随机重排,然后在随机位置添加一个字母。 请找出在 t 中被添加的字母。 示例 : 示例 1: 输入:s "abcd", t …

大学生抗疫逆行者网页作业 感动人物HTML网页代码成品 最美逆行者dreamweaver网页模板 致敬疫情感动人物网页设计制作

🎉精彩专栏推荐 💭文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 💂 作者主页: 【主页——🚀获取更多优质源码】 🎓 web前端期末大作业: 【📚毕设项目精品实战案例 (10…

多维时序 | MATLAB实现ELM极限学习机多维时序预测(股票价格预测)

多维时序 | MATLAB实现ELM极限学习机多维时序预测(股票价格预测) 目录 多维时序 | MATLAB实现ELM极限学习机多维时序预测(股票价格预测)效果一览基本介绍程序设计结果输出参考资料效果一览 基本介绍

MySQL-僵持锁

前言 一个僵持锁(deadlocks)是指锁处于僵持的状态,持有锁的事务既得不到期望的资源,也不愿意释放其他事务需要的资源,也就是,多个锁相互之间都持有其他锁所需的资源,所有的事务都在等待各自需要…

防止重复下单(redis+数据库唯一索引requestId实现幂等)

文章目录为什么会重复下单如何防止重复下单利用数据库实现幂等利用Redis防重为什么会重复下单 为什么会重复下单,对于订单服务而言,就是接到了多个下单的请求,原因可能有很多,最常见的是这两种: 用户重复提交网络原因…

使用easygui制作app

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 使用easygui制作app [太阳]选择题 对于以下python代码表述错误的一项是? import easygui easygui.msgbox("我是msgbox","msgbox标题") choices["A",…

学生网页设计作业源码(HTML+CSS)——海贼王6页代码质量好

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置,有div的样式格局,这个实例比较全面,有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 ⚽精彩专栏推荐&#x1…

【Pytorch with fastai】第 13 章 :卷积神经网络

🔎大家好,我是Sonhhxg_柒,希望你看完之后,能对你有所帮助,不足请指正!共同学习交流🔎 📝个人主页-Sonhhxg_柒的博客_CSDN博客 📃 🎁欢迎各位→点赞…

数据结构之线性表的顺序存储结构

配套环境 clion + g++ 顺序存储的定义 线性表的顺序存储结构,指的是用一段地址连续的存储单元一次存储线性表中的数据元素 设计思路 使用一维数组来实现顺序存储结构 存储空间:T* m_array 当前长度:int m_length 顺序存储结构的元素获取操作 判断目标位置是否合法 如…

Backblaze 2022 Q3 硬盘故障质量报告解读

在9月份,我们更新了Backblaze 2022上半年的中期质量报告解读(Backblaze2022中期SSD故障质量报告解读),基于报告中的分析数据,Backblaze也向外界传递作证了一个信息:固态硬盘SSD的长期可靠性比机械硬盘HDD要…

听说某宝抢购脚本大家都会了?那就在来个某东茅台抢购脚本吧。

前言 某宝脚本一搜能搜一大堆,就是不知道具体有没有用,但是这款某东的代码于11-17还是可用的,大家拿去白嫖吧! 需要用到的一些工具 Python版本:3.7.8相关模块:DecryptLogin模块;argparse模块&am…