代码基本来自项亮的<推荐系统实践>,把书上的伪代码具体实现,还参考了https://www.douban.com/note/336280497/

还可以加入对用户相似性的归一化操作,效果会更好。

数据集为MovieLens的10万条数据.
链接:MoiveLens

  1. #coding:utf-8
  2. import random,math
  3. from operator import itemgetter
  4.  
  5. class UserBasedCF:
  6. def __init__(self,trainDataFile=None,testDataFile=None,splitor='\t'):
  7. if trainDataFile!=None:
  8. self.train=self.loadData(trainDataFile, splitor)
  9. if testDataFile!=None:
  10. self.test=self.loadData(testDataFile, splitor)
  11. self.simiMatrix={}
  12.  
  13. def setData(self,train,test):
  14. self.train=train
  15. self.test=test
  16.  
  17. def loadData(self,dataFile,splitor='\t'):
  18. data={}
  19. for line in open(dataFile):
  20. user,item,record,_ = line.split()
  21. data.setdefault(user,{})
  22. data[user][item]=record
  23. return data
  24.  
  25. def recallAndPrecision(self,peersCount,topN=10):
  26. hit=0
  27. recall=0
  28. precision=0
  29. for user in self.train.keys():
  30. itemOfuser=self.test.get(user,{})
  31. recItems=self.recommend(user,peersCount,topN)
  32. for item,pui in recItems.items():
  33. if item in itemOfuser:
  34. hit+=1
  35. recall+=len(itemOfuser)
  36. precision+=topN
  37. #print 'Recall:%s hit:%s allRatings:%s'%(hit/(recall*1.0),hit,precision)
  38. return (hit / (recall * 1.0),hit / (precision * 1.0))
  39.  
  40. def coverage(self,peersCount,topN=10):
  41. recommend_items=set()
  42. all_items=set()
  43. for user in self.train.keys():
  44. for item in self.train[user].keys():
  45. all_items.add(item)
  46. rank=self.recommend(user,peersCount,topN)
  47. for item,pui in rank.items():
  48. recommend_items.add(item)
  49. return len(recommend_items)/(len(all_items)*1.0)
  50.  
  51. def popularity(self,peersCount,topN=10):
  52. item_popularity=dict()
  53. for user,items in self.train.items():
  54. for item in items.keys():
  55. if item not in item_popularity:
  56. item_popularity[item]=1
  57. item_popularity[item]+=1
  58. ret=0
  59. n=0
  60. for user in self.train.keys():
  61. rank=self.recommend(user,peersCount,topN)
  62. for item,pui in rank.items():
  63. ret+=math.log(1+item_popularity[item])
  64. n+=1
  65. return ret/(n*1.0)
  66.  
  67. def calUserSimilarity(self):
  68. item_users=dict()
  69. for u,ratings in self.train.items():
  70. for i in ratings.keys():
  71. item_users.setdefault(i,set())
  72. item_users[i].add(u)
  73.  
  74. #calculate co-rated items between users
  75. coRatedCount=dict()
  76. itemCountOfUser=dict()
  77. for item,users in item_users.items():
  78. for u in users:
  79. itemCountOfUser.setdefault(u,0)
  80. itemCountOfUser[u]+=1
  81. for v in users:
  82. if u==v:
  83. continue
  84. coRatedCount.setdefault(u,{})
  85. coRatedCount[u].setdefault(v,0)
  86. coRatedCount[u][v]+=1/math.log(1+len(users))
  87. userSimiMatrix=dict()
  88. for u,related_users in coRatedCount.items():
  89. userSimiMatrix.setdefault(u,{})
  90. for v,cuv in related_users.items():
  91. userSimiMatrix[u][v]=cuv/math.sqrt(itemCountOfUser[u]*itemCountOfUser[v])
  92. self.simiMatrix=userSimiMatrix
  93.  
  94. def recommend(self,userU,peersCount,topN=10):
  95. recItems=dict()
  96. interacted_items=self.train[userU]
  97. '''prepare the user similarity matrix first'''
  98. if not self.simiMatrix:
  99. self.calUserSimilarity()
  100. for userV,simiUV in sorted(self.simiMatrix[userU].items(),key=itemgetter(1),reverse=True)[0:peersCount]:
  101. for item,ratingV4I in self.train[userV].items():
  102. if item in interacted_items:
  103. continue
  104. if item not in recItems:
  105. recItems[item]=0
  106. recItems[item]+=simiUV*float(ratingV4I)#transform 4 stars into score 0.8
  107.  
  108. '''if len(recItems)==topN:
  109. return recItems'''
  110. return dict(sorted(recItems.items(),key = lambda x :x[1],reverse = True)[0:topN])
  111.  
  112. def testUserBasedCF():
  113. cf=UserBasedCF(trainDataFile=r'E:\ResearchAndPapers\DataSet\ml-100k\u3.base',testDataFile=r'E:\ResearchAndPapers\DataSet\ml-100k\u3.test')
  114. #cf.calUserSimilarity()
  115. print("%3s%15s%15s%15s%15s" % ('K',"precision",'recall','coverage','popularity'))
  116. for k in [5,10,20,40,80,160]:
  117. recall,precision = cf.recallAndPrecision(peersCount = k)
  118. coverage = cf.coverage(peersCount = k)
  119. popularity = cf.popularity(peersCount = k)
  120. print("%3d%14.2f%%%14.2f%%%14.2f%%%15.2f" % (k,precision * 100,recall * 100,coverage * 100,popularity))
  121.  
  122. def SplitData(wholeData,M,k,seed,splitor='\t'):
  123. test={}
  124. train={}
  125. random.seed(seed)
  126.  
  127. for line in wholeData:
  128. user,item,score,time=line.strip().split(splitor)
  129. if random.randint(0,M)==k:
  130. test.setdefault(user,{})
  131. test[user][item]=score
  132. else:
  133. train.setdefault(user,{})
  134. train[user][item]=score
  135. return train,test
  136.  
  137. def testUserBasedCF2():
  138. wholeData=open(r'E:\ResearchAndPapers\DataSet\ml-1m\ratings.dat')
  139. train,test=SplitData(wholeData, 8, 5, 10, splitor='::')
  140. cf=UserBasedCF()
  141. cf.setData(train, test)
  142. #cf=UserBasedCF(trainDataFile=r'E:\ResearchAndPapers\DataSet\ml-100k\u5.base',testDataFile=r'E:\ResearchAndPapers\DataSet\ml-100k\u5.test')
  143. #cf.calUserSimilarity()
  144. print("%3s%15s%15s%15s%15s" % ('K',"precision",'recall','coverage','popularity'))
  145. for k in [5,10,20,40,80,160]:
  146. recall,precision = cf.recallAndPrecision(peersCount = k)
  147. coverage = cf.coverage(peersCount = k)
  148. popularity = cf.popularity(peersCount = k)
  149. print("%3d%14.2f%%%14.2f%%%14.2f%%%15.2f" % (k,precision * 100,recall * 100,coverage * 100,popularity))
  150.  
  151. if __name__=="__main__":
  152. testUserBasedCF()
  153. #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. centos 7.0 查看根目录下所有文件夹

    centos 7.0最小化安装 第一行是登录 [root@localhost ~]# [root@localhost ~]# cd ../ [root@localhost /]# ls bin dev ...

  2. NancyFx中使用自带的IOC容器

    /// <summary> /// Cors扩展 /// </summary> public static class IPipelinesExtensions { /// & ...

  3. ng-repeat指令使用详解

    ng-repeat指令使用详解 link: function(scope,element,attr) scope.$index: if(scope.$last == true){} attr['mng ...

  4. java调用存储过程

    在做java调用sqlserver存储过程时遇到了各种各样的问题,不过在不懈的努力之下这些问题还是得以解决了.今天总结一下遇到的问题以及解决的方法. 首先调用存储过程的方法大家都很清楚: String ...

  5. MySql循环插入数据(定义了存储过程)

    MySQL一窍不通啊,今天工作上需要用到,请教了别人,做以备忘 DROP PROCEDURE test_insert ; DELIMITER ;; CREATE PROCEDURE test_inse ...

  6. java.lang.reflect.Constructor

    java.lang.reflect.Constructor 一.Constructor类是什么 Constructor是一个类,位于java.lang.reflect包下. 在Java反射中 Cons ...

  7. 优化PHP程序的方法(温故知新)

    1. If a method c++an be static, declare it static. Speed improvement is by a factor of 4. 如果一个方法可静态化 ...

  8. SQL Server 2012不支持从SQL Server 2000的备份进行还原

    错误: dbbackup failed: Unable to restore database 'ppt'Not valid backupThe database was backed up on a ...

  9. 利用Node.js对某智能家居服务器重构

    原文摘自我的前端博客,欢迎大家来访问 http://www.hacke2.cn 之前负责过一个智能家居项目的开发,外包重庆一家公司的,我们主要开发服务器监控和集群版管理. 移动端和机顶盒的远程通信是用 ...

  10. SQL 获取查询IO信息

    DBCC DROPCLEANBUFFERS --清空缓存 SET STATISTICS IO ON --开启IO统计 SET STATISTICS TIME ON -- 开启耗时统计 <code ...