基于用户的协同过滤Movielens电影推荐系统简单实例
基于用户的协同过滤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)。
基于用户的协同过滤Movielens电影推荐系统简单实例相关推荐
- 基于用户的协同过滤来构建推荐系统(附代码)
导读:协同过滤技术在推荐系统中应用的比较广泛,它是一个快速发展的研究领域.它比较常用的两种方法是基于内存 ( Memory-Based ) 和基于模型 ( Model-Based ). 基于内存:主要 ...
- 基于用户的协同过滤算法详解
0. 前言 基于领域的推荐算法是推荐系统中最基本的算法,此类算法不仅在学术界得到了深入研究,而且在工业界也得到了广泛地应用.基于领域的推荐算法主要分为两大类:一类是基于用户的协同过滤算法(User B ...
- 利用用户行为数据——基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二)
系列文章目录 初识推荐系统--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(一) 利用用户行为数据--基于Spark平台的协同过滤实时电影推荐系统项目系列博客(二) 项目主要效果展示--基 ...
- mysql数据推荐算法_Java+Mysql实现简单在线电影、音乐、图书推荐系统 基于用户的协同过滤推荐算法实现 源代码下载...
# Java+Mysql实现简单在线电影.音乐.图书等推荐系统(基于用户的协同过滤推荐算法) 一.项目简介 1.开发工具和实现技术 MyEclipse10,jdk1.7,mysql5.5,tomca ...
- Python实现基于用户的协同过滤推荐算法构建电影推荐系统
说明:这是一个机器学习实战项目(附带数据+代码+文档+视频讲解),如需数据+代码+文档+视频讲解可以直接到文章最后获取. 1.项目背景 基于用户的协同过滤推荐(User-based CF)的原理假设: ...
- 基于用户的协同过滤算法的电影推荐系统
上一篇讲解了推荐算法的分类,这里电影推荐系统具体分析一下 第一步:建立用户电影矩阵模型 如表1所示,协同过滤算法的输入数据通常表示为一个m*n的用户评价矩阵Matrix,m是用户数,n是电影数,Mat ...
- C++实现基于用户的协同过滤大数据电影推荐系统
<大数据计算及应用> [推荐系统]实验报告 目录 <大数据计算及应用> 1 [推荐系统]实验报告 1 [实验相关统计信息] 1 (1)统计用户数量:19835. 1 [实验原理 ...
- 基于Spark平台的协同过滤实时电影推荐系统
文章目录 摘要 0 引言 1 协同过滤算法 2 实时推荐服务 3 电影推荐系统设计部署 3.1 架构设计 3.2 系统功能设计 3.3 数据库设计 4 系统运行效果 5 结语 参考文献 摘要 摘要:随 ...
- 推荐系统--基于用户的协同过滤算法
1. 概述 和搜索引擎一样,推荐系统是为了帮助人们更快速的获得对自己有用的信息. 和搜索引擎不同,推荐系统是人们被动的获取,由系统根据用户行为或其他的信息推荐给用户的,儿搜索引擎是用户 ...
- 基于Spark MLlib平台的协同过滤算法---电影推荐系统
协同过滤算法概述 基于模型的协同过滤应用---电影推荐 实时推荐架构分析 一.协同过滤算法概述 本人对算法的研究,目前还不是很深入,这里简单的介绍下其工作原理. 通常,协同过滤算法按照数据使用 ...
最新文章
- CCNP ONT LAB之PQ WFQ
- 程序员究竟能干多少年?用数据说话!
- 为什么线粒体DNA突变率高?
- python 必备模块和包_Python_异常和模块
- NXP(I.MX6uLL)DDR3实验——DDR3重要时间参数、时钟配置与原理图简析
- vsc写vue生成基本代码快捷键_基于vue2.X的webpack基本配置,教你手动撸一个webpack4的配置...
- java初反射_java中的反射机制
- 23种设计模式(七)对象创建之工厂方法
- Matlab信息加密解密系统
- alize blue_泽野弘之 | 明明可以靠才华,却非要用脸滚键盘的神曲缔造者
- 超星尔雅不让下载?课件,拿来吧你!
- ABB机器人伺服电机维修故障
- 在Cadence中使用ADE进行蒙特卡洛仿真
- linux版本的火狐浏览器,火狐浏览器Linux版本
- OA协同办公系统对企业建设会带来什么好处?
- 土地购买[Usaco2008 Mar]
- android 8.0手机无法更新版本,微信8.0安卓机怎么安装更新 安卓微信更新不了8.0解决办法一览...
- 穹顶之下-善恶是非谁来负责
- 微信小程序 MinUI 组件库系列之 loadmore 页底组件
- 禾穗HERS | 职场新人第一定律