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())}
    
    # 映射用户和物品 ID
    train_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 nn

class 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 = 0
        for 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)。通过训练用户和物品的嵌入向量,模型能够学习到用户和物品之间的复杂关系,从而进行准确的评分预测和个性化推荐。我们还通过绘制损失曲线图,直观地展示了模型训练过程中的损失变化。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CF 641A.Little Artem and Grasshopper(Java实现)

题目分析 蚂蚱会在n个房间中根据既定房间规则向固定方向跳跃固定长度,试问是否能够跳出这个长度(即落点位置在0或n1) 思路分析 输入n就有n个房间,n套规则(固定方向和跳跃距离),蚂蚱到哪个房间就…

css 实现自定义虚线

需求: ui 画的图是虚线,但是虚线很宽正常的border 参数无法做到 进程: 尝试使用 border:1px dashed 发现使用这个虽然是虚线但是很短密密麻麻的 这并不是我们想要的那就只能换方案 第一个最简单,让ui 画一个图然…

Bottleneck层模型介绍

瓶颈设计的思想是引入一个瓶颈层,它由一系列不同大小的滤波器组成,通常是1x1、3x3和1x1的卷积层序列:第一个1x1卷积层:用于减少通道数,即降维,从而降低计算复杂度。 3x3卷积层:用于提取空间特征…

软件测试—接口测试面试题及jmeter面试题

一,接口面试题 1.接口的作用 实现前后端的交互,实现数据的传输 2.什么是接口测试 接口测试就是对系统或组件之间的接口进行测试,主要是校验数据的交换、传递和控制管理过程,以及相互逻辑关系 3.接口测试必要性 1.可以发现很…

使用python+pytest+requests完成自动化接口测试(包括html报告的生成和日志记录以及层级的封装(包括调用Json文件))

一、API的选择 我们进行接口测试需要API文档和系统,我们选择JSONPlaceholder免费API,因为它是一个非常适合进行接口测试、API 测试和学习的工具。它免费、易于使用、无需认证,能够快速帮助开发者模拟常见的接口操作(增、删、改、…

高等数学学习笔记 ☞ 不定积分的积分方法

1. 第一换元积分法 1. 基础概念:形如的过程,称为第一换元积分法。 2. 核心思想:通过对被积函数的观察(把被积函数的形式与积分表的积分公式进行比较),把外部的部分项拿到的内部(求原函数), 然后进行拼凑,…

win32汇编环境,窗口程序中基础列表框的应用举例

;运行效果 ;win32汇编环境,窗口程序中基础列表框的应用举例 ;比如在窗口程序中生成列表框,增加子项,删除某项,取得指定项内容等 ;直接抄进RadAsm可编译运行。重点部分加备注。 ;以下是ASM文件 ;>>>>>>>>>>>…

Jmeter配置服务代理器 Proxy(二)

1.创建脚本记录器 2.配置:Jmeter代理、端口、记录目标等 3.配置谷歌浏览器代理 浏览器配置代理的详细教程可参考:使用whistle代理-CSDN博客 4.启动Jmeter记录器 点击ok后弹出这个界面,生成了证书: 5.给浏览器安装Jmeter代理的证书…

红日-VulnStack靶场一

http://vulnstack.qiyuanxuetang.net/vuln/ 一、环境部署 win7(被攻击机/关火墙) web服务器 1张外网网卡(桥接192.168.1.105),一张内网网卡192.168.52.143/255.255.255.0/192.168.52.2 DNS 192.168.52.138 winser2008 域控服务器 1张…

Chrome谷歌浏览器如何能恢复到之前的旧版本

升级了谷歌最新版不习惯,如何降级版本 未完待续。。 电脑中的Chrome谷歌浏览器升级到了最新版本,但是有种种的不适应,如何能恢复到之前的旧版本呢?我们来看看操作步骤,而且无需卸载重装。 怎么恢复Chrome 之前版本&a…

云上贵州多彩宝荣获仓颉社区先锋应用奖 | 助力数字政务新突破

在信息技术应用创新的浪潮中,仓颉社区吸引了众多企业和开发者的积极参与,已有多个应用成功落地,展现出蓬勃的创新活力。仓颉编程语言精心遴选了在社区建设、应用创新、开源共建、技术布道等方面做出突出贡献的优秀项目应用,并颁发…

LabVIEW实车四轮轮速信号再现系统

开发了一个基于LabVIEW的实车四轮轮速信号再现系统。该系统解决现有电机驱动传感器成本高、重复性差、真实性差和精度低等问题,提供一种高精度、低成本的轮速信号再现解决方案。 项目背景 ABS轮速传感器在现代汽车安全系统中发挥着至关重要的作用。为保证其准确性和…

Java算法 二叉树入门 力扣简单题相同的树 翻转二叉树 判断对称二叉树 递归求二叉树的层数

目录 模版 先序遍历 中序遍历 后序遍历 力扣原题 相同的二叉树 力扣原题 翻转二叉树 遍历树的层数 题目 静态变量 核心逻辑 模版 // 二叉树public static class Node{public int value;public Node left;public Node right;public Node(int v) {valuev;}} 先序遍历 …

P6周:VGG-16算法-Pytorch实现人脸识别

🍨 本文为🔗365天深度学习训练营中的学习记录博客🍖 原作者:K同学啊 我的环境 语言环境:Python 3.8.12 编译器:jupyter notebook 深度学习环境:torch 1.12.0cu113 一、前期准备 1.设置GPU im…

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

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

Web端实时播放RTSP视频流(监控)

一、安装ffmpeg: 1、官网下载FFmpeg: Download FFmpeg 2、点击Windows图标,选第一个:Windows builds from gyan.dev 3、跳转到下载页面: 4、下载后放到合适的位置,不用安装,解压即可: 5、配置path 复制解压后的\bin路径,配置环境变量如图: <

Mongodb相关内容

Mongodb相关内容 1、Windows平台安装2、Linux平台安装3、基本常用命令文档更新删除文档分页查询索引 pymongo操作 客户端下载&#xff1a;https://download.csdn.net/download/guoqingru0311/90273435 1、Windows平台安装 方式一&#xff1a; 方式2&#xff1a; 方式3&#…

SQL2000在win10上安装的方法

安装前最好先关闭防火墙和一些杀毒软件&#xff0c;因为这些软件在安装过程中可能会碰到注册表等一下杀毒软件比较敏感的地带&#xff0c;如果违反杀毒软件的规则会被当做病毒强行终止删除 首相找到C盘下window文件中的sysWOW64文件 鼠标右键&#xff0c;点击属性、安全、高级 …

EAMM: 通过基于音频的情感感知运动模型实现的一次性情感对话人脸合成

EAMM: 通过基于音频的情感感知运动模型实现的一次性情感对话人脸合成 1所有的材料都可以在EAMM: One-Shot Emotional Talking Face via Audio-Based Emotion-Aware Motion Model网站上找到。 摘要 尽管音频驱动的对话人脸生成技术已取得显著进展&#xff0c;但现有方法要么忽…

【华为路由/交换机的ftp文件操作】

华为路由/交换机的ftp文件操作 PC&#xff1a;10.0.1.1 R1&#xff1a;10.0.1.254 / 10.0.2.254 FTP&#xff1a;10.0.2.1 S1&#xff1a;无配置 在桌面创建FTP-Huawei文件夹&#xff0c;里面创建config/test.txt。 点击上图中的“启动”按钮。 然后ftp到server&#xff0c;…