`
zhangyi0618
  • 浏览: 62003 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

《推荐系统》基于用户和Item的协同过滤算法的分析与实现(Python)(转)

 
阅读更多

http://blog.csdn.net/gamer_gyt/article/details/51684716  原文

 

1:协同过滤算法简介

2:协同过滤算法的核心

3:协同过滤算法的应用方式

4:基于用户的协同过滤算法实现

 

5:基于物品的协同过滤算法实现

 

一:协同过滤算法简介

    关于协同过滤的一个最经典的例子就是看电影,有时候不知道哪一部电影是我们喜欢的或者评分比较高的,那么通常的做法就是问问周围的朋友,看看最近有什么好的电影推荐。在问的时候,都习惯于问跟自己口味差不 多的朋友,这就是协同过滤的核心思想。

 

   协同过滤是在海量数据中挖掘出小部分与你品味类似的用户,在协同过滤中,这些用户成为邻居,然后根据他们喜欢的东西组织成一个排序的目录推荐给你。所以就有如下两个核心问题

   (1)如何确定一个用户是否与你有相似的品味?

   (2)如何将邻居们的喜好组织成一个排序目录?

   协同过滤算法的出现标志着推荐系统的产生,协同过滤算法包括基于用户和基于物品的协同过滤算法。

 

二:协同过滤算法的核心

      要实现协同过滤,需要进行如下几个步骤 

      1)收集用户偏好

      2)找到相似的用户或者物品

      3)计算并推荐

 

三:协同过滤算法的应用方式

1:基于用户的协同过滤算法   

基于用户的协同过滤通过不同用户对物品的评分来评测用户之间的相似性,基于用户的相似性做推荐,简单的讲:给用户推荐和他兴趣相投的其他用户喜欢的物品

算法实现流程分析:

(1):计算用户的相似度

计算用户相似度的方法请参考这篇博客:点击阅读  这里我采用的是余弦相似度

下面我拿这个图举例

     

计算用户的相似度,例如A,B为

同理

         但是这样计算的效率是低的,因为我们需要计算每一对用户之间的相似度,事实上,很多用户相互之间并没有对同样的物品产生过行为,所以很多时候当分子为0的时候没有必要再去计算分母,所以这里可以优化:即首先计算出|N(u) 并 N(v)| != 0 的用户对(u,v),然后对这种情况计算分母以得到两个用户的相似度。

 

针对此优化,需要2步:

     (1)建立物品到用户的倒查表T,表示该物品被哪些用户产生过行为;

     (2)根据倒查表T,建立用户相似度矩阵W:在T中,对于每一个物品i,设其对应的用户为j,k,在W中,更新相应的元素值,w[j][k]=w[j][k]+1,w[k][j]=w[k][j]+1,以此类推,扫描完倒查表T中的所有物品后,就可以得到最终的用户相似度矩阵W,这里的W是余弦相似度中的分子部分,然后将W除以分母可以得到最终的用户兴趣相似度。

得到用户的相似度后,便可以进行下一步了

 

(2):给用户推荐兴趣最相近的k个用户所喜欢的物品

公式如下:

其中,p(u,i)表示用户u对物品i的感兴趣程度,S(u,k)表示和用户u兴趣最接近的K个用户,N(i)表示对物品i有过行为的用户集合,Wuv表示用户u和用户v的兴趣相似度,Rvi表示用户v对物品i的兴趣(这里简化,所有的Rvi都等于1)。

根据UserCF算法,可以算出,用户A对物品c、e的兴趣是:

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

基于item的协同过滤通过不同用户对不同item的评分来评测item之间的相似性,基于item的相似性做推荐,简单的讲:给用户推荐和他之前喜欢物品相似的物品

算法流程分析:

同样拿上边的图举例,在这里默认用户对物品的打分均为1

(1):构建物品的同现矩阵

在这里对矩阵做归一化处理就可以得到物品之间的余弦相似度矩阵了其中归一化处理

按照标准定义

这里,分母|N(i)|是喜欢物品i的用户数,而分子 N(i) N( j) 是同时喜欢物品i和物品j的用户数。因此,上述公式可以理解为喜欢物品i的用户中有多少比例的用户也喜欢物品j。

 

进行处理后的结果为:

当然为了出现推荐热门的商品,对上述公式的优化为:

这个公式惩罚了物品j的权重,因此减轻了热门物品会和很多物品相似的可能性(此种情况下感兴趣的自己推导)。

 

(2):建立用户对物品的评分矩阵(以A举例,没有评分的物品为0)

 

(3):矩阵计算推荐结果


这里N(u)是用户喜欢的物品的集合,S(j,K)是和物品j最相似的K个物品的集合,wji是物品j和i的相似度,rui是用户u对物品i的兴趣。(对于隐反馈数据集,如果用户u对物品i有过行为,即可令rui=1。)该公式的含义是,和用户历史上感兴趣的物品越相似的物品,越有可能在用户的推荐列表中获得比较高的排名。

推荐结果=同现矩阵 * 评分矩阵

从中去掉A已经打过分的物品,a,b,d,则可以看出,A对e的喜欢程度和c一样,和上边计算结果一致,所以就会将两者推荐给A

3:混合推荐

 

所谓的混合算法,主体思路还是基于用户的协同过滤,只是在计算两个用户的相似度时又嵌套了item-based CF思想。

度量用户i和用户j相似度更好的方法是:

1.用户i参与评分的项目集合为IiIi,用户j参与评分的项目集合为IjIj,找到它们的并集Uij=IiIjUij=Ii∪Ij

2.在集合UijUij中用户i未评分的项目是Ni=UijIiNi=Uij−Ii,采用item-based CF方法重新估计用户i对NiNi中每个项目的评分。

3.这样用户i和j对UijUij的评分就都是非0值了,在此情况下计算他们的相似度。

四:基于用户的协同过滤算法实现

 

[python] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. #-*-coding:utf-8-*-  
  2. ''''' 
  3. Created on 2016年5月2日 
  4.  
  5. @author: Gamer Think 
  6. '''  
  7. from math import sqrt  
  8.   
  9. fp = open("uid_score_bid","r")  
  10.   
  11. users = {}  
  12.   
  13. for line in open("uid_score_bid"):  
  14.     lines = line.strip().split(",")  
  15.     if lines[0not in users:  
  16.         users[lines[0]] = {}  
  17.     users[lines[0]][lines[2]]=float(lines[1])  
  18.   
  19.   
  20. #----------------新增代码段END----------------------  
  21.   
  22.   
  23.   
  24. class recommender:  
  25.     #data:数据集,这里指users  
  26.     #k:表示得出最相近的k的近邻  
  27.     #metric:表示使用计算相似度的方法  
  28.     #n:表示推荐book的个数  
  29.     def __init__(self, data, k=3, metric='pearson', n=12):  
  30.   
  31.         self.k = k  
  32.         self.n = n  
  33.         self.username2id = {}  
  34.         self.userid2name = {}  
  35.         self.productid2name = {}  
  36.   
  37.         self.metric = metric  
  38.         if self.metric == 'pearson':  
  39.             self.fn = self.pearson  
  40.         if type(data).__name__ == 'dict':  
  41.             self.data = data  
  42.         
  43.     def convertProductID2name(self, id):  
  44.   
  45.         if id in self.productid2name:  
  46.             return self.productid2name[id]  
  47.         else:  
  48.             return id  
  49.   
  50.     #定义的计算相似度的公式,用的是皮尔逊相关系数计算方法  
  51.     def pearson(self, rating1, rating2):  
  52.         sum_xy = 0  
  53.         sum_x = 0  
  54.         sum_y = 0  
  55.         sum_x2 = 0  
  56.         sum_y2 = 0  
  57.         n = 0  
  58.         for key in rating1:  
  59.             if key in rating2:  
  60.                 n += 1  
  61.                 x = rating1[key]  
  62.                 y = rating2[key]  
  63.                 sum_xy += x * y  
  64.                 sum_x += x  
  65.                 sum_y += y  
  66.                 sum_x2 += pow(x, 2)  
  67.                 sum_y2 += pow(y, 2)  
  68.         if n == 0:  
  69.             return 0  
  70.           
  71.         #皮尔逊相关系数计算公式   
  72.         denominator = sqrt(sum_x2 - pow(sum_x, 2) / n)  * sqrt(sum_y2 - pow(sum_y, 2) / n)  
  73.         if denominator == 0:  
  74.             return 0  
  75.         else:  
  76.             return (sum_xy - (sum_x * sum_y) / n) / denominator  
  77.       
  78.     def computeNearestNeighbor(self, username):  
  79.         distances = []  
  80.         for instance in self.data:  
  81.             if instance != username:  
  82.                 distance = self.fn(self.data[username],self.data[instance])  
  83.                 distances.append((instance, distance))  
  84.   
  85.         distances.sort(key=lambda artistTuple: artistTuple[1],reverse=True)  
  86.         return distances  
  87.       
  88.     #推荐算法的主体函数  
  89.     def recommend(self, user):  
  90.         #定义一个字典,用来存储推荐的书单和分数  
  91.         recommendations = {}  
  92.         #计算出user与所有其他用户的相似度,返回一个list  
  93.         nearest = self.computeNearestNeighbor(user)  
  94.         # print nearest  
  95.           
  96.         userRatings = self.data[user]  
  97. #         print userRatings  
  98.         totalDistance = 0.0  
  99.         #得住最近的k个近邻的总距离  
  100.         for i in range(self.k):  
  101.             totalDistance += nearest[i][1]  
  102.         if totalDistance==0.0:  
  103.             totalDistance=1.0  
  104.               
  105.         #将与user最相近的k个人中user没有看过的书推荐给user,并且这里又做了一个分数的计算排名  
  106.         for i in range(self.k):  
  107.               
  108.             #第i个人的与user的相似度,转换到[0,1]之间  
  109.             weight = nearest[i][1] / totalDistance  
  110.               
  111.             #第i个人的name  
  112.             name = nearest[i][0]  
  113.   
  114.             #第i个用户看过的书和相应的打分  
  115.             neighborRatings = self.data[name]  
  116.   
  117.             for artist in neighborRatings:  
  118.                 if not artist in userRatings:  
  119.                     if artist not in recommendations:  
  120.                         recommendations[artist] = (neighborRatings[artist] * weight)  
  121.                     else:  
  122.                         recommendations[artist] = (recommendations[artist]+ neighborRatings[artist] * weight)  
  123.   
  124.         recommendations = list(recommendations.items())  
  125.         recommendations = [(self.convertProductID2name(k), v)for (k, v) in recommendations]  
  126.           
  127.         #做了一个排序  
  128.         recommendations.sort(key=lambda artistTuple: artistTuple[1], reverse = True)  
  129.   
  130.         return recommendations[:self.n],nearest  
  131.    
  132. def adjustrecommend(id):  
  133.     bookid_list = []  
  134.     r = recommender(users)  
  135.     k,nearuser = r.recommend("%s" % id)  
  136.     for i in range(len(k)):  
  137.         bookid_list.append(k[i][0])  
  138.     return bookid_list,nearuser[:15]        #bookid_list推荐书籍的id,nearuser[:15]最近邻的15个用户  

 

 

数据集的格式如下(点击下载):


 

程序调用:

 

 

[python] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. bookid_list,near_list = adjustrecommend("changanamei")  
  2. print ("bookid_list:",bookid_list)  
  3. print ("near_list:",near_list)  

 

 

运行结果:

 

 

五:基于物品的协同过滤算法的实现

 

参考项亮的《推荐系统实战》结合上例中的数据进行算法实现

 

 

[python] view plain copy
 
 在CODE上查看代码片派生到我的代码片
  1. #-*-coding:utf-8-*-  
  2.   
  3. ''''' 
  4. Created on 2016-5-30 
  5.  
  6. @author: thinkgamer 
  7. '''  
  8. import math  
  9.   
  10. class ItemBasedCF:  
  11.     def __init__(self,train_file):  
  12.         self.train_file = train_file  
  13.         self.readData()  
  14.     def readData(self):  
  15.         #读取文件,并生成用户-物品的评分表和测试集  
  16.         self.train = dict()     #用户-物品的评分表  
  17.         for line in open(self.train_file):  
  18.             # user,item,score = line.strip().split(",")  
  19.             user,score,item = line.strip().split(",")  
  20.             self.train.setdefault(user,{})  
  21.             self.train[user][item] = int(float(score))  
  22.   
  23.     def ItemSimilarity(self):  
  24.         #建立物品-物品的共现矩阵  
  25.         C = dict()  #物品-物品的共现矩阵  
  26.         N = dict()  #物品被多少个不同用户购买  
  27.         for user,items in self.train.items():  
  28.             for i in items.keys():  
  29.                 N.setdefault(i,0)  
  30.                 N[i] += 1  
  31.                 C.setdefault(i,{})  
  32.                 for j in items.keys():  
  33.                     if i == j : continue  
  34.                     C[i].setdefault(j,0)  
  35.                     C[i][j] += 1  
  36.         #计算相似度矩阵  
  37.         self.W = dict()  
  38.         for i,related_items in C.items():  
  39.             self.W.setdefault(i,{})  
  40.             for j,cij in related_items.items():  
  41.                 self.W[i][j] = cij / (math.sqrt(N[i] * N[j]))  
  42.         return self.W  
  43.   
  44.     #给用户user推荐,前K个相关用户  
  45.     def Recommend(self,user,K=3,N=10):  
  46.         rank = dict()  
  47.         action_item = self.train[user]     #用户user产生过行为的item和评分  
  48.         for item,score in action_item.items():  
  49.             for j,wj in sorted(self.W[item].items(),key=lambda x:x[1],reverse=True)[0:K]:  
  50.                 if j in action_item.keys():  
  51.                     continue  
  52.                 rank.setdefault(j,0)  
  53.                 rank[j] += score * wj  
  54.         return dict(sorted(rank.items(),key=lambda x:x[1],reverse=True)[0:N])  
  55.       
  56. #声明一个ItemBased推荐的对象      
  57. Item = ItemBasedCF("uid_score_bid")  
  58. Item.ItemSimilarity()  
  59. recommedDic = Item.Recommend("xiyuweilan")  
  60. for k,v in recommedDic.iteritems():  
  61.     print k,"\t",v  

 

 

运行结果:

 

1080309     8.18161438413
1119522     11.8165100292
1040104     7.92927319995
1254588     12.8331124639
1082138     7.72409411532
3131626     11.3426906217
26669243     6.96972128519
26305561     6.24816554216
26384985     6.36064881658
1085799     8.20314297616

 

分享到:
评论

相关推荐

    基于Python的协同过滤算法的设计与实现.pdf

    在文档“基于Python的协同过滤算法的设计与实现.pdf”中,介绍了如何使用Python语言设计和实现协同过滤算法,重点强调了如何通过Python库Numpy来提高算法的时间和空间效率。 首先,协同过滤算法的关键在于计算物品...

    推荐系统基于用户和Item的协同过滤算法的分析与实现

    在推荐系统中,协同过滤算法是一种非常流行且有效的推荐技术,主要分为基于用户的协同过滤算法和基于物品的协同过滤算法。 1. 协同过滤算法简介: 协同过滤的基本思想是通过收集和分析用户的行为信息,找出与目标...

    基于协同过滤算法实现的图书推荐系统.zip

    - 使用Python的`scikit-surprise`库,它提供了多种协同过滤算法的实现,如User-Based和Item-Based CF。 - 数据处理和模型训练可以使用Pandas进行,模型预测则通过`surprise`库的内置函数完成。 - 还可以利用`...

    基于UserCF和ItemCF协同过滤算法的电影推荐系统python实现源码含项目使用说明.zip

    基于UserCF和ItemCF协同过滤算法的电影推荐系统python实现源码含项目使用说明.zip基于UserCF和ItemCF协同过滤算法的电影推荐系统python实现源码含项目使用说明.zip基于UserCF和ItemCF协同过滤算法的电影推荐系统...

    基于Python+Django协同过滤算法的电影推荐系统.zip

    基于Python+Django协同过滤算法的电影推荐系统.zip 基于 Python+Django 功能很全,常见的电影网站功能都有。 推荐算法方面是基于用户的协同过滤以及基于Item的协同过滤,同时结合电影点击次数、收藏人数、标签选择等...

    基于物品的协同过滤算法itemCF原理及python代码实现

    **基于物品的协同过滤算法(Item-based Collaborative Filtering, itemCF)**是一种广泛应用于推荐系统中的预测技术。它主要依赖于用户对物品的历史评价数据,通过寻找物品之间的相似性来预测用户可能对未评价物品的...

    基于python实现协同过滤算法CollaborativeFiltering

    总结,基于Python实现协同过滤算法涉及了数据预处理、相似度计算、推荐预测及系统评估等多个环节。通过使用如Surprise这样的库,我们可以快速搭建推荐系统并进行优化,以满足实际应用场景的需求。在实践中,不断调整...

    基于用户品协同过滤python

    在这个场景中,"基于用户品协同过滤python"指的是使用Python编程语言实现的一种用户之间的协同过滤算法。这种算法的核心思想是,如果两个用户在过去的评价或行为上有相似性,那么他们未来可能会对同一物品有类似的...

    基于用户或者物品协同过滤博客整理python

    ### 基于用户的协同过滤算法的Python实现 在推荐系统领域,协同过滤是一种非常流行的推荐算法,它根据用户的历史行为和其他用户的行为相似性来进行推荐。基于用户的协同过滤(User-based Collaborative Filtering, ...

    协同过滤算法 python脚本

    例如,Surprise库提供了一种简单的方式来构建和评估推荐系统,支持多种协同过滤算法。 在实际应用中,协同过滤算法还面临一些挑战,如冷启动问题(新用户或新物品没有足够的历史记录)、稀疏性问题(用户和物品的...

    基于用户协同过滤python

    `Surprise`是一个轻量级的Python推荐系统库,提供了多种协同过滤算法,包括基于用户的协同过滤。首先,我们需要安装这个库,可以通过`pip install surprise`命令完成。 接下来,我们将使用Movielens数据集,这是一...

    基于模型的协同过滤电影评分预测模型_springsnc_python预测_python_协作编辑Python_预测模型_

    在本项目中,开发人员可能使用了surprise库,这是一个专为推荐系统设计的Python库,提供了多种协同过滤算法的实现,包括User-Based和Item-Based CF。 在代码实现过程中,首先需要加载电影评分数据集,这通常包含...

    基于物品的协同过滤算法源码及数据集Python

    本文将深入探讨基于物品的协同过滤算法,并结合提供的Python源码,解析其实现细节。 协同过滤的基本思想是,如果两个用户在过去对某些物品的评分相近,那么他们可能对未来的物品也有相似的喜好。在基于物品的协同...

    Python基于协同过滤算法的电影推荐视频网站源码

    所以系统拟采用两种协 同过滤算法给出两种不同的推荐结果,一种是基于用户的协同过滤算法,另一种是基于物 品的协同过滤算法,用户可以根据两种推荐结果更加合理的选择合适的电影.系统采用了 改进之后的ItemCF-IUF和...

    基于协同过滤的推荐系统算法研究项目源码+论文.zip

    协同过滤算法研究 [摘要] 随着“大数据”的出现,人们在庞大的数据面前更是显得束手无策。信息过载的问题成为了让人们头疼的事情。社会信息超过了个人或系统所能接受、处理或有效利用的范围,并导致故障。当前要...

    Python基于协同过滤算法的电影推荐视频网站设计

    所以系统拟采用两种协 同过滤算法给出两种不同的推荐结果,一种是基于用户的协同过滤算法,另一种是基于物 品的协同过滤算法,用户可以根据两种推荐结果更加合理的选择合适的电影.系统采用了 改进之后的ItemCF-IUF和...

    基于python与协同过滤实现推荐算法

    推荐系统是现代在线服务的重要组成部分,它通过分析用户行为和兴趣来个性化地为用户提供内容或产品建议。在本项目中,我们将深入探讨如何利用Python语言和协同过滤(Collaborative Filtering)方法构建一个推荐系统...

    基于物品的协同过滤算法实现图书推荐系统.zip

    本项目主要关注的是基于物品的协同过滤算法(Item-Based Collaborative Filtering,简称ItemCF)在图书推荐系统中的实现,这是一种广泛应用于推荐系统中的方法,具有良好的预测性能和实用性。 协同过滤是一种基于...

Global site tag (gtag.js) - Google Analytics