欧几里德距离、皮尔逊相关度、Tanimoto

集体智慧编程正式开始了接触,第一课便是如何寻找想进用户(也就是两者的相似程度),正如大多数的推送服务一样,通过计算你和其他的用户的相似程度,给你推荐最佳匹配人认为很好的但是你还没有购买的东西。

这里重点讲了三个计算相似程度的评价方法:欧几里德距离、皮尔逊相关度、Tanimoto

测试数据如下:(就是嵌套字典,共7个人对使用过的商品的评价)


 
 
  1. critics={ 'Lisa Rose': { 'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,
  2. 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5,
  3. 'The Night Listener': 3.0},
  4. 'Gene Seymour': { 'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5,
  5. 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0,
  6. 'You, Me and Dupree': 3.5},
  7. 'Michael Phillips': { 'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,
  8. 'Superman Returns': 3.5, 'The Night Listener': 4.0},
  9. 'Claudia Puig': { 'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,
  10. 'The Night Listener': 4.5, 'Superman Returns': 4.0,
  11. 'You, Me and Dupree': 2.5},
  12. 'Mick LaSalle': { 'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
  13. 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,
  14. 'You, Me and Dupree': 2.0},
  15. 'Jack Matthews': { 'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,
  16. 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},
  17. 'Toby': { 'Snakes on a Plane': 4.5, 'You, Me and Dupree': 1.0, 'Superman Returns': 4.0}}

 

一:欧几里德距离

 

原理很简单,降维理解:已知直角三角形的两直角边,求斜边长度。

通过两者曾共同使用、评价过的东西来计算。例如:以人们一致评价过的物品为坐标轴,将参与评价的人绘制到图上,以此来考查他们的远近关系。简单的二维图如下:

Toby(1,4.5),若两者在“偏好空间”越相近,则两者越相似。由于这是二维图,所以同一时间只能看到两项评分。可以看下面代码,仔细理解一下,在多维情况下依旧适用。(每个共有物品都会做比较)


 
 
  1. #欧几里德距离
  2. from math import sqrt
  3. def sim_distance(prefs,person1,person2):
  4. si = {}
  5. for item in prefs[person1]:
  6. if(item in prefs[person2]):
  7. si[item] = 1
  8. if(len(si) == 0):
  9. return 0 #上面的代码应该可以省略
  10. sum_of_squares = sum([pow(prefs[person1][item]-prefs[person2][item], 2) for item in prefs[person1] if item in prefs[person2]])
  11. return ( 1/( 1+sqrt(sum_of_squares)))     #下面解释一下
  12. sim = sim_distance(critics, 'Lisa Rose', 'Gene Seymour')
  13. print(sim)

解释:上面的sum_of_squares越小,两者距离越近,越相似。但我们需要一个函数对偏好越近的情况给出越大值,所以我们对开方后的值加1(防止分母为0),再取倒数。

适合于特征数据量较小的情况

二:皮尔逊相关度

这个相对于欧几里德距离要复杂一点。它的一个好处是,当两者对一件物品的评分差距较大时,并不一定两者不想近,如果他两对于其他的物品评价也有差距,但是都是正相关,那两者的相似度还是相近的。这个比欧几里德距离准确。

它是存在一条拟合线的,这条线尽量靠近所有点,结果也是求所有点和这条线的拟合程度。皮尔逊相关度评价算法首先会找出两位评论者都曾评论过的物品,然后计算两者的评分总和与平方和,并求得评分的乘积之和。最后,算法利用这些计算结果计算出皮尔逊相关度。


 
 
  1. #皮尔逊相关度
  2. from math import sqrt
  3. def sim_pearson(prefs,person1,person2):
  4. si = {}
  5. for item in prefs[person1]:
  6. if(item in prefs[person2]):
  7. si[item] = 1
  8. n = len(si)
  9. if(n == 0):
  10. return 0
  11. #求和
  12. sum1 = sum(prefs[person1][item] for item in si)
  13. sum2 = sum(prefs[person2][item] for item in si)
  14. #求平方和
  15. sum1_sq = sum(pow(prefs[person1][item], 2) for item in si)
  16. sum2_sq = sum(pow(prefs[person2][item], 2) for item in si)
  17. #求乘积和
  18. asum = sum(prefs[person1][item]*prefs[person2][item] for item in si)
  19. #计算皮尔逊评价值
  20. num = asum-(sum1*sum2/n)
  21. den = sqrt((sum1_sq-pow(sum1, 2)/n)*(sum2_sq-pow(sum2, 2)/n))
  22. if(den == 0):
  23. return 0
  24. return (num/den)
  25. sim = sim_pearson(critics, 'Lisa Rose', 'Gene Seymour')
  26. print(sim)

适合于特征数据量较大的情况(效果较好)

三:Tanimoto

Tanimoto感觉比较简单:

    交集/并集

    这是一个计算交集和并集的比率的方法

   度量两个集合之间的相似程度的方法。 
    A=[1,2,3,4]                 列表长度:4
    B=[1,2,7]                     列表长度:3
    C = A & B = [1,2]        列表长度:2
    T = Nc / ( Na + Nb -Nc) = len(c) / ( len(a) + len(b) - len(c)) = 2 / (4+3-2) = 0.4 


 
 
  1. def tanimoto(p,q):
  2. c = [v for v in p if v in q]
  3. return float(len(c)) / ((len(p) + len(q) - len(c)))

    可以用户计算用户之间的相似程度,这种方法适用于:数据表示为0、1这种二值化,而非有数量大小的情况

 

以上为全部内容,在查找物品、人物相似程度上都是比较简单的算法,各自都有适用于的场景。

    • 0
      点赞
    • 0
      收藏
      觉得还不错? 一键收藏
    • 1
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论 1
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值