集体智慧编程 第二章 提供推荐
2016-12-29 17:29
309 查看
我们要知道在购物网站中,如何构建一个系统,用以寻找具有相同品味的人,并根据他人的喜好自动给出推荐。
一个协作型过滤算法通常的做法是对一大群人进行搜索,并从中找到与我们品味相近的一小群人。算法会对这些人所偏爱的其他内容进行考察,并将它们组合起来构造出一个经过排名的推荐列表。
搜集偏好
第一件事是寻找一种表达不同人和偏好的方法,这里用Python的嵌套字典来达到目的。
新建一个名为 recommendations.py 的文件,加入如下代码构造一个数据集:
同样的,如果我们正在架设一个购物网站,不妨用数字 1 来代表有人过去曾购买过某件商品,用数字 0 来代表未曾购买过任何商品。而对于一个新闻网站可以用 -1 、 0 、1 来代表不喜欢、没有投票、喜欢。
写一个 run1.py 来运行程序:
另外:
这句话似乎没什么意义,因为本来字典里面也是 4.5 的评分。
====================================================================================
寻找相近的用户
搜集完偏好数据以后,我们需要有一种方法确定人们在品味方面的相似度。为此,我们可以将每个人与所有其他人进行对比,并计算他们的相似度评价值。这里有两种体系:欧几里得距离和皮尔逊相关度。
欧几里得距离评价:它以经过人们一致评价的物品为坐标轴,然后将参与评价的人绘制到地图上,并考查他们彼此间的距离远近。
就这样简单,两个人的“距离”越近,偏好就越相似。
比如 Toby 和 LaSalle
这个新函数总是返回介于 0 到 1 之间的数值,返回 1 表示两人有一样的偏好。
在 recommendations.py 里面加入代码:
改变 run1 文件:
结果:
这个 0.294298055086 就是两者的相似度评价。
皮尔逊相关度评价:该相关系数是判断两组数据与某一直线拟合程度的一种度量。
Mick给《Superman》打了3分,Gene打了5分,所以我们把这个影片定位在(3,5)处。这样定位完毕以后,作一条线性回归线就行了。这条线称为“最佳拟合线”。
皮尔逊相关度评价算法首先会找出两位评论者都曾评价过的物品,然后计算两者评分总和与平方和,并求得评分的乘积之和。
在之前的代码里面添加:
运行函数里面写上:
结果:
==========================================================================
现在的问题是:应该用哪一种相似性度量方法?
其实这是个统计学问题,以后还会遇到Jaccard系数或者曼哈顿距离算法。只能说具体情况具体分析
=========================================================================================
为评论者打分
我们有了两个人进行比较的函数,下面就可以根据指定人员对每个人打分,找出最接近的匹配结果。
添加代码:
给出全部运行程序:
结果:
===========================================================
推荐物品
我们想要的其实是影片的推荐。
表中列出了每位评论者的相关度评价值,以及他们对三部影片的评分情况。以S.x开头的列是乘以评价值之后的相似度。如此一来,与我们相近的人对整体评价值有更多的贡献。
同时还要考虑到,一部受更多人评论的影片会对结果有更大影响,也要修正这个问题。
在代码里面加入:
需要说明的是,这里要注意列表推导式这个东西,百度一下格式和用法。
然后运行里面添加:
结果:
这里不仅得到了一个经过排名的影片列表,还推测除了自己对每部影片的评价情况。
电影推荐到此为止,下一章是商品推荐。
一个协作型过滤算法通常的做法是对一大群人进行搜索,并从中找到与我们品味相近的一小群人。算法会对这些人所偏爱的其他内容进行考察,并将它们组合起来构造出一个经过排名的推荐列表。
搜集偏好
第一件事是寻找一种表达不同人和偏好的方法,这里用Python的嵌套字典来达到目的。
新建一个名为 recommendations.py 的文件,加入如下代码构造一个数据集:
# -*- coding:utf-8 -*- # 集体智慧编程 第二章 # recommendations.py #下列字典使用 1 到 5 的评分,体现包括本人在内的每位影评者对某一给定影片的喜爱程度 critics = {'Lisa Rose':{'Lady in the Water':2.5, 'Snake 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, 'Snake 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, 'Snake on a Plane':3.0, 'Superman Returns':3.5, 'The Night Listener':4.0}, 'Claudia Puig':{'Snake 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, 'Snake 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, 'Snake on a Plane':4.0, 'The Night Listener':3.0, 'Superman Returns':5.0, 'You, Me and Dupree':3.5}, 'Toby':{'Snake on a Plane':4.5, 'You, Me and Dupree':1.0, 'Superman Returns':4.0}}
同样的,如果我们正在架设一个购物网站,不妨用数字 1 来代表有人过去曾购买过某件商品,用数字 0 来代表未曾购买过任何商品。而对于一个新闻网站可以用 -1 、 0 、1 来代表不喜欢、没有投票、喜欢。
写一个 run1.py 来运行程序:
# run recommendations.py from recommendations import critics print critics['Lisa Rose']['Lady in the Water'] critics['Toby']['Snakes on a Plane'] = 4.5 print critics['Toby']结果:
另外:
critics['Toby']['Snakes on a Plane'] = 4.5
这句话似乎没什么意义,因为本来字典里面也是 4.5 的评分。
====================================================================================
寻找相近的用户
搜集完偏好数据以后,我们需要有一种方法确定人们在品味方面的相似度。为此,我们可以将每个人与所有其他人进行对比,并计算他们的相似度评价值。这里有两种体系:欧几里得距离和皮尔逊相关度。
欧几里得距离评价:它以经过人们一致评价的物品为坐标轴,然后将参与评价的人绘制到地图上,并考查他们彼此间的距离远近。
就这样简单,两个人的“距离”越近,偏好就越相似。
比如 Toby 和 LaSalle
from math import sqrt 1/(1+sqrt(pow(4.5-4,2) + pow(1-2,2)))
这个新函数总是返回介于 0 到 1 之间的数值,返回 1 表示两人有一样的偏好。
在 recommendations.py 里面加入代码:
from math import sqrt # 返回一个有关 person1 和 person2 的基于距离的相似度评价 def sim_distance(prefs, person1, person2): #得到 shared_items 的列表 si={} for item in prefs[person1]: if item in prefs[person2]: si[item] = 1 # 如果没有共同之处,返回 0 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))
改变 run1 文件:
# run recommendations.py import recommendations from recommendations import critics print critics['Lisa Rose']['Lady in the Water'] critics['Toby']['Snakes on a Plane'] = 4.5 print critics['Toby'] print '==========================================' import recommendations print recommendations.sim_distance(recommendations.critics,'Lisa Rose','Gene Seymour')
结果:
这个 0.294298055086 就是两者的相似度评价。
皮尔逊相关度评价:该相关系数是判断两组数据与某一直线拟合程度的一种度量。
Mick给《Superman》打了3分,Gene打了5分,所以我们把这个影片定位在(3,5)处。这样定位完毕以后,作一条线性回归线就行了。这条线称为“最佳拟合线”。
皮尔逊相关度评价算法首先会找出两位评论者都曾评价过的物品,然后计算两者评分总和与平方和,并求得评分的乘积之和。
在之前的代码里面添加:
# 返回 p1 和 p2 的皮尔逊相关系数 def sim_pearson(prefs, p1, p2): # 得到双方都曾评价过的物品列表 si = {} for item in prefs[p1]: if item in prefs[p2]:si[item] = 1 # 得到 si 列表元素的个数 n = len(si) # 如果两者没有共同之处,返回 1 if n == 0:return 1 # 对所有偏好求和 sum1 = sum([prefs[p1][it] for it in si]) sum2 = sum([prefs[p2][it] for it in si]) # 求平方和 sum1Sq = sum([pow(prefs[p1][it], 2) for it in si]) sum2Sq = sum([pow(prefs[p2][it], 2) for it in si]) # 求乘积和 pSum = sum([prefs[p1][it] * prefs[p2][it] for it in si]) # 计算皮尔逊评价值 num = pSum - (sum1 * sum2 /n) den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n)) if den == 0:return 0 r = num/den return r
运行函数里面写上:
print '==========================================' print 'sim_pearson' print recommendations.sim_pearson(recommendations.critics,'Lisa Rose','Gene Seymour')
结果:
==========================================================================
现在的问题是:应该用哪一种相似性度量方法?
其实这是个统计学问题,以后还会遇到Jaccard系数或者曼哈顿距离算法。只能说具体情况具体分析
=========================================================================================
为评论者打分
我们有了两个人进行比较的函数,下面就可以根据指定人员对每个人打分,找出最接近的匹配结果。
添加代码:
# 从反映偏好的字典中返回最为匹配者 # 返回结果的个数和相似度函数均为可选参数 def topMatches(prefs, person, n = 5, similarity = sim_pearson): scores = [(similarity(prefs, person, other), other)for other in prefs if other != person] # 参见列表推导式 # 对列表排序,评价值最高的排在前面 scores.sort() # 排序 scores.reverse() # 反向列表中元素 return scores[0:n]
给出全部运行程序:
# run recommendations.py import recommendations from recommendations import critics print critics['Lisa Rose']['Lady in the Water'] critics['Toby']['Snakes on a Plane'] = 4.5 print critics['Toby'] print '\n==========================================' print 'sim_distance' print recommendations.sim_distance(recommendations.critics,'Lisa Rose','Gene Seymour') print '\n==========================================' print 'sim_pearson' print recommendations.sim_pearson(recommendations.critics,'Lisa Rose','Gene Seymour') print '\n==========================================' print 'topMatches' print recommendations.topMatches(recommendations.critics,'Toby', n = 3)
结果:
===========================================================
推荐物品
我们想要的其实是影片的推荐。
表中列出了每位评论者的相关度评价值,以及他们对三部影片的评分情况。以S.x开头的列是乘以评价值之后的相似度。如此一来,与我们相近的人对整体评价值有更多的贡献。
同时还要考虑到,一部受更多人评论的影片会对结果有更大影响,也要修正这个问题。
在代码里面加入:
# 利用所有他人评价值的加权平均,为某人提供建议 def getRecommendations(prefs,person,similarity = sim_pearson): totals = {} simSums = {} for other in prefs: # 不要和自己作比较 if other ==person: continue sim = similarity(prefs, person, other) #忽略评价值为零或小于零的情况 if sim <= 0: continue for item in prefs[other]: #只对自己还没看过的影片评价 if item not in prefs[person] or prefs[person][item] == 0: # 相似度 * 评价值 totals.setdefault(item, 0) # setdefault() 函数: 如果键不已经存在于字典中,将会添加键并将值设为默认值。 # dict.setdefault(key, default=None) # key -- 查找的键值。 # default -- 键不存在时,设置的默认键值。 totals[item] += prefs[other][item] * sim # 相似度之和 simSums.setdefault(item, 0) simSums[item] += sim # 建立一个归一化的列表 rankings = [(total / simSums[item], item) for item, total in totals.items()] # 列表推导式 # 返回经过排序的列表 rankings.sort() rankings.reverse() return rankings
需要说明的是,这里要注意列表推导式这个东西,百度一下格式和用法。
然后运行里面添加:
print '\n==========================================' print 'getRecommendations.sim_pearson' print recommendations.getRecommendations(recommendations.critics, 'Toby') print '\n==========================================' print 'getRecommendations.sim_distance' print recommendations.getRecommendations(recommendations.critics, 'Toby',\ similarity = recommendations.sim_pearson)
结果:
这里不仅得到了一个经过排名的影片列表,还推测除了自己对每部影片的评价情况。
电影推荐到此为止,下一章是商品推荐。
相关文章推荐
- 集体智慧编程----第二章 提供推荐(Making Recommendations)
- 【集体智慧编程】第二章、提供推荐
- 【集体智慧编程】提供推荐
- Spark实现 集体智慧编程 第二章电影推荐
- 7.12-集体智慧编程-笔记-提供推荐--未完
- 【转】读书笔记:“集体智慧编程”之第二章:推荐算法——协同滤波
- 集体智慧编程(一)提供推荐
- 集体智慧编程chapter 2提供推荐<寻找相似性的用户>
- 集体智慧编程(2)——提供推荐
- 【集体智慧编程】【Python3】【读书笔记1】提供推荐
- 8.14-集体智慧编程-4-提供推荐--未完
- 集体智慧编程——提供推荐
- 集体智慧编程笔记:物品推荐过程小结
- 集体编程智慧代码摘抄【第二章】
- 集体智慧编程--推荐系统
- 【集体智慧编程 学习笔记】 推荐系统构建
- programming collective intelligence(集体智慧编程)第二章python3.x安装pydelicious
- 集体智慧编程_推荐系统
- 集体智慧编程:第二章,推荐算法
- “集体智慧编程”之第二章:推荐算法