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

embedded/2025/1/21 3:29:07/

目录

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

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

教程概述

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

在本教程中,我们将:

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

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

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

NCF__18">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 昻射到连续的整数索引,并划分训练集和测试集。

python">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)来组合用户和物品的嵌入向量,最后输出一个预测评分。

python">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 绘制损失曲线图。

python">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)来衡量预测的准确性。

python">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. 推荐物品

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

python">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. 完整示例

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

python">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.ppmy.cn/embedded/155661.html

相关文章

NavVis手持激光扫描帮助舍弗勒快速打造“数字孪生”工厂-沪敖3D

在全球拥有近100家工厂的舍弗勒,从2016年开启数字化运营进程,而当前制造、库存、劳动力和物流的数字化,已无法支持其进一步简化工作流程,亟需数字化物理制造环境,打造“数字孪生”工厂。 NavVis为其提供NavVis VLX 3…

计算机网络 (45)动态主机配置协议DHCP

前言 计算机网络中的动态主机配置协议(DHCP,Dynamic Host Configuration Protocol)是一种网络管理协议,主要用于自动分配IP地址和其他网络配置参数给连接到网络的设备。 一、基本概念 定义:DHCP是一种网络协议&#xf…

CSS 网络安全字体

适用于 HTML 和 CSS 的最佳 Web 安全字体 下面列出了适用于 HTM L和 CSS 的最佳 Web 安全字体: Arial (sans-serif)Verdana (sans-serif)Helvetica (sans-serif)Tahoma (sans-serif)Trebuchet MS (sans-serif)Times New Roman (serif)Georgia (serif)Garamond (se…

windows下安装并使用node.js

一、下载Node.js 选择对应你系统的Node.js版本下载 Node.js官网下载地址 Node.js中文网下载地址??? 这里我选择的是Windows64位系统的Node.js20.18.0(LTS长期支持版本)版本的.msi安装包程序 官网下载: 中文网下载: 二、安…

Nginx在Linux中的最小化安装方式

1. 安装依赖 需要安装的东西: wget​,方便我们下载Nginx的包。如果是在Windows下载,然后使用SFTP上传到服务器中,那么可以不安装这个软件包。gcc g​,Nginx是使用C/C开发的服务器,等一下安装会用到其中的…

移动端H5缓存问题

移动端页面缓存问题是指页面的静态资源(如图片、JS 和 CSS 文件)在浏览器中被缓存后,用户在下次访问时可以直接从本地获取缓存数据,而不需要每次都从服务器重新获取,不过这样可能会导致页面不能正确地更新或者加载最新…

《贪心算法:原理剖析与典型例题精解》

必刷的贪心算法典型例题! 算法竞赛(蓝桥杯)贪心算法1——数塔问题-CSDN博客 算法竞赛(蓝桥杯)贪心算法2——需要安排几位师傅加工零件-CSDN博客 算法(蓝桥杯)贪心算法3——二维数组排序与贪心算…

软考中级复习篇章:数据结构部分的复习

软考中级快速通过篇章:数据结构部分的复习 一、引言 在软考中级的备考过程中,数据结构是极为重要的一个部分。它不仅是计算机科学的基础,也是软考中考查的重点知识领域。扎实掌握数据结构相关内容,对于顺利通过软考中级考试起着…