代码基本来自项亮的<推荐系统实践>,把书上的伪代码具体实现,还参考了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实现的更多相关文章

  1. 基于用户的最近邻协同过滤算法(MovieLens数据集)

      基于用户的最近邻算法(User-Based Neighbor Algorithms),是一种非概率性的协同过滤算法,也是推荐系统中最最古老,最著名的算法. 我们称那些兴趣相似的用户为邻居,如果用户 ...

  2. SVD++:推荐系统的基于矩阵分解的协同过滤算法的提高

    1.背景知识 在讲SVD++之前,我还是想先回到基于物品相似的协同过滤算法.这个算法基本思想是找出一个用户有过正反馈的物品的相似的物品来给其作为推荐.其公式为:

  3. Mahout分布式运行实例:基于矩阵分解的协同过滤评分系统(一个命令实现文件格式的转换)

     Apr 08, 2014  Categories in tutorial tagged with Mahout hadoop 协同过滤  Joe Jiang 前言:之前配置Mahout时测试过一个简 ...

  4. memory-based 协同过滤(CF)方法

    协同过滤(collaborative filtering,CF)算法主要分为memory-based CF 和 model-based CF,而memory-based CF 包括user-based ...

  5. 推荐系统-协同过滤在Spark中的实现

    作者:vivo 互联网服务器团队-Tang Shutao 现如今推荐无处不在,例如抖音.淘宝.京东App均能见到推荐系统的身影,其背后涉及许多的技术.本文以经典的协同过滤为切入点,重点介绍了被工业界广 ...

  6. 基于Python协同过滤算法的认识

    Contents    1. 协同过滤的简介    2. 协同过滤的核心    3. 协同过滤的实现    4. 协同过滤的应用 1. 协同过滤的简介 关于协同过滤的一个最经典的例子就是看电影,有时候 ...

  7. 基于物品的协同过滤item-CF 之电影推荐 python

    推荐算法有基于协同的Collaboration Filtering:包括 user Based和item Based:基于内容 : Content Based 协同过滤包括基于物品的协同过滤和基于用户 ...

  8. Music Recommendation System with User-based and Item-based Collaborative Filtering Technique(使用基于用户及基于物品的协同过滤技术的音乐推荐系统)【更新】

    摘要: 大数据催生了互联网,电子商务,也导致了信息过载.信息过载的问题可以由推荐系统来解决.推荐系统可以提供选择新产品(电影,音乐等)的建议.这篇论文介绍了一个音乐推荐系统,它会根据用户的历史行为和口 ...

  9. 基于协同过滤的个性化Web推荐

    下面这是论文笔记,其实主要是摘抄,这片博士论文很有逻辑性,层层深入,所以笔者保留的比较多. 看到第二章,我发现其实这片文章对我来说更多是科普,科普吧…… 一.论文来源 Personalized Web ...

随机推荐

  1. Thread 与 Runnable

    在Java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...

  2. sqlmap注入检测经验0x01

    某日偶遇一SQLInjection Point,MSSQL 2008,已开启显错模式. 马上扔进SQLMap跑,一路顺畅,竟然还是SA的权限,心想运气真好,无论如何都拿定了. 数据库,表,列都列出来了 ...

  3. heartbleed漏洞利用

    1.  heartbleed漏洞扫描: 2.  heartbleed漏洞利用: poc.py      117.52.93.111 貌似没有打到管理员账号密码,可能是管理员没登录,其实,可以写一个自动 ...

  4. 在Razor中如何引入命名空间?("import namespace in razor view") 【转】

    原文链接 找了半天,原来如此: 在aspx中: <%@ Import Namespace = "Martian.Areas.SFC.Models" %><%@ I ...

  5. Yii URL

    参考文章: http://blog.csdn.net/iefreer/article/details/21325371 以http://localhost/basic/web/index.php?r= ...

  6. Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']

    public function getMinLimit () {        $sql = "...";        $result = yii::app()->db-& ...

  7. 使用proguard混淆java web项目代码

    1.首先下载proGuard.zip到本地: proguard4.5beta4.tar.zip解压开,2.新建文本文档,修改文件名为XXX.pro,然后复制下面内容到.pro -injars 'Y:\ ...

  8. Jenkins入门总结

    Jenkins是基于Java开发的一种持续集成工具,用于监控持续重复的工作,功能包括: 1.持续的软件版本发布/测试项目. 2.监控外部调用执行的工作 在网上貌似没有找到Jenkins的中文的太多的文 ...

  9. MySQL创建一个用户,指定一个数据库 授权

    Mysql 创建一个用户 hail,密码 hail,指定一个数据库 haildb 给 hail mysql -u root -ppassworduse mysql;insert into user(h ...

  10. java常用类 --- Object

    Object类 Object类是所有Java类的父类,其位于java.lang包中.任何Java对象,如果没有显示定义父类则它默认Object类作为父类. 方法如下: 其中与线程相关的有5个方法: n ...