读书笔记:“集体智慧编程”之第二章:推荐算法

什么是推荐?

推荐,就是根据个人偏好,对某个人进行个性化推荐。

  • 在线购物的商品推荐
  • 热门网站的推荐
  • 音乐推荐
  • 电影、电视的推荐
推荐的依据主要来自每个人过去的操作:购买、评分、评论。对这些过去的数据利用算法进行处理,就能得到这个人的偏好、甚至产生值得推荐的产品。

通常,我们会询问朋友有什么好看的电影,当然正常人都会询问和自己有着相同爱好的人。那么有一种算法叫做协同过滤:就是找到和目标用户有着相同爱好的人,然推荐给目标用户,这些有相同爱好的人喜欢的物品。本文主要就是讲这个算法。


推荐电影的例子


下面,我们通过一个实际的小例子来完成这个过程,这个例子是关于用户电影的。

用户的历史操作


完成协同过滤这个算法的第一步就是你要知道谁喜欢什么。本例子中,不仅知道哪个用户喜欢哪个电影,并且还用具体的数字来量化了,也就是每人对电影的有着评分。用一个字典表示,具体代码如下:
#一个字典,第一个key是人名,value是又是一个字典,字典里面是key电影名,value是评分   
critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 
 'The Night Listener': 3.0},
'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 
 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, 
 'You, Me and Dupree': 3.5}, 
'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,
 'Superman Returns': 3.5, 'The Night Listener': 4.0},
'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,
 'The Night Listener': 4.5, 'Superman Returns': 4.0, 
 'You, Me and Dupree': 2.5},
'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 
 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,
 'You, Me and Dupree': 2.0}, 
'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},
'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}

用数字来代表行为是一个非常关键的手段。这样才编程的进行运行,如下图所示:

基于用户的协同过滤

协同过滤:就是找到和目标用户有着相同爱好的人,然推荐给目标用户,这些有相同爱好的人喜欢的物品。本文主要就是讲这个算法。


计算用户相似度


那么现在我们已经有了用户数据了,下一步就是:找出爱好相同的用户。专业术语:寻找相近用户或者相似度高的用户。下面介绍三种计算相似度的体系:

  • 欧几里得距离
  • 皮尔逊相关度
  • Tanimoto系数

欧几里得距离


首先是欧几里得距离:
实际上,欧几里得距离非常直观,对于某两部电影,所有的用户都对其有着评分,我们以一个电影为x轴、一个电影为y轴,将每个人的对两个电影的评分画在坐标系中,直接考察每对用户的直线距离,距离近的相似度高。比如电影:dupree和snake,可以画出的图如下所示:



虽然这幅图只使用了二维坐标系,但实际上三维、四维都是同样的道理。
求两点间直线的距离,我相信大家都知道怎么算吧?三维、四维、n维的其实和二维的一个道理,都是两点差的平方和,再开方。注意:两点是指两个用户。在二维中就有x,y轴两个差值的平方和,而在n维中,就是n个差值的平方和。在本题中,对于两用户,必须是共同评过分的电影才有计算的意义。求出平方和再开方就是直线距离了。现在两用户越相邻距离越小,但是我们希望得到的是用户越相邻,数值越大,(0-1之间),故我们对最后的结果加1再求倒数就可以了。试想:如果两点重合,距离为1,再求倒数则是0被除,所以必须要加一。而如果两点距离越远,求倒数后值越小,符合我们的要求。解释清楚之后,让我们来看一看代码:

from math import sqrt
#利用欧几里得计算两个人之间的相似度
def sim_distance(prefs,person1,person2):
    #首先把这个两个用户共同拥有评过分电影给找出来,方法是建立一个字典,字典的key电影名字,电影的值就是1
    si={}
    for item in prefs[person1]:
        if item in prefs[person2]:
            si[item]=1
    #如果亮着没有共同之处
    if len(si)==0:return 0


    #计算所有差值的平方和
    sum_of_squares=sum([pow(prefs[person1][item]-prefs[person2][item],2) for item in prefs[person1] if item in prefs[person2]])


    return 1/(1+sqrt(sum_of_squares))


print sim_distance(critics,'Lisa Rose','Claudia Puig')

最后一句代码可以计算两个实例。


皮尔逊相关度评价

下面介绍的是皮尔逊相关度评价。用图里讲是非常清晰的,我们用某两个用户作为x、y轴,然后以用户对电影的评分,画出每一点来。如下图所示:


图中superman电影的坐标为(3.0,5.0),这是因为用户Gene Seymour对其的评分为5,而mick lasalle的评分为3.考虑所有的点:我们画一条线,叫最佳拟合线:画的原则是尽可能地靠近图中所有的坐标点。就是上图的线,试想一种情况就是两个用户的评分完成一样,我们将得到一条线:所有点都在线上,而且线的角度是45度。这时,两个用户的兴趣完全相同,我们称之为1,我想别的拟合线与之对比即可看出差距吧。
我来看一种情况较好的时候:上图的相关系数为0.4,下图为0.75



上述这么多有点讲出了推导原理的感觉,我们但是实际上我们求的就是皮尔逊相关系数,这是一个数学上的公式,其最后得到的结果是一个-1到1的之间的小数。-1称之为负相关:表示一个变量的值越大,另一个变量的值会反而越来越小。计算过程首先要找出两位评论者曾经评价过的物品,然后计算两者的评分总和平方和,并求出评分的乘积之和。利用公式算出pearson相关系数,
公式如下:其中X和Y分别是个数相同的数组或者是列表(python),相当于算出了两个数组之间的perason相关度。



我们在本题的实际的应用中也是如此,我们算的时候,是根据两个用户对电影的打分来计算的,打分组成了数组列表。
请看代码:

#返回两个人的皮尔逊相关系数
def sim_pearson(prefs,p1,p2):


    si={}
    for item in prefs[p1]:
        if item in prefs[p2]: si[item]=1


    #得到列表元素的个数
 
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值