机器学习——基于协同过滤推荐系统

本文深入探讨了基于用户和物品的协同过滤推荐算法原理及应用,通过实例展示了算法的计算流程,介绍了算法优缺点,适合对个性化推荐系统感兴趣的读者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于用户人口属性和行为数据设计的推荐算法,称为协同过滤算法。此方法主要根据用户的历史行为,寻找用户或物品的近邻集合,以此计算用户对物品的偏好,包括基于领域,图,关联规则,知识的推荐算法,其中最广泛应用是基于领域的方法,在实践中往往是上述几种方法的混合应用。

基于领域的推荐算法

基于领域的推荐算法主要包含两种:基于用户的协同过滤算法(UserCF)和基于物品的协同过滤算法(ItemCF)基于用户的协同过滤计算用户感兴趣相似度,基于物品的协同过滤算法计算与用户偏好的物品相似的物品。

(1)基于领域的推荐算法

基于酸奶的协同过滤算法为用户推荐兴趣相似的其他用户喜欢的物品。算法的关键是计算两个用户的兴趣相似度。计算用户相似度的常用方法有余弦相似性,皮尔森系数和修正的余弦相似性。

算法步骤如下:

  1. 找到与目标用户兴趣相似的用户集合;
  2. 找到这个集合中的用户喜欢的,且目标用户没有用过的物品,推荐给目标用户。

下面举一个简单的例子说明

下表是基于用户的协同过滤推荐示例,可以看到用户阿与用户Ç所喜欢的物品具有较多的交集,即两个用户具有相似性,那么用户Ç喜欢的物品很有可能用户甲也会喜欢,而用户ç喜欢物品d,则可以向用户甲推荐物品D.

用户/物品物品一个物品乙物品ç物品d
用户一 X X推荐
用户乙 X  
用户çX X

X

 

计算用户兴趣相似度时,要避免热门物品自带马太效应的影响,即大部分用户可能都对热门的物品表现出喜欢的状况,但是这些用户之间并非一类人,因为所谓的热门物品区分度较弱。

基于用户的协同过滤算法的缺点是随着用户数目增大,计算用户兴趣相似度越来越复杂,时间和空间复杂度与用户数接近于平方关系。所以一般采用离线方式进行推荐,即当用户产生新的行为时,不会立即进行计算,所以推荐结果并不会马上发生变化。此外,这一算法是基于隐式群体的兴趣进行推荐,可解释性不强。这一算法适用于用户数据比较稳定的场景,即通过群体的兴趣来代表用户个体的兴趣,一旦群体的兴趣确立,就可以认为个体用户服从此兴趣,由此向其进行推荐,结果一般较准确。

(2)基于物品的协同过滤算法

基于物品的协同过滤算法是依据用户喜欢的物品向其推荐与之相似的其他物品,属于基础的推荐算法,集成在各类电商平台的推荐系统中。与基于内容的推荐算法相比,该。算法是通过用户的行为计算物品之间的相似度而基于内容的推荐算法计算用户喜欢的物品的内容共同特征,作为用户的偏好描述,然后寻找与此特征相似的其他物品。

下面举一个简单的例子说明一下

两个物品是相似的,可能是因为它们共同被很多用户喜欢,也就是说,每个用户都可以通过其历史兴趣列表给物品“贡献”相似度。下表中用户对物品甲和物品乙都表现了相同的用户行为,即喜欢这两种物品,而且这两种物品与物品d具有一定的相似性(某些属性取值相同或相近),那么可以向用户推荐物品D.

用户/物品物品一个物品乙物品ç物品d
用户1X  X
用户2XX 推荐
用户3X XX

基于物品的协同推荐在物品数量较少时,物品间相似度的计算量不大,主要应用于长尾物品领域,在用户行为较少时,只要用户有少数点击行为就可以向其推荐相似的物品,所以可以用于解决用户冷启动问题,并且这一过程是基于用户的向其推荐的,推荐结果的可解释性较好。

下面写一个电影的推荐系统代码如下:

  1. #!/usr/bin/python
  2. # -*- coding: UTF-8 -*-
  3. '''
  4. 基于用户的推荐算法
  5. '''
  6. from math import sqrt,pow
  7. import operator
  8. class UserCf():
  9. #获得初始化数据
  10. def __init__(self,data):
  11. self.data=data
  12. #通过用户名获得电影列表,仅调试使用
  13. def getItems(self,username1,username2):
  14. return self.data[username1],self.data[username2]
  15. #计算两个用户的皮尔逊相关系数
  16. def pearson(self,user1,user2):#数据格式为:电影,评分 {'Snakes on a Plane': 4.5, 'You, Me and Dupree': 1.0, 'Superman Returns': 4.0}
  17. sumXY=0.0
  18. n=0
  19. sumX=0.0
  20. sumY=0.0
  21. sumX2=0.0
  22. sumY2=0.0
  23. try:
  24. for movie1,score1 in user1.items():
  25. if movie1 in user2.keys():#计算公共的电影的评分
  26. n+=1
  27. sumXY+=score1*user2[movie1]
  28. sumX+=score1
  29. sumY+=user2[movie1]
  30. sumX2+=pow(score1,2) #score1的平方
  31. sumY2+=pow(user2[movie1],2)
  32. molecule=sumXY-(sumX*sumY)/n
  33. denominator=sqrt((sumX2-pow(sumX,2)/n)*(sumY2-pow(sumY,2)/n))
  34. r=molecule/denominator
  35. except Exception as e:
  36. print ("异常信息:",e.message)
  37. return None
  38. return r
  39. #计算与当前用户的距离,获得最临近的用户
  40. def nearstUser(self,username,n=1):
  41. distances={}#用户,相似度
  42. for otherUser,items in self.data.items():#遍历整个数据集n
  43. if otherUser not in username:#非当前的用户
  44. distance=self.pearson(self.data[username],self.data[otherUser])#计算两个用户的相似度
  45. distances[otherUser]=distance
  46. sortedDistance=sorted(distances.items(),key=operator.itemgetter(1),reverse=True)#最相似的N个用户
  47. print ("排序后的用户为:",sortedDistance)
  48. return sortedDistance[:n]
  49. #给用户推荐电影
  50. def recomand(self,username,n=1):
  51. recommand={}#待推荐的电影
  52. for user,score in dict(self.nearstUser(username,n)).items():#最相近的n个用户
  53. print ("推荐的用户:",(user,score))
  54. for movies,scores in self.data[user].items():#推荐的用户的电影列表
  55. if movies not in self.data[username].keys():#当前username没有看过
  56. print ("%s为该用户推荐的电影:%s"%(user,movies))
  57. if movies not in recommand.keys():#添加到推荐列表中
  58. recommand[movies]=scores
  59. return sorted(recommand.items(),key=operator.itemgetter(1),reverse=True)#对推荐的结果按照电影评分排序
  60. if __name__=='__main__':
  61. users = {'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
  62. 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5,
  63. 'The Night Listener': 3.0},
  64. 'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5,
  65. 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0,
  66. 'You, Me and Dupree': 3.5},
  67. 'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,
  68. 'Superman Returns': 3.5, 'The Night Listener': 4.0},
  69. 'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,
  70. 'The Night Listener': 4.5, 'Superman Returns': 4.0,
  71. 'You, Me and Dupree': 2.5},
  72. 'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
  73. 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,
  74. 'You, Me and Dupree': 2.0},
  75. 'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
  76. 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},
  77. 'Toby': {'Snakes on a Plane': 4.5, 'You, Me and Dupree': 1.0, 'Superman Returns': 4.0}
  78. }
  79. userCf=UserCf(data=users)
  80. recommandList=userCf.recomand('Toby', 2)
  81. print ("最终推荐:%s"%recommandList)

运行结果如下:

				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									if(typeof window.localStorage === "object" && typeof window.csdn.anonymousUserLimit === "object"){
										if(!window.csdn.anonymousUserLimit.judgment()){
											window.csdn.anonymousUserLimit.Jumplogin();
											return false;
										}else if(!currentUserName){
											window.csdn.anonymousUserLimit.updata();
										}
									}
									
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值