基于用户相似性的协同过滤——Python实现
代码基本来自项亮的<推荐系统实践>,把书上的伪代码具体实现,还参考了https://www.douban.com/note/336280497/
还可以加入对用户相似性的归一化操作,效果会更好。
数据集为MovieLens的10万条数据.
链接:MoiveLens
#coding:utf-8
import random,math
from operator import itemgetter class UserBasedCF:
def __init__(self,trainDataFile=None,testDataFile=None,splitor='\t'):
if trainDataFile!=None:
self.train=self.loadData(trainDataFile, splitor)
if testDataFile!=None:
self.test=self.loadData(testDataFile, splitor)
self.simiMatrix={} def setData(self,train,test):
self.train=train
self.test=test def loadData(self,dataFile,splitor='\t'):
data={}
for line in open(dataFile):
user,item,record,_ = line.split()
data.setdefault(user,{})
data[user][item]=record
return data def recallAndPrecision(self,peersCount,topN=10):
hit=0
recall=0
precision=0
for user in self.train.keys():
itemOfuser=self.test.get(user,{})
recItems=self.recommend(user,peersCount,topN)
for item,pui in recItems.items():
if item in itemOfuser:
hit+=1
recall+=len(itemOfuser)
precision+=topN
#print 'Recall:%s hit:%s allRatings:%s'%(hit/(recall*1.0),hit,precision)
return (hit / (recall * 1.0),hit / (precision * 1.0)) def coverage(self,peersCount,topN=10):
recommend_items=set()
all_items=set()
for user in self.train.keys():
for item in self.train[user].keys():
all_items.add(item)
rank=self.recommend(user,peersCount,topN)
for item,pui in rank.items():
recommend_items.add(item)
return len(recommend_items)/(len(all_items)*1.0) def popularity(self,peersCount,topN=10):
item_popularity=dict()
for user,items in self.train.items():
for item in items.keys():
if item not in item_popularity:
item_popularity[item]=1
item_popularity[item]+=1
ret=0
n=0
for user in self.train.keys():
rank=self.recommend(user,peersCount,topN)
for item,pui in rank.items():
ret+=math.log(1+item_popularity[item])
n+=1
return ret/(n*1.0) def calUserSimilarity(self):
item_users=dict()
for u,ratings in self.train.items():
for i in ratings.keys():
item_users.setdefault(i,set())
item_users[i].add(u) #calculate co-rated items between users
coRatedCount=dict()
itemCountOfUser=dict()
for item,users in item_users.items():
for u in users:
itemCountOfUser.setdefault(u,0)
itemCountOfUser[u]+=1
for v in users:
if u==v:
continue
coRatedCount.setdefault(u,{})
coRatedCount[u].setdefault(v,0)
coRatedCount[u][v]+=1/math.log(1+len(users))
userSimiMatrix=dict()
for u,related_users in coRatedCount.items():
userSimiMatrix.setdefault(u,{})
for v,cuv in related_users.items():
userSimiMatrix[u][v]=cuv/math.sqrt(itemCountOfUser[u]*itemCountOfUser[v])
self.simiMatrix=userSimiMatrix def recommend(self,userU,peersCount,topN=10):
recItems=dict()
interacted_items=self.train[userU]
'''prepare the user similarity matrix first'''
if not self.simiMatrix:
self.calUserSimilarity()
for userV,simiUV in sorted(self.simiMatrix[userU].items(),key=itemgetter(1),reverse=True)[0:peersCount]:
for item,ratingV4I in self.train[userV].items():
if item in interacted_items:
continue
if item not in recItems:
recItems[item]=0
recItems[item]+=simiUV*float(ratingV4I)#transform 4 stars into score 0.8 '''if len(recItems)==topN:
return recItems'''
return dict(sorted(recItems.items(),key = lambda x :x[1],reverse = True)[0:topN]) def testUserBasedCF():
cf=UserBasedCF(trainDataFile=r'E:\ResearchAndPapers\DataSet\ml-100k\u3.base',testDataFile=r'E:\ResearchAndPapers\DataSet\ml-100k\u3.test')
#cf.calUserSimilarity()
print("%3s%15s%15s%15s%15s" % ('K',"precision",'recall','coverage','popularity'))
for k in [5,10,20,40,80,160]:
recall,precision = cf.recallAndPrecision(peersCount = k)
coverage = cf.coverage(peersCount = k)
popularity = cf.popularity(peersCount = k)
print("%3d%14.2f%%%14.2f%%%14.2f%%%15.2f" % (k,precision * 100,recall * 100,coverage * 100,popularity)) def SplitData(wholeData,M,k,seed,splitor='\t'):
test={}
train={}
random.seed(seed) for line in wholeData:
user,item,score,time=line.strip().split(splitor)
if random.randint(0,M)==k:
test.setdefault(user,{})
test[user][item]=score
else:
train.setdefault(user,{})
train[user][item]=score
return train,test def testUserBasedCF2():
wholeData=open(r'E:\ResearchAndPapers\DataSet\ml-1m\ratings.dat')
train,test=SplitData(wholeData, 8, 5, 10, splitor='::')
cf=UserBasedCF()
cf.setData(train, test)
#cf=UserBasedCF(trainDataFile=r'E:\ResearchAndPapers\DataSet\ml-100k\u5.base',testDataFile=r'E:\ResearchAndPapers\DataSet\ml-100k\u5.test')
#cf.calUserSimilarity()
print("%3s%15s%15s%15s%15s" % ('K',"precision",'recall','coverage','popularity'))
for k in [5,10,20,40,80,160]:
recall,precision = cf.recallAndPrecision(peersCount = k)
coverage = cf.coverage(peersCount = k)
popularity = cf.popularity(peersCount = k)
print("%3d%14.2f%%%14.2f%%%14.2f%%%15.2f" % (k,precision * 100,recall * 100,coverage * 100,popularity)) if __name__=="__main__":
testUserBasedCF()
#testUserBasedCF2()
基于用户相似性的协同过滤——Python实现的更多相关文章
- 基于用户的最近邻协同过滤算法(MovieLens数据集)
基于用户的最近邻算法(User-Based Neighbor Algorithms),是一种非概率性的协同过滤算法,也是推荐系统中最最古老,最著名的算法. 我们称那些兴趣相似的用户为邻居,如果用户 ...
- SVD++:推荐系统的基于矩阵分解的协同过滤算法的提高
1.背景知识 在讲SVD++之前,我还是想先回到基于物品相似的协同过滤算法.这个算法基本思想是找出一个用户有过正反馈的物品的相似的物品来给其作为推荐.其公式为:
- Mahout分布式运行实例:基于矩阵分解的协同过滤评分系统(一个命令实现文件格式的转换)
Apr 08, 2014 Categories in tutorial tagged with Mahout hadoop 协同过滤 Joe Jiang 前言:之前配置Mahout时测试过一个简 ...
- memory-based 协同过滤(CF)方法
协同过滤(collaborative filtering,CF)算法主要分为memory-based CF 和 model-based CF,而memory-based CF 包括user-based ...
- 推荐系统-协同过滤在Spark中的实现
作者:vivo 互联网服务器团队-Tang Shutao 现如今推荐无处不在,例如抖音.淘宝.京东App均能见到推荐系统的身影,其背后涉及许多的技术.本文以经典的协同过滤为切入点,重点介绍了被工业界广 ...
- 基于Python协同过滤算法的认识
Contents 1. 协同过滤的简介 2. 协同过滤的核心 3. 协同过滤的实现 4. 协同过滤的应用 1. 协同过滤的简介 关于协同过滤的一个最经典的例子就是看电影,有时候 ...
- 基于物品的协同过滤item-CF 之电影推荐 python
推荐算法有基于协同的Collaboration Filtering:包括 user Based和item Based:基于内容 : Content Based 协同过滤包括基于物品的协同过滤和基于用户 ...
- Music Recommendation System with User-based and Item-based Collaborative Filtering Technique(使用基于用户及基于物品的协同过滤技术的音乐推荐系统)【更新】
摘要: 大数据催生了互联网,电子商务,也导致了信息过载.信息过载的问题可以由推荐系统来解决.推荐系统可以提供选择新产品(电影,音乐等)的建议.这篇论文介绍了一个音乐推荐系统,它会根据用户的历史行为和口 ...
- 基于协同过滤的个性化Web推荐
下面这是论文笔记,其实主要是摘抄,这片博士论文很有逻辑性,层层深入,所以笔者保留的比较多. 看到第二章,我发现其实这片文章对我来说更多是科普,科普吧…… 一.论文来源 Personalized Web ...
随机推荐
- Js获取指定Url参数
在 C#.PHP.JSP 中,都有直接获取 Url 中指定参数的方法,但 Javascript 却没有这样的现在方法,得自己写一个.在 Web 的开发过程中,获取 Url 中的参数是十分常用的操作,所 ...
- echosp 销量排行 新增实际价格
找到lib_goods.php第147行,代码 $sql = 'SELECT g.goods_id, g.goods_name, g.shop_price,g.goods_thumb, SUM(og. ...
- oracle union 注入工具
'***********************************************************************************************'ora ...
- Python之路【第十五篇】WEB框架
WEB框架本质 Python的WEB框架分为两类: 1.自己写socket,自己处理请求 2.基于wsgi(Web Server Gateway Interface WEB服务网关接口),自己处理请求 ...
- 程序日志输出实现-Log4j
学习开发的过程中,我们都应该用过System.out.println():来做一些调试工作,有时候确实很有用有没有.但是这种简单粗暴的方式让程序中到处存在着sysout.这种方式难免会有性能的影响,维 ...
- PhpStorm 快捷键
不容易记住的: Ctrl + Shift + F 查找文本,在项目目录或指定的目录 Ctrl + Shift + R 查找文本并替换,在项目目录或指定的目录 Ctrl + E 打开最近关闭的 ...
- ASP.NET MVC4/5 - Ajax 防止 CSRF攻击
前言 CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对 ...
- Jetty多Connector
有时候想要启动两个端口,或者通过一个Jetty server提供多个不同服务,比如说使用8080来指定默认访问端口,使用8433指定https访问端口等等,此时就可以通过创建多个Connector来解 ...
- mysql中获取一天、一周、一月时间数据的各种sql语句写法
今天抽时间整理了一篇mysql中与天.周.月有关的时间数据的sql语句的各种写法,部分是收集资料,全部手工整理,自己学习的同时,分享给大家,并首先默认创建一个表.插入2条数据,便于部分数据的测试,其中 ...
- motto11
我们应该这样来提高自己表达能力:在和人交流的时候,以欣赏的态度接受对方的观点,如果不太同意对方的观点,不能说对方的观点不好,而应该说,你的想法(观点)很好,但我认为,xxxxxx这样做会更好些. 这样 ...