本文只是对协同过滤的一个简单的知识总结,对该方面知识的学习,可参考《推荐系统实践》、《集体智慧编程》。这里并不给出原因,而只是一个该方面知识点的简单应用。通过这些简单的应用再反过来学习相关的知识点,应该能提升很大的兴趣。
先谈什么是机器学习:
机器学习:将一组数据传递给算法,并由算法推断出与这些数据的属性相关的信息——借助这些信息,算法就能够预测出未来有可能会出现的其他数据。
因为几乎所有的非随机数据中,都会包含这样或那样的“模式”,这些模式的存在使得机器得以据此进行归纳。为了实现归纳,机器会利用它所认定的出现于数据中的重要特征对数据进行“训练”,并借此得到一个模型。
什么是推荐系统:
如在线购物中的商品推荐、热门网站的推荐、以及帮助人们寻找音乐盒影片的应用。
什么是协同过滤Collaborative Filtering
对一大群人进行搜索,并从中找出与我们品位相近的一群人。算法会对这些人所偏爱的内容进行考察,并将它们组合起来构造出一个经过排名的推荐列表。
基于协同过滤算法构建一个推荐系统的过程:(Python实现)
1.收集偏好——可以使用一个嵌套的字典
2.寻找相近的用户
欧几里得距离
皮尔逊相关度
3.为评论者打分,并找到最接近的匹配结果
4.推荐物品
数据集:
一个可以用来做练习的数据集如下:
http://grouplens.org/datasets/movielens/
实例:
1.有如下数据集:描述的是一些用户对一些电影的评价
#list of movies
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}}
2.寻找相近的用户
这里需要计算的是不同人之间品位的相似程度。常用算法有欧几里德距离和皮尔逊相关度。(详细内容参考相关书籍)
计算方法这里不详述。
算法1:欧几里德距离
from math import sqrt
def sim_distance(prefs,person1,person2):
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))
这里对其加1并取倒数的原因是:避免遇到零整除的错误。
这样总能得到一个介于0到1之间的小数,数越大,表示偏好越相近
算法2:皮尔逊相关度:
皮尔逊相关系数用来判断两组数据与某一直线的拟合程度。
通过这种算法,首先会找出两位评论者都评价过的物品,然后计算两者的评分总和与平方和,并求得评分的乘积和。从而计算出皮尔逊相关系数。
def sim_pearson(prefs,p1,p2):
si = {}
for item in prefs[p1]:
if item in prefs[p2]: si[item]=1
n=len(si)
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
该函数返回一个介于-1到1之间的数值,越大越相似。
3.为评论者打分,得到相近的匹配结果
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]
上面对列表进行方向排序,使得相似度最高的排在前面。
4.推荐物品:
思想是:通过一个加权评价值(考虑到一些影片不同的质量,如收到越多的人评价的电影权重应该更高点)来为影片打分。
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)
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
通过上面这些步骤,可以构建出一个基本的推荐系统。我们所要做的只是:构建涉及人员、物品和评价值的字典,然后借此来为用户提供建议。
注:关于上面引用的代码的具体解释,可以参考 《集体智慧编程》一书。