集体智慧编程_jaccard相似度实现

算法原理:

(1) 杰卡德相似系数

       两个集合A和B的交集元素在A,B的并集中所占的比例,称为两个集合的杰卡德相似系数,用符号J(A,B)表示。

  杰卡德相似系数是衡量两个集合的相似度一种指标。

(2) 杰卡德距离

       与杰卡德相似系数相反的概念是杰卡德距离(Jaccard distance)。杰卡德距离可用如下公式表示:

  杰卡德距离用两个集合中不同元素占所有元素的比例来衡量两个集合的区分度。

(3) 杰卡德相似系数与杰卡德距离的应用

       可将杰卡德相似系数用在衡量样本的相似度上。

  样本A与样本B是两个n维向量,而且所有维度的取值都是0或1。例如:A(0111)和B(1011)。我们将样本看成是一个集合,1表示集合包含该元素,0表示集合不包含该元素。

p :样本A与B都是1的维度的个数

q :样本A是1,样本B是0的维度的个数

r :样本A是0,样本B是1的维度的个数

s :样本A与B都是0的维度的个数


那么样本A与B的杰卡德相似系数可以表示为:

这里p+q+r可理解为A与B的并集的元素个数,而p是A与B的交集的元素个数。

而样本A与B的杰卡德距离表示为:


_____________________________________________________________________________________

* 分隔符 *  * 分隔符 *  * 分隔符 *  * 分隔符 *  * 分隔符 *  * 分隔符 *  * 分隔符 *  * 分隔符 *  * 分隔符 *  


不考虑评分高低,只代表看过同样的电影,初版代码如下:

def sim_jaccard(prefs,person1,person2):
  # Get the list of shared_items
  si={}
  for item in prefs[person1]: 
    if item in prefs[person2]: 
      si[item]=1


  # if they have no ratings in common, return 0
  if len(si)==0: 
  return 0
 
  n=len(si)
  n1=len(prefs[person1])
  n2=len(prefs[person2])
  p=n1+n2-n
  return n/float(p)

输出:

>>> recommendations.topMatches(recommendations.critics,'Lisa Rose',n=5,similarity=recommendations.sim_jaccard);
[(1.0, 'Mick LaSalle'), (1.0, 'Gene Seymour'), (0.8333333333333334, 'Jack Matthews'), (0.8333333333333334, 'Claudia Puig'), (0.6666666666666666, 'Michael Phillips')]


取评分均值区分喜欢和不喜欢,两部分相似度和

def sim_jaccard1(prefs,person1,person2):
  sum1=sum([prefs[person1][it] for it in prefs[person1]])
  sum2=sum([prefs[person1][it] for it in prefs[person2]])
  
  avg_p1=sum1/float(len(prefs[person1]))
  avg_p2=sum2/float(len(prefs[person2]))
  
  p10={}
  p11={}
  for item in prefs[person1]: 
    if prefs[person1][item]>= avg_p1:
      p10[item]=prefs[person1][item]
    else:
    p11[item]=prefs[person1][item]


  p20={}
  p21={}
  for item in prefs[person2]: 
    if prefs[person2][item]>= avg_p1:
      p20[item]=prefs[person2][item]
    else:
      p21[item]=prefs[person2][item]
  
  si={}
  for item in p10: 
    if item in p20: 
      si[item]=1

  sj={}
  for item in p11: 
    if item in p21: 
      sj[item]=1

  a=len(si)/float(len(p10)+len(p20)-len(si))
  b=len(sj)/float(len(p11)+len(p21)-len(sj))

  return a+b

输出:

>>> recommendations.topMatches(recommendations.critics,'Lisa Rose',n=5,similarity=recommendations.sim_jaccard1);
[(1.5, 'Claudia Puig'), (1.25, 'Michael Phillips'), (1.0, 'Toby'), (0.9333333333333333, 'Mick LaSalle'), (0.5, 'Jack Matthews')]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值