步骤一:搜索偏好
我们要做的第一件事就是寻找表达不同人及其偏好的方法。在Python中,达到这一目的的一个非常简单有效的方式就是使用一个嵌套的字典。下面就是新建的一个名为recommendations.py的文件,加入如下代码实现一个数据集:
critics={'Lisa Rose':{'Lady in winter':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 winter':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 winter':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,'Superman returns':4.0,'The Night Listener':4.5,'You ,Me,and Dupree':2.5}, 'Mick LaSalle':{'Lady in winter':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 winter':3.0,'Snakes on a plane':4.0,'Superman returns':5.0,'The Night Listener':3.0,'You ,Me,and Dupree':3.5}, 'Toby':{'Snakes on a plane':4.5,'Superman returns':4.0,'You ,Me,and Dupree':1.0}}
其中数字表示不同的人对这部电影的评分。
启动python解释程序,并输入下面几行代码,可以看到数据集中的内容。
>>>import recommendations >>>critics['Lisa Rose']['Lady in Winter'] 2.5 >>>critics['Toby'] {'Snakes on a plane':4.5,'Superman returns':4.0,'You ,Me,and Dupree':1.0}}
步骤二:寻找相近用户
主要使用的是相似度评价值。这里主要有两种方式:欧几里德距离和皮尔逊相似度。
1.欧几里德距离:先计算每一轴上的差值,求平方后再相加,最后对总和取平方根。
将如下代码插入到recommendations中:
from math import sqrt def sim_distance(prefs,person1,preson2): si={} for item in prefs[person1]: if item in prefs[preson2]: si[item]=1 if len(si)==0:return 0 n=len(si) print n sum_of_squares=sum([pow(prefs[person1][item]-prefs[preson2][item],2) for item in prefs[person1] if item in prefs[preson2]]) return 1/(1+sqrt(sum_of_squares))
我们可以调用该函数,分别输入两个人的名字,计算相似度的评价值。
>>>reload(recommendations) >>> recommendations.sim_distance(recommendations.critics,'Lisa Rose','Gene Seymour') 0.294298055086
上面的执行结果就是Lisa Rose和Gene Seymour的相似度评价。
(2)皮尔逊相关度评价
还有一种更为复杂的方法来判断人们的相似度,那就是皮尔逊相关度。
该相关系数是判断两组数据与某一条直线的拟合程度的一种度量。在数据不是很规范的时候,会倾向于给出更好的结果。
该算法首先会找到两位评价者都曾经评价的物品,然后计算两者的评分总和和平方和,并求得评分的乘积,最后利用这些计算结果计算出皮尔逊相关系数。代码如下:
def sim_pearson(prefs,p1,p2): # Get the list of mutually rated items si={} for item in prefs[p1]: if item in prefs[p2]: si[item]=1 # if they are no ratings in common, return 0 if len(si)==0: return 0 # Sum calculations n=len(si) # Sums of all the preferences sum1=sum([prefs[p1][it] for it in si]) sum2=sum([prefs[p2][it] for it in si]) # Sums of the squares sum1Sq=sum([pow(prefs[p1][it],2) for it in si]) sum2Sq=sum([pow(prefs[p2][it],2) for it in si]) # Sum of the products pSum=sum([prefs[p1][it]*prefs[p2][it] for it in si]) # Calculate r (Pearson score) 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
将上述代码加到recommendations中。
执行结果如下:
>>> reload(recommendations) >>> print recommendations.sim_pearson(recommendations.critics,'Lisa Rose','Gene Seymour') 0.396059017191