PyTorch 神经协同过滤 (NCF) 推荐系统教程

目录

      • 教程概述
      • 1. 神经协同过滤模型概述
        • NCF 模型的主要组成部分:
      • 2. 数据加载与预处理
      • 3. 定义神经协同过滤模型
      • 4. 训练模型
      • 5. 模型评估
      • 6. 推荐物品
      • 7. 完整示例
      • 8. 总结

在本教程中,我们将使用 PyTorch 实现一个神经协同过滤(Neural Collaborative Filtering,简称 NCF)推荐系统。神经协同过滤是一种基于深度学习的推荐系统模型,通过学习用户和物品的嵌入表示来预测用户对物品的评分,进而提供个性化的推荐。

教程概述

推荐系统通过分析用户历史行为数据,为用户推荐相关的物品或内容。在协同过滤方法中,我们关注于从用户-物品评分矩阵中挖掘出潜在的规律,从而预测用户对未见物品的评分。

在本教程中,我们将:

  1. 介绍神经协同过滤模型的基本原理。
  2. 使用 PyTorch 实现 NCF 模型。
  3. 训练并评估该模型。
  4. 使用训练好的模型为用户推荐物品。
  5. 绘制训练过程中的损失曲线图表,帮助我们更直观地理解模型训练效果。

1. 神经协同过滤模型概述

神经协同过滤 (NCF) 是一种深度学习方法,用于解决传统协同过滤方法在处理用户-物品关系时的限制。其基本思想是通过将用户和物品的特征嵌入到低维向量空间中,然后通过神经网络对这些嵌入向量进行组合和映射,最终预测用户对物品的评分。

NCF 模型的主要组成部分:
  • 嵌入层 (Embedding Layer):通过学习低维的用户和物品嵌入向量,将高维的用户 ID 和物品 ID 映射到低维空间。
  • 多层感知机 (MLP):通过一个多层感知机(全连接层)将用户和物品的嵌入向量拼接起来,进行进一步的特征学习和映射,最后输出预测的评分。

2. 数据加载与预处理

首先,我们需要准备一个评分数据集。该数据集通常包含用户对物品的评分,格式如下:

userId, movieId, rating
1, 102, 4.32
2, 47, 3.85
3, 356, 4.72
...

我们使用 pandas 加载数据并进行预处理,将用户 ID 和物品 ID 昻射到连续的整数索引,并划分训练集和测试集。

import torch
import torch.nn as nn
import torch.optim as optim
import pandas as pd
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt# 1. 加载并准备数据
def load_data(file_path):df = pd.read_csv(file_path)train_data, test_data = train_test_split(df, test_size=0.2, random_state=42)# 创建用户和物品的映射字典user_map = {user: idx for idx, user in enumerate(df['userId'].unique())}movie_map = {movie: idx for idx, movie in enumerate(df['movieId'].unique())}# 映射用户和物品 IDtrain_data['user'] = train_data['userId'].map(user_map)train_data['movie'] = train_data['movieId'].map(movie_map)test_data['user'] = test_data['userId'].map(user_map)test_data['movie'] = test_data['movieId'].map(movie_map)return train_data, test_data, len(user_map), len(movie_map)

3. 定义神经协同过滤模型

接下来,我们将使用 PyTorch 定义神经协同过滤模型。该模型包含两个嵌入层(一个用于用户,另一个用于物品)和一个多层感知机(MLP)来组合用户和物品的嵌入向量,最后输出一个预测评分。

import torch
import torch.nn as nnclass NCF(nn.Module):def __init__(self, num_users, num_movies, embedding_dim=50, hidden_dim=64):super(NCF, self).__init__()# 嵌入层self.user_embedding = nn.Embedding(num_users, embedding_dim)self.movie_embedding = nn.Embedding(num_movies, embedding_dim)# MLP 层self.mlp = nn.Sequential(nn.Linear(embedding_dim * 2, hidden_dim),nn.ReLU(),nn.Linear(hidden_dim, hidden_dim),nn.ReLU(),nn.Linear(hidden_dim, 1))def forward(self, user, movie):# 获取用户和物品的嵌入向量user_emb = self.user_embedding(user)movie_emb = self.movie_embedding(movie)# 拼接用户和物品的嵌入向量x = torch.cat([user_emb, movie_emb], dim=-1)# 通过 MLP 计算预测评分output = self.mlp(x)return output.squeeze()  # 返回标量预测值

4. 训练模型

模型训练包括使用均方误差 (MSE) 损失函数,采用 Adam 优化器进行优化。我们在每个 epoch 后记录损失值,并使用 matplotlib 绘制损失曲线图。

def train_model(model, train_data, num_epochs=10, batch_size=64, learning_rate=0.001):criterion = nn.MSELoss()optimizer = optim.Adam(model.parameters(), lr=learning_rate)train_users = torch.tensor(train_data['user'].values, dtype=torch.long)train_movies = torch.tensor(train_data['movie'].values, dtype=torch.long)train_ratings = torch.tensor(train_data['rating'].values, dtype=torch.float32)model.train()# 用于记录每个epoch的损失epoch_losses = []for epoch in range(num_epochs):total_loss = 0for i in range(0, len(train_users), batch_size):user_batch = train_users[i:i+batch_size]movie_batch = train_movies[i:i+batch_size]rating_batch = train_ratings[i:i+batch_size]# 前向传播optimizer.zero_grad()predictions = model(user_batch, movie_batch)# 计算损失loss = criterion(predictions, rating_batch)# 反向传播loss.backward()optimizer.step()total_loss += loss.item()avg_loss = total_loss / len(train_users)epoch_losses.append(avg_loss)  # 记录损失值print(f"Epoch {epoch+1}/{num_epochs}, Loss: {avg_loss}")return epoch_losses

5. 模型评估

训练完成后,我们可以使用测试集来评估模型的表现,计算其均方误差(MSE)来衡量预测的准确性。

def evaluate_model(model, test_data):test_users = torch.tensor(test_data['user'].values, dtype=torch.long)test_movies = torch.tensor(test_data['movie'].values, dtype=torch.long)test_ratings = torch.tensor(test_data['rating'].values, dtype=torch.float32)model.eval()with torch.no_grad():predictions = model(test_users, test_movies)mse = nn.MSELoss()(predictions, test_ratings)print(f'Mean Squared Error on Test Set: {mse.item()}')

6. 推荐物品

一旦模型训练完成,我们可以使用它为用户推荐物品。模型将根据用户的历史评分为其推荐最相关的电影。

def recommend_for_user(model, user_id, num_movies, movie_map, top_n=10):user_tensor = torch.tensor([user_id], dtype=torch.long)all_movies = torch.tensor(range(num_movies), dtype=torch.long)model.eval()with torch.no_grad():scores = model(user_tensor.repeat(num_movies), all_movies)# 获取前 N 个物品recommended_movie_ids = scores.argsort(descending=True)[:top_n]recommended_movies = [list(movie_map.keys())[i.item()] for i in recommended_movie_ids]return recommended_movies

7. 完整示例

最后,将所有组件组合在一起,完成模型的训练和推荐过程:

if __name__ == "__main__":# 1. 加载数据train_data, test_data, num_users, num_movies = load_data('ratings.csv')# 2. 创建和训练模型model = NCF(num_users, num_movies)num_epochs = 10  # 训练的 epoch 数epoch_losses = train_model(model, train_data, num_epochs=num_epochs, batch_size=64, learning_rate=0.001)# 3. 测试模型evaluate_model(model, test_data)# 4. 推荐:为用户 1 推荐物品recommended_movies = recommend_for_user(model, 1, num_movies, dict(enumerate(range(num_movies))))print("Recommended movies for user 1:", recommended_movies)# 5. 绘制损失图表plt.plot(range(1, num_epochs + 1), epoch_losses, marker='o', color='b')plt.title('Training Loss Over Epochs')plt.xlabel('Epoch')plt.ylabel('Loss')plt.grid(True)plt.show()

8. 总结

在本教程中,我们使用 PyTorch 实现了一个基于神经网络的协同过滤推荐系统(NCF)。通过训练用户和物品的嵌入向量,模型能够学习到用户和物品之间的复杂关系,从而进行准确的评分预测和个性化推荐。我们还通过绘制损失曲线图,直观地展示了模型训练过程中的损失变化。

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

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

相关文章

03.选择排序

一、题目思路 选择排序是一种简单直观的排序算法。它的工作原理是:首先在未排序序列中找到最小(或最大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(或最大&#xff…

大模型学习笔记 - 第一期 - Milvus向量数据库

大模型学习笔记 - 向量数据库 目录 大模型学习笔记 - 向量数据库传统文字检索(无嵌入)面临的困境1. 用户和商户表述差异2. 不同语种的表述差异3. 不同背景下的音译表述差异 向量检索向量化服务 参考 传统文字检索(无嵌入)面临的困境 1. 用户和商户表述差异 ​ 如果商户维护了…

详细图文解读Transformer模型:《Attention is All You Need》完整版

目录 前言1、Transformer模型《Attention is All You Need》总结2、Transformer整体结构2.1、工作流程 3、Transformer的输入4、Self-Attention(自注意力机制)4.1、Self-Attention 结构4.2、Q, K, V计算4.3、Self-Attention 的输出4.4、Multi-Head Atten…

Hadoop•用Web UI查看Hadoop状态词频统计

听说这里是目录哦 通过Web UI查看Hadoop运行状态🐇一、关闭防火墙二、在物理计算机添加集群的IP映射三、启动集群四、进入HDFS的Web UI 词频统计🦩1、准备文本数据2、在HDFS创建目录3、上传文件4、查看文件是否上传成功5、运行MapReduce程序6、查看MapRe…

vue编写一个可拖动的模块,并可以和任何其他组件组合使用

实现思路&#xff1a; 使用 Vue 的自定义指令&#xff08;directive&#xff09;来处理拖动逻辑。在 mounted 钩子中添加鼠标事件监听器&#xff0c;以实现拖动功能。在 unmounted 钩子中移除鼠标事件监听器&#xff0c;防止内存泄漏。 代码示例&#xff1a; <template&g…

Ubuntu、Windows系统网络设置(ping通内外网)

一、 虚拟机VMware和Ubuntu系统的网络配置说明 1、虚拟机的网络适配器的模式有三种&#xff1a; 桥接模式NAT模式主机模式 2、虚拟机VMware的网卡配置(如何进行配置界面(虚拟机->设置)) 注意&#xff1a; 1、以上桥接模式(ubuntu有独立IP)、NAT模式(没有独立IP)都可以联…

将IDLE里面python环境pyqt5配置的vscode

首先安装pyqt5全套&#xff1a;pip install pyqt5-tools 打开Vscode&#xff1a; 安装第三方扩展&#xff1a;PYQT Integration 成功配置designer.exe的路径【个人安装pyqt5的执行路径】&#xff0c;便可直接打开UI文件&#xff0c;进行编辑。 配置pyuic,如果下图填写方法使用…

大模型之三十三- 开源Melo 语音合成

大模型之三十三- 开源Melo 语音合成 文本到语音(TTS)系统从基于基础音素的模型演变成复杂的端到端神经方法,这种方法可以直接将文本转换为语音。这一变革得益于深度学习的进步和计算能力的提升,已经在语音的自然度、韵律控制和跨语言能力方面取得了重大进展 。现代TTS系统…

C# OpenCV机器视觉:特征匹配 “灵魂伴侣”

在一个阳光仿佛被施了魔法&#xff0c;欢快得直蹦跶的早晨&#xff0c;阿强像个即将踏上神秘寻宝之旅的探险家&#xff0c;一屁股墩在实验室那张堆满各种奇奇怪怪小玩意儿的桌前。桌上&#xff0c;零件、线路、半成品设备乱成一团&#xff0c;唯有他那宝贝电脑屏幕散发着清冷又…

【SSH端口转发:实现安全的远程端口映射】

SSH端口转发&#xff1a;实现安全的远程端口映射 在网络应用开发和运维过程中&#xff0c;我们经常需要进行端口转发来实现各种网络访问需求。今天我要分享一个使用SSH进行端口转发的实用脚本&#xff0c;并详细讲解其工作原理。 脚本内容 免密 ssh-copy-id -p 20080 rootxx…

GPT-4o背后的语音技术

GPT-4o背后的语音技术 GPT-4o是一个any2any的多模态模型,能够接受文本、音频、图像、视频等多模态输入,也能够生成包含文本、语音、图像和视频等混合内容的多模态输出。本文主要谈语音多模态的实现,并分享一些对于语音研究未来发展的看法。 GPT-4o (“o” 代表 “omni”) …

简述mysql 主从复制原理及其工作过程,配置一主两从并验证

第一种基于binlog的主从同步 首先对主库进行配置&#xff1a; [rootopenEuler-1 ~]# vim /etc/my.cnf 启动服务 [rootopenEuler-1 ~]# systemctl enable --now mysqld 主库的配置 从库的配置 第一个从库 [rootopenEuler-1 ~]# vim /etc/my.cnf [rootopenEuler-1 ~]# sys…

Spring自定义BeanPostProcessor实现bean的代理Java动态代理知识

上文&#xff1a;https://blog.csdn.net/qq_26437925/article/details/145241149 中大致了解了spring aop的代理的实现&#xff0c;其实就是有个BeanPostProcessor代理了bean对象。顺便复习下java代理相关知识 目录 自定义BeanPostProcessor实现aopJava动态代理知识动态代理的几…

医院挂号就诊系统设计与实现(代码+数据库+LW)

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装医院挂号就诊系统软件来发挥其高效地信息处理的作用&#…

【GORM】初探gorm模型,字段标签与go案例

GORM是什么&#xff1f; GORM 是一个Go 语言 ORM&#xff08;对象关系映射&#xff09;库&#xff0c;它让我们可以使用结构体来操作数据库&#xff0c;而无需编写SQL 语句 GORM 模型与字段标签详解 在 GORM 中&#xff0c;模型是数据库表的抽象表示&#xff0c;字段标签&am…

R 语言科研绘图第 20 期 --- 箱线图-配对

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

YOLOv10-1.1部分代码阅读笔记-dataset.py

dataset.py ultralytics\data\dataset.py 目录 dataset.py 1.所需的库和模块 2.class YOLODataset(BaseDataset): 3.class ClassificationDataset(torchvision.datasets.ImageFolder): 4.def load_dataset_cache_file(path): 5.def save_dataset_cache_file(prefix,…

【物联网】ARM核介绍

文章目录 一、芯片产业链1. CPU核(1)ARM(2)MIPS(3)PowerPc(4)Intel(5)RISC-V 2. SOC芯片(1)主流厂家(2)产品解决方案 3. 产品 二、ARM核发展1. 不同架构的特点分析(1)VFP(2)Jazelle(3)Thumb(4)TrustZone(5)SIMD(6)NEON 三、ARM核(ARMv7)工作模式1. 权限级别(privilege level)2.…

uniApp开通uniPush1.0个推,SpringBoot集成uniPush1.0个推

uniApp开通unipush1.0个推&#xff0c;SpringBoot程序集成 一、APP开通unipush1.0个推(商户App源码仅支持1.0个推) 1.app模块配置开通推送 2.应用开通推送 3.开通后点击消息推送菜单会看到如下页面 完成以上步骤后 此时android 仅支持在线推送。 4.配置各厂商离线推送 暂未…

JS宏进阶: 工厂函数与构造函数

一、构造函数 在JavaScript中&#xff0c;构造函数是一种用于创建和初始化对象的特殊函数。构造函数的名字通常以大写字母开头&#xff0c;以区分于普通函数。通过new关键字调用构造函数&#xff0c;可以创建一个新的实例对象&#xff0c;并自动执行构造函数内部的代码来初始化…