基于用户的协同过滤Movielens电影推荐系统简单实例

article/2025/10/12 16:22:54

基于用户的协同过滤Movielens电影推荐系统简单实例

一、Movielens数据集

1. MovieLens数据集的下载(Download)

1) 从网站下载数据
链接: https://grouplens.org/datasets/movielens/.
有好几种版本,对应不同数据量,本文所用的数据为1M的数据。
MovieLens 1M Dataset
在这里插入图片描述

2、MovieLens数据集简介

MovieLens数据集包含多个用户对多部电影的评级数据,也包括电影元数据信息和用户属性信息。

这个数据集经常用来做推荐系统,机器学习算法的测试数据集。尤其在推荐系统领域,很多著名论文都是基于这个数据集的。(PS: 它是某次具有历史意义的推荐系统竞赛所用的数据集)。

1m的数据解压后,可以看到四个主要的csv文件,分别是links.csv,movies.csv,ratings.csv,tags.csv。links介绍了该数据集中的movieId和imdb、tmdb中电影的对应关系。tags是用户的打标签数据。本文的介绍主要基于ratings.csv movies.csv

ratings数据
文件里面的内容包含了每一个用户对于每一部电影的评分。数据格式如下:
userId, movieId, rating, timestamp
userId: 每个用户的id
movieId: 每部电影的id
rating: 用户评分,是5星制,按半颗星的规模递增(0.5 stars - 5 stars)
timestamp: 自1970年1月1日零点后到用户提交评价的时间的秒数
数据排序的顺序按照userId,movieId排列的。

movies数据
movieId:每部电影的id
title:电影的标题
genres:电影的类别

二、 协同过滤算法原理

协同过滤推荐算法是诞生最早,并且较为著名的推荐算法。主要的功能是预测和推荐。算法通过对用户历史行为数据的挖掘发现用户的偏好,基于不同的偏好对用户进行群组划分并推荐品味相似的商品。协同过滤推荐算法分为两类,分别是基于用户的协同过滤算法(user-based collaboratIve filtering),和基于物品的协同过滤算法(item-based collaborative filtering)。简单的说就是:人以类聚,物以群分。下面我们将分别说明这两类推荐算法的原理和实现方法。

基于用户的协同过滤(UserCF)

基于用户的协同过滤就是给用户推荐“和他兴趣相投的其他用户”喜欢的物品。
通过用户的历史行为数据发现用户喜欢的物品,并对这些偏好进行度量和评分,然后根据不同用户的评分或者偏好程度来评测用户之间的相似性,对相同骗号的用户进行物品推荐。
算法总结
一、找到和目标用户兴趣相似的用户集合——计算两个用户的兴趣相似度
二、找到这个集合中的用户喜欢的,且目标用户没有听说过的物品推荐给目标用户——找出物品推荐

1.计算用户的相似度

计算用户相似度的方法:这里我采用的是余弦相似度
下面我拿这个图举例
在这里插入图片描述

计算用户的相似度,例如A,B为
在这里插入图片描述

同理

在这里插入图片描述

(1) 算法复杂度优化

背景分析:上面计算存在一个问题-需要计算每一个用户的相似度,在实际生产环境中,很多用户之间并没有交集,也就是并没有对同一样物品产生过行为,所以很多情况分子为0,这样的稀疏数据就没有计算的必要。

优化思路:首先计算出|N(u) 并 N(v)| != 0 的用户对(u,v),然后对这种情况计算分母以得到两个用户的相似度

实施步骤
(1)建立物品到用户的倒查表T,表示该物品被哪些用户产生过行为;
(2)根据倒查表T,建立用户相似度矩阵W:在T中,对于每一个物品i,设其对应的用户为j,k,在W中,更新相应的元素值,w[j][k]=w[j][k]+1,w[k][j]=w[k][j]+1,以此类推,扫描完倒查表T中的所有物品后,就可以得到最终的用户相似度矩阵W,这里的W是余弦相似度中的分子部分,然后将W除以分母可以得到最终的用户兴趣相似度。
在这里插入图片描述

(2)惩罚热门商品

对一件冷门物品有过相同行为比对一件热门物品有过相同行为更能说明两个用户兴趣相似。

如果两个用户都买过《新华字典》,这并不能说明他们兴趣相投,因为绝大多数中国人都买过《新华字典》。
但是如果两个用户都买过《机器学习实战》,那可以认为他们兴趣比较相似,因为只有研究机器学习的人才会购买这本书。
在这里插入图片描述

该公式通过1/log1+|N(i)|惩罚了用户u和用户v共同兴趣列表中的热门物品i,实验表明,改进的UserCF算法的各预测指标都有所提升。

三、案例实现思路

首先使用训练数据得到用户的偏好矩阵和物品的特征信息矩阵,然后计算用户对未进行评分电影的偏好分,选取前K个推荐用户。

1.MovieLens数据准备与处理

创建一个UserCFRec类 添加如下内容:

class UserCFRec:def __init__(self,datafile):self.datafile = datafileself.data = self.loadData()self.trainData,self.testData = self.splitData(3,47)  # 训练集与数据集self.users_sim = self.UserSimilarityBest()

加载评分数据到data

  def loadData(self):print("加载数据...")data=[]for line in open(self.datafile):userid,itemid,record,_ = line.split("::")data.append((userid,itemid,int(record)))return data

拆分数据集为训练集和测试集
k: 参数
seed: 生成随机数的种子
M: 随机数上限

 def splitData(self,k,seed,M=8):print("训练数据集与测试数据集切分...")train,test = {},{}random.seed(seed)for user,item,record in self.data:if random.randint(0,M) == k:test.setdefault(user,{})test[user][item] = recordelse:train.setdefault(user,{})train[user][item] = recordreturn train,test

2.使用基于物品的系统过滤算法构建模型

计算用户之间的相似度,采用惩罚热门商品和优化算法复杂度的算法

 def UserSimilarityBest(self):print("开始计算用户之间的相似度 ...")if os.path.exists("./data/user_sim.json"):print("用户相似度从文件加载 ...")userSim = json.load(open("./data/user_sim.json","r"))else:# 得到每个item被哪些user评价过item_users = dict()for u, items in self.trainData.items():for i in items.keys():item_users.setdefault(i,set())if self.trainData[u][i] > 0:item_users[i].add(u)# 构建倒排表count = dict()user_item_count = dict()for i, users in item_users.items():for u in users:user_item_count.setdefault(u,0)user_item_count[u] += 1count.setdefault(u,{})for v in users:count[u].setdefault(v, 0)if u == v:continuecount[u][v] += 1 / math.log(1+len(users))# 构建相似度矩阵userSim = dict()for u, related_users in count.items():userSim.setdefault(u,{})for v, cuv in related_users.items():if u==v:continueuserSim[u].setdefault(v, 0.0)userSim[u][v] = cuv / math.sqrt(user_item_count[u] * user_item_count[v])json.dump(userSim, open('./data/user_sim.json', 'w'))return userSim

3.模型训练

为用户user进行物品推荐
user: 为用户user进行推荐
k: 选取k个近邻用户
nitems: 取nitems个物品

    def recommend(self, user, k=8, nitems=40):result = dict()have_score_items = self.trainData.get(user, {})for v, wuv in sorted(self.users_sim[user].items(), key=lambda x: x[1], reverse=True)[0:k]:for i, rvi in self.trainData[v].items():if i in have_score_items:continueresult.setdefault(i, 0)result[i] += wuv * rvireturn dict(sorted(result.items(), key=lambda x: x[1], reverse=True)[0:nitems])

4.效果评估

计算准确率
k: 近邻用户数
nitems: 推荐的item个数

    def precision(self, k=8, nitems=10):print("开始计算准确率 ...")hit = 0precision = 0for user in self.trainData.keys():tu = self.testData.get(user, {})rank = self.recommend(user, k=k, nitems=nitems)for item, rate in rank.items():if item in tu:hit += 1precision += nitemsreturn hit / (precision * 1.0)

5.运行测试结果


--------------开始计时... -------------------------基于MovieLens的推荐系统 运行中... -----------加载数据...
训练数据集与测试数据集切分...
开始计算用户之间的相似度 ...
user '1' recommend result is {'1907': 1.1719770420320046, '2078': 1.0771247187392352, '2081': 1.0758836648976486, '1029': 1.0711008152996346, '2096': 1.0625630426343857, '596': 1.0451797898417066, '2085': 0.9577988630036637, '2080': 0.9410112225805409, '364': 0.9193391674871346, '1270': 0.8780339152128267, '480': 0.8681534812717586, '1282': 0.8674376643580475, '2028': 0.8547482945805895, '783': 0.7351700653028361, '1032': 0.7315950136253785, '593': 0.720277373175779, '1265': 0.6967484368684826, '1198': 0.6954032288177417, '1580': 0.6872105901375891, '2137': 0.6749673909596987, '1584': 0.6504546954200493, '2396': 0.6223822374562248, '539': 0.6216743169985597, '1196': 0.614253658798736, '1073': 0.614253658798736, '1148': 0.599029462528578, '110': 0.5979119650391214, '1210': 0.5770033651370033, '34': 0.5609050960671571, '2087': 0.5563225830541934, '296': 0.5189526708406325, '2571': 0.48716409090204715, '3751': 0.4779821383770259, '920': 0.47310567081152793, '2858': 0.4653183808365773, '3578': 0.4653183808365773, '3000': 0.4633607993152704, '1617': 0.4522073324341529, '1721': 0.4443252923900383, '3615': 0.4408193455994457} --------------结束计时... -----------总耗时:0:21:00.978540
开始计算准确率 ...
precision is 0.1909437086092715Process finished with exit code 0

四、总结

本文是基于用户的协同过滤的简单案列,采用Movielens数据集作为实验,本文代码实现起来比较简单,最后的结果我们可以看出UserCF准确率并不高 可以尝试使用不同的k值(近邻用户)来调节推荐算法的准确率。以后可以结合发掘更多相关因素 比如加入时间衰退因子 进行加强相似度的准确率,或者我们可以继续探讨另一种协同过滤算法 -基于物品的协同过滤(ItemCF)。


http://chatgpt.dhexx.cn/article/OGKXxhsU.shtml

相关文章

ML之GB:基于MovieLens电影评分数据集利用基于图的推荐算法(Neo4j图数据库+Cypher查询语言)实现对用户进行Top5电影推荐案例

ML之GB:基于MovieLens电影评分数据集利用基于图的推荐算法(Neo4j图数据库Cypher查询语言)实现对用户进行Top5电影推荐案例 目录 基于MovieLens电影评分数据集利用基于图的推荐算法(Neo4j图数据库Cypher查询语言)实现对用户进行Top5电影推荐案例 1、定义数据集 1.…

从IMDB上爬取MovieLens-1m的补充数据(电影海报和简介)

文章主要内容 本人是想做推荐算法相关的一名在校生,目前想做多模态融合,而MovieLens-1m数据集只有电影信息和用户信息,于是有想法能否在原有的电影推荐公开数据集中而外获取电影海报(图片信息)和电影简介(…

对Movielens数据集进行评分预测

对Movielens数据集进行评分预测 实验源码:lab3代码.ipynb 实验环境:vscode colab 数据解释: movies.dat的数据如下 1::Toy Story (1995)::Animation|Childrens|Comedy 2::Jumanji (1995)::Adventure|Childrens|Fantasy 3::Grumpier Old…

ML之KG:基于MovieLens电影评分数据集利用基于知识图谱的推荐算法(networkx+基于路径相似度的方法)实现对用户进行Top电影推荐案例

ML之KG:基于MovieLens电影评分数据集利用基于知识图谱的推荐算法(networkx基于路径相似度的方法)实现对用户进行Top电影推荐案例 目录 基于MovieLens电影评分数据集利用基于知识图谱的推荐算法(networkx基于路径相似度的方法)实现对用户进行Top电影推荐案例 # 1、定…

利用pandas对MovieLens电影数据分析

掌握pandas基本语法操作「pandas基础入门中有详细语法格式」后,就可以利用pandas做一些简单实例的数据处理。 Movie电影数据分析 首先需要下载电影数据集MovieLens,这个数据集中包含用户数据;电影数据;电影评分表。电影数据中包…

MovieLens数据集处理

有一个定律,对于内容的访问遵循80/20原则,也就是20%的内容,会占有80%的访问量。就是zipf分布[1]。  根据MovieLens的数据集中的ratings.dat,我做了数据处理,获取得分最高的2000个条目。 ml-pro.py import os import …

推荐系统笔记(二):常用数据集Movielens学习

介绍 movielens数据集是电影推荐数据集,数据集有多种大小和目的使用的数据集。按照使用目的可以分为两类,一类数据集适用于推进最新研究的数据,一类数据集是用于高校研究和教育科研使用的数据集。本次介绍三个数据集的使用和处理。 数据集下…

java读取movielens数据txt

各位好,我是菜鸟小明哥,movielens数据是常见的推荐方面的开源数据集,另一个推荐方面的数据集是新闻MIND,本文将从movielens再次出发,做基础的推荐方法,比如基本的基于标题的相似性,word2vector&…

推荐系统数据集之MovieLens

1.概述 MovieLens其实是一个推荐系统和虚拟社区网站,它由美国 Minnesota 大学计算机科学与工程学院的GroupLens项目组创办,是一个非商业性质的、以研究为目的的实验性站点。GroupLens研究组根据MovieLens网站提供的数据制作了MovieLens数据集合&#xff…

【工具】Movielens数据集详细介绍

MovieLens数据集 MovieLens数据集包含多个用户对多部电影的评级数据,也包括电影元数据信息和用户属性信息。 下载地址 http://files.grouplens.org/datasets/movielens/ 介绍 下面以ml-100k数据集为例进行介绍: 最主要用的是u.data(评分) | u.item…

movielens数据集简述

一、movielens数据集 ratings数据: 文件里面的内容包含了每一个用户对于每一部电影的评分。数据格式如下: userId, movieId, rating, timestamp userId: 每个用户的id movieId: 每部电影的id rating: 用户评分,是5星制,按半颗星的规模递增(0.5 stars - 5 stars) timestam…

Movielens数据集详细介绍

MovieLens数据集包含多个用户对多部电影的评级数据,也包括电影元数据信息和用户属性信息。下载地址为:http://files.grouplens.org/datasets/movielens/ 下面以ml-100k数据集为例进行介绍: 最主要用的是u.data(评分) | u.item(电影信息) …

movielens数据集介绍及使用python简单处理

0 前言 个性化推荐中,电影推荐研究时常使用movielens上的数据集。该网站的数据集主要分两部分, 一是用于推进最新研究进展的数据集。当前最新的是发布于2019年12月份的25M数据集。 二是用于高校、组织科研的数据集。该类数据集按其是否带有标签、时间…

mui用ajax上拉加载更多,mui上拉加载更多下拉刷新数据的封装过程

辗转用mui做了两个项目,空下来把mui上拉加载更多,下拉刷新数据做了一个简单的封装,希望可以帮助到需要的朋友 demo项目的结构 直接贴代码了 index.html mui上拉刷新下拉加载都这里了,两个方法搞定mui上拉刷新下拉加载demo--封装 l…

如何实现上拉加载和下拉刷新

下拉刷新和上拉加载这两种交互⽅式通常出现在移动端中 本质上等同于PC⽹⻚中的分⻚,只是交互形式不同 开源社区也有很多优秀的解决⽅案,如 iscroll 、 better-scroll 、 pulltorefresh.js 库等等 这些第三⽅库使⽤起来⾮常便捷 我们通过原⽣的⽅式实现…

ComposeUI——下拉刷新+上拉加载(一、简单封装)

前言:ComposeUI是将来开发的趋势,本人也在对它进行学习,会把踩过的坑一一记录下来,希望能对大家有帮助。话不多说,直接开干。 目录 下拉刷新 1、引入依赖库 2、使用方法 上拉加载 1、先看用法(结合下…

Flutter 下拉刷新、上拉加载

Flutter 下拉刷新、上拉加载有很多第三方插件,本文使用插件为:pull_to_refresh 目前pull_to_refresh在pub.dev上的使用情况: 刷新header的类型: ClassicHeader const ClassicHeader({Key? key,RefreshStyle refreshStyle: RefreshStyle.…

BaseQuickAdapter上拉加载功能实现

最近使用BaseQuickAdapter进行RecyclerView 的Adapter的数据绑定显示。 实现上拉加载与下拉刷新功能,遇到如下问题: 1、首先是实现下拉刷新、下拉加载的监听(xml布局就不贴出来了): 2、现在贴出来错误的处理方式&…

android 官方上拉,手把手教你实现RecyclerView的下拉刷新和上拉加载更多

纵观多数App,下拉刷新和上拉加载更多是很常见的功能,但是谷歌官方只有一个SwipeRefreshLayout用来下拉刷新,上拉加载更多还要自己做。 基于RecyclerView简单封装了这两个操作,下拉刷新支持LinearLayoutManager、GridLayoutManager…

uniapp下拉刷新上拉加载

一、需求 留言板主页&#xff0c;显示所有的留言信息&#xff0c;带有分页功能&#xff1b;上拉加载数据&#xff0c;下拉刷新数据二、代码 1、pages.json 2、messageBoard.vue 用了 uniapp 提供的组件&#xff1a; uni-load-more.vue <uni-load-more :status"load…