欧几里得距离
概述
- 根据两用户之间共同评价的Item为维度,建立一个多维的空间,那么通过用户对单一维度上的评价Score组成的坐标系X(s1,s2,s3……,si)即可定位该用户在这个多维度空间中的位置,那么任意两个位置之间的距离Distance(X,Y)(即:欧式距离)就能在一定程度上反应了两用户兴趣的相似程度。
![](https://img2018.cnblogs.com/blog/1159210/201910/1159210-20191024142809654-1377017395.png)
- 欧氏距离越小,两个用户相似度就越大,欧氏距离越大,两个用户相似度就越小。
- 计算所得距离+1取倒数( 1/(1+Distance(X,Y))),得到0-1范围内的相似值。+1的原因是防止距离为0,无法取倒数。相似值越高越相似。
公式
注意事项
- 因为计算是基于各维度特征的绝对数值,所以欧氏度量需要保证各维度指标在相同的刻度级别,比如对身高(cm)和体重(kg)两个单位不同的指标使用欧式距离可能使结果失效。
- 欧几里得距离是数据上的直观体现,看似简单,但在处理一些受主观影响很大的评分数据时,效果则不太明显;比如,U1对Item1,Item2 分别给出了2分,4分的评价;U2 则给出了4分,8分的评分。通过分数可以大概看出,两位用户褒Item2 ,贬Item1,也许是性格问题,U1 打分更保守点,评分偏低,U2则更粗放一点,分值略高。在逻辑上,是可以给出两用户兴趣相似度很高的结论。如果此时用欧式距离来处理,得到的结果却不尽如人意。即评价者的评价相对于平均水平偏离很大的时候欧几里德距离不能很好的揭示出真实的相似度。
示例代码
critics = {
'Lisa':{'Lady':2.5,'Snak':3.5,'Just':3.0,'Superman':3.5,'Dupree':2.5,'Night':3.0},
'Gene':{'Lady':3.0,'Snak':3.5,'Just':1.5,'Superman':5.0,'Dupree':3.5,'Night':3.0},
'Michael':{'Lady':2.5,'Snak':3.0,'Superman':3.5,'Night':4.0},
'Claudia':{'Snak':3.5,'Just':3.0,'Superman':4.0,'Dupree':2.5,'Night':4.5},
'Mick':{'Lady':3.0,'Snak':4.0,'Just':2.0,'Superman':3.0,'Dupree':2.0,'Night':3.0},
'Jack':{'Lady':3.0,'Snak':4.0,'Just':3.0,'Superman':5.0,'Dupree':3.5,'Night':3.0},
'Toby':{'Snak':4.5,'Superman':4.0,'Dupree':1.0}
}
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))
print (sim_distance(critics,'Lisa','Gene'))
print (sim_distance(critics,'Lisa','Toby'))
print (sim_distance(critics,'Lisa','Michael'))