协同过滤(Collaborative Filtering):UserCF and Item CF
具体的学习资料可以参考王喆老师的《深度学习推荐系统》,已经梳理好了知识体系,我也将按照这个路线再次梳理一遍,同时做一些拓展和加深理解
一、前言
系统过滤曾是多年前推荐系统领域的应用最广泛的模型,也是基石一样的存在,重要!重要!
这里推出两篇论文,我们将简单看下论文,并进行代码复现 ,这里主要讲两部分
(1)基于用户的协同过滤算法(UserCF): 给用户推荐和他兴趣相似的其他用户喜欢的产品
(2)基于物品的协同过滤算法(ItemCF): 给用户推荐和他之前喜欢的物品相似的物品
2001年 Item-Based Collaborative Filtering Recommendation Algorithms
2003年 Amazon.com Recommendations Item-to-Item Collaborative Filtering
二、协同过滤
1、什么是协同过滤
就是协同大家的反馈、评价和意见一起对海量的信息进行过滤,从中筛选出目标用户可能感兴趣的信息这样一个推荐过程
简而言之,我们要判断目标用户是否喜欢某物品,就是将所有用户交互的物品,生成共现矩阵(这里就是指用户对于物品的评分,存成矩阵方便后面的计算),然后通过找到相似用户(或相似物品),看相似用户的评价,进而估计出目标用户的评价
2、用户的相似度计算
计算相似度需要根据特点的不同选择不同的相似度计算方法, 比较常用的有下面几种,
(1)余弦相似度
余弦相似度( Cosine Similarity ) 衡量 了用户向量i和用户向量J之间的向量夹角大小。显然,夹角越小,证明余弦相似 度越大,两个用户越相似。
对于某些用户喜欢普遍低分或者普遍打高分,所以对于这种用户评分偏置的情况, 余弦相似度就不是那么好了, 可以考虑使用下面的皮尔逊相关系数。
(2)皮尔逊相关系数
(3)物品平均分的方式
3、最终的结果排序
(2)还有一种方式如下, 而是该物品的评分与此用户的所有评分的差值进行加权平均, 这时候考虑到了有的用户内心的评分标准不一的情况, 即有的用户喜欢打高分, 有的用户喜欢打低分的情况。
至此, 基于用户的协同过滤算法的推荐过程完成。
三、算法实现
1、userCF概念
1.1 UserCF代码实现
(1)数据集加载
依次对应用户ID、物品ID、评分、时间戳
划分训练集和测试集
# 声明两个字典, 分别是训练集和测试集
trainSet, testSet = {}, {}
trainSet_len, testSet_len = 0, 0
pivot = 0.75 # 训练集的比例# 遍历data的每一行, 把userId, movidId, rating按照{user: {movidId: rating}}的方式存储, 当然定义一个随机种子进行数据集划分
for ele in data.itertuples(): # 遍历行这里推荐用itertuples, 比iterrows会高效很多user, movie, rating = getattr(ele, 'userId'), getattr(ele, 'movieId'), getattr(ele, 'rating')if random.random() < pivot:trainSet.setdefault(user, {})trainSet[user][movie] = ratingtrainSet_len += 1else:testSet.setdefault(user, {})testSet[user][movie] = rating testSet_len += 1
例如:将用户1所交互的物品随机分3:1Split trainingSet and testSet success! TrainSet = 75657 TestSet = 25179
(2)计算用户间的相似度
user_sim_matrix = {}# 构建“电影-用户”倒排索引 # key = movidID, value=list of userIDs who have seen this move
print('Building movie-user table ...')
movie_user = {}
for user, movies in trainSet.items(): # 这里的user就是每个用户, movies还是个字典, {movieID: rating}for movie in movies: # 这里的movie就是movieID了if movie not in movie_user: # 如果movidID没在倒排索引里面movie_user[movie] = set() # 声明这个键的值是set, 保证用户不重复movie_user[movie].add(user) # 把用户加进去,
print('Build movie-user table success!')# 下面建立用户相似矩阵
movie_count = len(movie_user)
print('Total movie number = %d' % movie_count)print('Build user co-rated users matrix ...')
for movie, users in movie_user.items(): # movid是movieID, users是set集合for u in users: # 对于每个用户, 都得双层遍历for v in users:if u == v:continueuser_sim_matrix.setdefault(u, {}) # 把字典的值设置为字典的形式user_sim_matrix[u].setdefault(v, 0)user_sim_matrix[u][v] += 1 # 这里统计两个用户对同一部电影产生行为的次数, 这个就是余弦相似度的分子
print('Build user co-rated users matrix success!')# 下面计算用户之间的相似性
print('Calculating user similarity matrix ...')
for u, related_users in user_sim_matrix.items():for v, count in related_users.items(): # 这里面v是相关用户, count是共同对同一部电影打分的次数user_sim_matrix[u][v] = count / math.sqrt(len(trainSet[u]) * len(trainSet[v])) # len 后面的就是用户对电影产生过行为的个数
print('Calculate user similarity matrix success!')
Building movie-user table ... Build movie-user table success! Total movie number = 8765 Build user co-rated movies matrix ... Build user co-rated movies matrix success! Calculating user similarity matrix ... Calculate user similarity matrix success!
(3)产生推荐
# 找到最相似的20个用户, 产生10个推荐
k = 20
n = 10aim_user = 3 # 目标用户ID
rank ={}
watched_movies = trainSet[aim_user] # 找出目标用户看到电影# 下面从相似性矩阵中找到与aim_user最相近的K个用户# v 表示相似用户, wuv表示相似程度
for v, wuv in sorted(user_sim_matrix[aim_user].items(), key=lambda x: x[1], reverse=True)[0:k]: # 字典按值从大到小排序, 相关性高到第# 把v用户看过的电影推荐给目标用户for movie in trainSet[v]:if movie in watched_movies:continuerank.setdefault(movie, 0)rank[movie] += wuv# 产生最后的推荐列表
rec_movies = sorted(rank.items(), key=itemgetter(1), reverse=True)[:n] # itemgetter(1) 是简洁写法
(4)评价指标
# 准确率、召回率和覆盖率
hit = 0
rec_count = 0 # 统计推荐的影片数量, 计算查准率
test_count = 0 # 统计测试集的影片数量, 计算查全率
all_rec_movies = set() # 统计被推荐出来的影片个数, 无重复了, 为了计算覆盖率
item_populatity = dict() # 计算新颖度# 先计算每部影片的流行程度
for user, items in trainSet.items():for item in items.keys():if item not in item_populatity:item_populatity[item] = 0item_populatity[item] += 1 # 这里统计训练集中每部影片用户观看的总次数, 代表每部影片的流行程度# 计算评测指标
ret = 0
ret_cou = 0
for user, items in trainSet.items(): # 这里得保证测试集里面的用户在训练集里面才能推荐test_movies = testSet.get(user, {})rec_movies = recommend(user)for movie, w in rec_movies:if movie in test_movies:hit += 1all_rec_movies.add(movie)ret += math.log(1+item_populatity[movie])ret_cou += 1rec_count += ntest_count += len(test_movies)precision = hit / (1.0 * rec_count)
recall = hit / (1.0 * test_count)
coverage = len(all_rec_movies) / movie_count
ret /= ret_cou*1.0print('precisioin = %.4f\nrecall = %.4f\ncoverage = %.4f\npopularity = %.4f' % (precision, recall, coverage, ret))
四、总结
协同过滤的头部效应较为明显、泛化能力较弱
所以后续被加以改进,提出矩阵分解在系统过滤的基础上加入隐向量的概念,加强模型处理稀疏矩阵的能力,后续将会出矩阵分解(MF)的论文及复现代码
协同过滤(Collaborative Filtering):UserCF and Item CF相关推荐
- 推荐系统:协同过滤collaborative filtering
http://blog.csdn.net/pipisorry/article/details/51788955 (个性化)推荐系统构建三大方法:基于内容的推荐content-based,协同过滤col ...
- 协同过滤(collaborative filtering)
Author: Summer; Email: huangmeihong11@sina.com Datawhale 协同过滤简介 协同过滤是推荐算法中最常用的算法之一,它根据user与item的交互,发 ...
- 基于关联规则(Apriori)+协同过滤(collaborative filtering)实现电影推荐系统
基于关联规则算法+协同过滤算法的电影推荐系统 一.前言 1.数据集介绍 2.方法概述 3.运行环境 二.数据准备与预处理 1.数据熟悉 2.数据读取 3.数据预处理 3.1 无用属性删除 3.2 缺失 ...
- 机器学习实战(十三)推荐系统(协同过滤 Collaborative Filtering)
目录 0. 前言 1. 相似度 1.1. 欧式距离(Euclidean metric) 1.2. 皮尔逊相关系数(Pearson correlation coefficient) 1.3. 余弦相似度 ...
- usercf代码java_基于用户的协同过滤算法(UserCF)原理以及代码实践
简介 协同过滤(collaborative filtering)是一种在推荐系统中广泛使用的技术.该技术通过分析用户或者事物之间的相似性,来预测用户可能感兴趣的内容并将此内容推荐给用户.这里的相似性可 ...
- 推荐系统-模型(一):召回模型【协同过滤类: ItemCF/UserCF】【Embedding类】【Dssm/双塔/word2vec】【图类召回算法 (Deepwalk、EGES)】
推荐系统-召回模型:[协同过滤类: ItemCF/UserCF][Embedding类][Dssm/双塔/word2vec][图类召回算法 (Deepwalk.EGES)]
- 协同过滤算法分类-UserCF
UserCf 基于用户的协同过滤算法 给用户推荐相似兴趣用户感兴趣的物品 举例如下: 用户ABCD物品a.b.c.d 上述的信息汇总userA点击了item a.b.d类似往后userD 点击了ite ...
- 协同过滤推荐算法:UserCF、ItemCF python现实
目录 一.协同过滤算法 二.基于邻域的算法:UserCF.ItemCF 三.UserCF.ItemCF的改进 一.协同过滤推荐算法 协同过滤算法是指基于用户行为数据设计的推荐算法,主要包括: 1.基于 ...
- [推荐] 协同滤波 —— Collaborative Filtering (CF)
协同滤波在推荐当中应用比较广泛的算法,协同滤波主要是有两种方式: 既然是推荐,一定设计人和物两个方面,因此 CF 分为基于用户的CF和基于item的CF. 一.基于用户的CF计算用户之间的相似性,并且 ...
最新文章
- Showstopper [POJ3484] [二分] [思维]
- Android之Android触摸事件传递机制
- 使用CEfSharp之旅(1) 加载网络页面
- 2022年计算机考研学校,2022计算机考研院校推荐
- extjs jquery使用场合
- ZK Framework(一、HelloWorld)
- linux把虚拟机上的文件共享,[转]windows中vmware虚拟机中的Linux如何进行文件的共享...
- Linux环境下查看CPU资源的命令
- Python中的lamda表达式
- c语言59秒倒计时程序,59分59秒倒计时程序及仿真显示
- PDF Expert for Mac最新2020注册码激活版下载
- 九步用树莓派开发板实现QT工程项目
- access建立两个字段唯一索引_Mysql不止CRUD,聊聊索引
- i5 10500h和i5 10300h有什么区别i510500h和i510300h差距大不大
- win10禁止访问某网站
- git tag 打标签(我看过最透彻的文章)
- ads1258_ADS1258高精度多通道模/数转换芯片
- npm -g, npm -s, npm -d 的区别
- 全国计算机三级网络技术电子版,全国计算机三级网络技术最新版笔试电子教材(完全免费版).doc...
- mouseinfo的使用
热门文章
- 【AD封装】VGA视频座子,RJ11座子(带3D)
- Qt之基于Graphics View实现Mesh网络拓扑图
- [翻译]Kean' Blog 在一个.NET应用程序中调用AutoCAD(续)
- Python——NumPy数值计算基础
- iText7高级教程之构建基础块——1.引入字体
- 电脑鼠原理与实践学习笔记
- 问:小程序订阅消息用户拒绝后,如何引导用户开启?并获得用户的操作状态?
- SpringCloud微服务技术实践与总结(基础篇)
- 免费ARP(Gratuitousnbsp;ARP)简析
- java 级联删除_java 级联删除文件夹下的所有文件