用Python写个简单的推荐系统(一)

         本篇建立在电影评分的环境下,对多位成员通过各自电影评分的情况,利用两种相似度测量(欧几里得距离和皮尔逊相关度)查看用户之间的相似度。

Python version3.4


1.   建立影评评分字典

电影种类6种:a,b,c,d,e,f用户7人: Cathy, Sophie, Susie, Antonio,Marco,Jack, Leo

critics={'Cathy':{'a':2.5,'b':3.5,'c':3,'d':3.5,'e':2.5,'f':3},

'Sophie':{'a':3,'b':3.5,'c':1.5,'d':5,'e':1.5,'f':3},

'Susie':{'a':2.5,'b':3,'d':3.5,'f':4},

'Antonio':{b':3.5,'c':3,'d':4,'e':2.5,'f':4.5},

'Marco':{'a':3,'b':4,'c':2,'d':3,'e':2,'f':3},

'Jack':{'a':3,'b':4,'d':5,'e':3.5,'f':3}

'Leo':{'b':4.5,'d':4,'e':1.0}}


先保存该文件为recommendations.py,推荐系统的数据集构造成。 


2.   关于欧几里得距离和计算

欧几里得度量定义欧几里得空间中,点x =(x1,...,xn)和 y =(y1,...,yn)之间的距离为

(以上来自维基百科官方定义。其实欧几里得距离就类似在一个一维坐标系中两个点的距离。其中水平轴上一种item,垂直轴上一个item。

 

3.  在python解释器中秋欧几里得距离例子:

>>>from math import sqrt

>>>sqrt (pow(4.5-4, 2) + pow (1-2,2))


4.   计算相似度(欧几里得)

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))

5.   调用该函数,分别传入两个人的名字,并计算出相似度的评价值

>>>import recommendations

>>>recommendations.sim_distance(recommendations.critics,’Cathy’,’Sophie’)

0.29429805508554946

 

注意:python3中已经移去reload模块,创建的recommendations模块做过任何修改,保存直接用即可。

 

皮尔逊相关系数评估相似度

 

6.  关于皮尔逊相关系数

两个变量之间的皮尔逊相关系数定义为两个变量之间的协方差标准差的商:

以上方程定义了总体相关系数, 一般表示成希腊字母ρ(rho)。基于样本对协方差和标准差进行估计,可以得到样本相关系数, 一般表示成r

对于有些用户会给评分的电影普遍打高分,而有些用户普遍打的分低,用皮尔逊相关系数就可以更好的体现相似度,一样可以体现出两种高低趋势下对同种电影的相似偏好。

 

7.  用皮尔逊相关度定义函数

#返回p1和p2的皮尔逊相关系数
def sim_pearson (prefs,person1,person2):
    si={}
    for item in prefs[person1]:
         if item in prefs[person2]: si[item]=1
    n=len(si)

    if n==0:return 1

    sum1=sum([prefs[person1][it] for it in si])
    sum2=sum([prefs[person2][it] for it in si])

    sum1Sq=sum([pow(prefs[person1][it],2)for it in si])
    sum2Sq=sum([pow(prefs[person2][it],2)for it in si])

    pSum=sum([prefs[person1][it]*prefs[person2][it] for it in si])
 #calculate the pearsonvlaue
    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

为区别欧几里得距离的py文件,皮尔逊的另存为recommendations1.py



8.  用皮尔逊相关系数的recommendations1 模块求相关评价值

>>> import recommendations1

>>> print (sim_pearson(critics, ‘Cathy’,’Sophie’)

0.39605901719066977


9.  相似度排名列表

            上述的方法只能先计算出任两个人之间的相似度,下面我们就来找和自己有相似品味的影评者。将该函数加入上面皮尔逊方法的recommendations1.py中,得到一个人员的有序列表。

def topmatches (prefs,person,n,similarity=sim_pearson):
    scores=[(similarity(prefs,person,other),other)
                for other in prefs if other!=person]
    scores.sort()#sort the similarity 
    scores.reverse()
    return scores[0:n]

10.  得到有关影评者相似度评价值的列表

>>>import recommendations1

>>>recommendation1s.topmatches(critics,’Leo’,5)

 

得到结果(皮尔逊相关度):

[(1.0, 'Marco'),(0.9912407071619299, 'Cathy'), (0.66284898035987, 'Jack'),(0.38124642583151164, 'Sophie'), (0, 'Antonio')]


如果在之前的欧几里得距离的recommendations.py中得到人员的有序列表,则:

def topmatches (prefs,person,n,similarity=sim_distance):
    scores=[(similarity(prefs,person,other),other)
                for other in prefs if other!=person]
    scores.sort()#sort the similarity 
    scores.reverse()
    return scores[0:n]

>>>import recommendations

>>>recommendations.topmatches(critics,’Leo’,5)

 

得到结果:

[(0.5, 'Antonio'),(0.4721359549995794, 'Marco'), (0.38742588672279304, 'Susie'), (0.3483314773547883, 'Cathy'), (0.2674788903885893, 'Jack')]



你可能感兴趣的:(推荐系统)