黑马程序员技术交流社区

标题: 【西安校区】寻找最近的用户(用户相似度判定) [打印本页]

作者: 就业高冷派    时间: 2017-12-20 21:53
标题: 【西安校区】寻找最近的用户(用户相似度判定)
本帖最后由 就业高冷派 于 2017-12-20 22:24 编辑

       通常在网站会有一些推荐场景,如买了这个商品的用户同时购买了....一些电影网站根据用户评价数据对一些电影进行推荐。那么关于相似度的评价值的体系本文主要介绍两种:欧几里德距离和皮尔逊相关度。
欧几里德距离评价
欧几里德距离是指多维空间两点间的距离,这是一种用直尺测量出来的距离。如果将两个点分别标记为(p1,p2,p3....pn)和(q1,q2,q3.....qn),则欧几里德距离的计算公式为:




比如用户对一些商品的评价可以用python的字典来表示:
[Python] 纯文本查看 复制代码
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}}
欧几里德距离评价算法是一个非常简单的计算相似度评价值的方法。它以经过人们一致评价的物品为坐标轴,然后将参与评价的人绘制到图上,并考查他们彼此间的距离远近。如图:

上述算式可以计算出距离值,偏好越相似的人,其距离就越短,不过,我们还需要一个函数,来对偏好越相近的情况给出越大的值。为此,可以将函数值加1(这样就可以避免遇到被零整除的错误了),并取其倒数:
[Python] 纯文本查看 复制代码
def sim_distance(prefs, person1, person2):
simple_flag = False
for item in prefs[person1]:
    if item in prefs[person2]:
        simple_flag = True
if simple_flag is False:
    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/(sqrt(sum_of_squares)+1)
皮尔逊相关度
皮尔逊相关系数是比欧几里德距离更加复杂的可以判断人们兴趣的相似度的一种方法。该相关系数是判断两组数据与某一直线拟合程序的一种试题。它在数据不是很规范的时候,会倾向于给出更好的结果。

如图,Mick Lasalle为<<Superman>>评了3分,而Gene Seyour则评了5分,所以该影片被定位中图中的(3,5)处。在图中还可以看到一条直线。其绘制原则是尽可能地靠近图上的所有坐标点,被称为最佳拟合线。如果两位评论者对所有影片的评分情况都相同,那么这条直线将成为对角线,并且会与图上所有的坐标点都相交,从而得到一个结果为1的理想相关度评价。
计算公式如下:

[Python] 纯文本查看 复制代码
def sim_pearson(prefs, p1, p2):
    sim = {}
    for item in prefs[p1]:
        if item in prefs[p2]:
            sim[item] = 1
    n = len(sim)
    if n == 0:
        return 0
    sum1 = sum([prefs[p1][item] for item in sim])
    sum2 = sum([prefs[p2][item] for item in sim])

    sum1_pow = sum([pow(prefs[p1][item], 2) for item in sim])
    sum2_pow = sum([pow(prefs[p2][item], 2) for item in sim])

    pSum = sum([prefs[p1][item] * prefs[p2][item] for item in sim])

    num = pSum - (sum1 * sum2)/n
    den = sqrt((sum1_pow - pow(sum1, 2)/n) * (sum2_pow - pow(sum2, 2)/n))
    if den == 0:
        return 0
    return num/den
皮尔逊相关系数是一个介于 1 和 -1 之间的值,其中,1 表示变量完全正相关, 0 表示无关,-1 表示完全负相关。
注意:这里的相关系数只是用来衡量两个变量线性相关程度的指标;
反之不成立:
比如
总结:如果两个变量本身就是线性的关系,那么皮尔逊相关系数ok没问题,绝对值大的就是相关性强,小的就是相关性弱; 但在你不知道这两个变量是什么关系的情况下,即使算出皮尔逊相关系数,发现很大,也不能说明那两个变量线性相关,甚至不能说他们相关,
如何选择哪一种相似度度量方法
如何选择,完全取决于具体的应用,可以通过以下方法,来测试哪种方法可以达到最好的效果
[Python] 纯文本查看 复制代码
def top_matches(prefs, person, n=5, sim_def = sim_pearson):
    # scores = []
    # for other in prefs:
    #     if other != person:
    #         scores.append((sim_def(prefs, person, other), other))
    scores = [(sim_def(prefs, person, other), other)
              for other in prefs if other != person]
    scores.sort()
    scores.reverse()
    return scores[0:n]
其他相似度计算方法
Jaccard系数
曼哈顿距离算法
        

作者: wheat    时间: 2017-12-20 22:36
很不错哦

作者: 溜达的鱼    时间: 2017-12-21 07:24
感谢分享

作者: 逆风TO    时间: 2017-12-21 14:39
太棒了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2