计算相似度

顾名思义,就是计算两个item的相似度,这些在数据挖掘中是个很基础的部分,很多数据挖掘的算法都要以此为基础,例如聚类。因为以前总结过,这里就不再详细说了,下面简单列举了4个方法,根据不同的数据样本选择不同的方式。

举个例子,这里有五本书,a,b,c三个童鞋看过,它们对这五本书的评价如下(分数为1~5):

A = [1, 2, 4, 3, 5]
B = [2, 4, 3, 3, 4]
C = [3, 3, 2, 2, 3]

问题,谁和用户A的口味比较相似?

1,欧几里德距离。这个大家都熟悉,两点之间的欧几里德距离就是两点间距离公式,各维数据相减,平方后相加,再开方。

2,余弦值。将A,B看成两个向量,计算两个向量的余弦值,也就是这两个向量夹角的余弦值,越大表明越相似(即两向量的夹角越小)。考虑下面两个数据,[1,2,1,2,2] 和 [2, 4, 2, 4, 4], 可以看到第二组评分数据每项都是第一组的2倍,这说明两个人的品位也可能相同(只是第一个人要求更严格一些),但是这两个数据若采用上面的欧拉距离,那么得出的差异值就比较大了,而当用余弦计算时,因为两个有倍数关系,这两个向量的夹角是0,所以cos(0) =  1,也说明了两个向量的相似度很高。

3,皮尔森系数。这个公式更复杂,考虑下面两个向量,加入引入了负值评分系统,打分可以从-5 ~ 5了,那么可能有这两个向量[-2, 1, 2, -2, 1] 和 [4, -2, -4, 4, -2],这两个向量如果使用余弦计算,由于它们是-2倍数的关系,所以cos值仍然是1,但是这两个用户的品位是完全相反的。这时候使用皮尔森系数,结果在-1 ~ 1 之间,对于正倍数关系,它可以象余弦一样得到正值;对于负倍数关系,它会计算产生负值,如上面这两个,它产生的结果是-1,符合我们的“品位相反”。

4。Tanimoto。广义Jaccard系数,在二元属性下归约为Jaccard系数。(Jaccard系数是很简单的公式,请google之),Jaccard系数适合处理非对称二元属性,Tanimoto系数在哪种情况下用的多还不清楚。

看代码就知道公式了,python版的(文件是utf-8编码的),点击查看。只要将文件中的sample改成开始我们设置的那三个ABC就可以得到相似度了,进而也就知道谁和用户a的口味比较接近。

– EOF –

6 comments:

  1. lotus

    博主你好,源代码文件已经查看不了了。
    我用余弦定理没有计算出来余弦值为1,所以想看看你的代码,谢谢。
    向量内积:cos(b,c) = (x1x2 + y1y2 + z1z2) / [sqrt(x1^2 + y1^2 + z1^2) * sqrt(x2^2 + y2^2 + z2^2)] 我也计算不出来。

  2. Vonbo *

    那文件地址更新了,应该能看了。你是怎么算的?算式是对的,怎么会算不出来呢?
    a = [1,2,1] b= [2, 4, 2],这两个向量是2倍的关系:
    下面这行是octave的代码,结果就是1:
    octave-3.4.0:12> sum(a .* b) / (sqrt(sum(a.^2)) * sqrt(sum(b.^2)))
    ans = 1.0000

  3. lotus

    文件看到了,谢谢。
    你的计算正确,但是你给的例子是数据: [1,2,1,2,2] 和 [2, 4, 2, 4, 4] 这个计算结果不是1

Leave a Reply

Your email address will not be published. Required fields are marked *