余弦相似度与皮尔逊相关系数之间的比较
余弦相似度(也叫作余弦距离)和皮尔逊相关系数是数据挖掘中很常见的两种相似度计算方式,除此之外还有欧式距离、Jaccard 距离、曼哈顿距离等计算方法。
本文主要讨论余弦相似度和皮尔逊相关系数之间的区别,首先,这两者返回的结果(相似度、相关系数)都介于 0 到 1 之间,并且都是值越大代表越相似,直觉上看起来两种算法之间并没有什么区别,然而实际并非如此,在用户的评分维度差距比较大的场景下,余弦相似度得到的结论可能不太合理,这篇文章的目的就是为了把余弦相似度和皮尔逊相似系数之间的区别解释清楚。
余弦相似度
余弦相似度通过计算两个向量的夹角的余弦值来度量它们之间的相似性,在计算文档相似度中应用非常广泛,计算公式如下:
cos(a,b)=a·b | a | · | b | cos(a,b)=a·b | a | · | b |
其中,上式中的分子是向量 a 与向量 b 的内积,分母是向量 a 与向量 b 模的乘积,可以肯定的是分母一定是大于零的,所以余弦相似度的正负性完全由分子决定。
举个例子,比如向量 a 为(1,2,4)
,向量 b 为(-1,0,2)
,那 a 和 b 之间的余弦相似度是这样计算的:
首先,计算内积:1∗(−1)+2×0+4×2=71∗(−1)+2×0+4×2=7
然后,计算向量模的乘积:(1+4+16)‾‾‾‾‾‾‾‾‾‾‾‾√∗(1+0+4)‾‾‾‾‾‾‾‾‾‾‾√(1+4+16)∗(1+0+4)
最后相除得向量 a 与 b 的余弦相似度为 0.683,说明两个向量比较相似。
调整余弦相似度
(修正余弦相似度)
然而,余弦相似度也有它的不足,比如在推荐业务中通常基于用户对物品的评分计算用户之间的相似度,它无法把不同用户的打分维度也纳入到相似度计算中来。
比如用户 A、B 和 C 对三个物品的评分分别为(1,4,0)、(3,5,1) 和 (8,9,2),用余弦相似度计算得到 A 和 B 用户之间的相似度为 0.874
(1∗8+4∗9+0∗2)/(12+42+02‾‾‾‾‾‾‾‾‾‾‾‾√∗82+92+22‾‾‾‾‾‾‾‾‾‾‾‾√)(1∗8+4∗9+0∗2)/(12+42+02∗82+92+22)
然而,从数据上来看 A 用户对这两个物品的喜好程度都不如 B,直觉告诉我这两个用户不太可能有这么相似,因为他们的口味相差实在有点大,正如男生和女生对篮球和运动物品的喜好程度是不一样的,所以用上述的计算方法不太合理。
一般针对评分内容的相似度计算会用到改进后的余弦相似度算法——调整余弦相似度(Adjusted Cosine Similarity),计算公式为:
sim(a,b)=∑i∈I(Ri,a−R⎯⎯⎯⎯i)(Ri,b−R⎯⎯⎯⎯i)∑i∈I(Ri,a−R⎯⎯⎯⎯i)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√∑i∈I(Ri,b−R⎯⎯⎯⎯i)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√sim(a,b)=∑i∈I(Ri,a−R¯i)(Ri,b−R¯i)∑i∈I(Ri,a−R¯i)2∑i∈I(Ri,b−R¯i)2
其中 R⎯⎯⎯⎯iR¯i 为物品 ii 得分的平均值,由上文得物品 1 的平均得分为 4,物品 2 的平均得分为 6,代入上述计算公式:
(1−4)∗(8−4)+(4−6)∗(9−6)+(0−1)∗(2−1)(1−4)2+(4−6)2+(0−1)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√∗(8−4)2+(9−6)2+(2−1)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√(1−4)∗(8−4)+(4−6)∗(9−6)+(0−1)∗(2−1)(1−4)2+(4−6)2+(0−1)2∗(8−4)2+(9−6)2+(2−1)2
得调整余弦相似度为 - 0.996,得出用户 A 和用户 C 之间根本就不相似,这与余弦相似度得出的结论完全相反,这是因为 A 和 C 对 3 个商品的偏好差距太大了,余弦相似度没能捕捉到这种差异,调整余弦相似度正好弥补了它的缺陷。
当然,如果你再计算一遍 A 和 B 的余弦相似度和调整余弦相似度,你会发现 A 和 B 的差异其实不大,从打分的差异上也可以看出来这一点。
从计算过程来看,调整余弦相似度和余弦相似度的计算方法非常相似,只是用户对物品的打分都减去了该物品所有得分的平均值,这一步等价于对数据做了标准化的处理。
另外,把上式中的符号稍微修改一下就能应用于计算物品之间的相似度(把人和物品对调一下),公式如下:
sim(i,j)=∑u∈U(Ru,i−R⎯⎯⎯⎯u)(Ru,j−R⎯⎯⎯⎯u)∑u∈U(Ru,i−R⎯⎯⎯⎯u)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√∑u∈U(Ru,j−R⎯⎯⎯⎯u)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√sim(i,j)=∑u∈U(Ru,i−R¯u)(Ru,j−R¯u)∑u∈U(Ru,i−R¯u)2∑u∈U(Ru,j−R¯u)2
其中 R⎯⎯⎯⎯uR¯u 为用户 uu 打分的平均值。
皮尔逊相关系数
\[sim(a,b)=∑i∈I(Ri,a−R⎯⎯⎯⎯a)(Ri,b−R⎯⎯⎯⎯b)∑i∈I(Ri,a−R⎯⎯⎯⎯a)2√∑i∈I(Ri,b−R⎯⎯⎯⎯b)2√sim(a,b)=∑i∈I(Ri,a−R¯a)(Ri,b−R¯b)∑i∈I(Ri,a−R¯a)2∑i∈I(Ri,b−R¯b)2\]其中,R⎯⎯⎯⎯aR¯a 和 R⎯⎯⎯⎯bR¯b 代表各自打分的平均值。
接着上文,我们试着计算 A 与 C 之间的皮尔逊相似系数,R⎯⎯⎯⎯aR¯a 和 R⎯⎯⎯⎯cR¯c 分别为 1.67 和 6.33,代入上个式子中
(1−1.67)∗(8−6.33)+(4−1.67)∗(9−6.33)+(0−1.67)∗(2−6.33)(1−1.67)2+(4−1.67)2+(0−1.67)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√∗(8−6.33)2+(9−6.33)2+(2−6.33)2‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾√(1−1.67)∗(8−6.33)+(4−1.67)∗(9−6.33)+(0−1.67)∗(2−6.33)(1−1.67)2+(4−1.67)2+(0−1.67)2∗(8−6.33)2+(9−6.33)2+(2−6.33)2
计算得到的结果是 0.782,说明 a,b 两个用户之间的皮尔逊相似度为 0.782,相比余弦相似度计算得到用户高得离谱的相似度稍显正常一点。
对比
皮尔逊相关系数实际上可以看作是一种特殊的余弦相似度计算方式,如果从公式的外形上给三个算法论资排辈的话,皮尔逊相关系数应该是调整余弦相似度的堂兄弟,是余弦相似度的亲儿子。
从上文中举的例子,我们也提到过余弦相似度在面对评分维度差距较大的情形下计算会不太准确,所以建议在用户评分维度差异比较大的场景下优先使用调整余弦相似度和皮尔逊相似度,这一步相当于也是先对数据做了标准化处理。