关于相似度计算的算法总结
相似度计算
1 相似度的计算简介
关于相似度的计算,现有的几种基本方法都是基于向量(Vector)的,其实也就是计算两个向量的距离,距离越近相似度越大。在推荐的场景中,在用户-物品偏好的二维矩阵中,我们可以将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,或者将所有用户对某个物品的偏好作为一个向量来计算物品 之间的相似度。下面我们详细介绍几种常用的相似度计算方法:
1.1 皮尔逊相关系数(Pearson Correlation Coefficient)(百度用来判断tiele相似度的算法之一)
皮尔逊相关系数一般用于计算两个定距变量间联系的紧密程度,它的取值在 [-1,+1] 之间。
sx, sy是 x 和 y 的样品标准偏差。
类名:PearsonCorrelationSimilarity
原理:用来反映两个变量线性相关程度的统计量
范围:[-1,1],绝对值越大,说明相关性越强,负相关对于推荐的意义小。
说明:1、 不考虑重叠的数量;2、 如果只有一项重叠,无法计算相似性(计算过程被除数有n-1);3、 如果重叠的值都相等,也无法计算相似性(标准差为0,做除数)。
该相似度并不是最好的选择,也不是最坏的选择,只是因为其容易理解,在早期研究中经常被提起。使用Pearson线性相关系数必须假设数据是成对地从正态分布中取得的,并且数据至少在逻辑范畴内必须是等间距的数据。Mahout中,为皮尔森相关计算提供了一个扩展,通过增加一个枚举类型(Weighting)的参数来使得重叠数也成为计算相似度的影响因子。
1.2 欧几里德距离(Euclidean Distance)
最初用于计算欧几里德空间中两个点的距离,假设 x,y 是 n 维空间的两个点,它们之间的欧几里德距离是:
可以看出,当 n=2 时,欧几里德距离就是平面上两个点的距离。当用欧几里德距离表示相似度,一般采用以下公式进行转换:距离越小,相似度越大。
类名:EuclideanDistanceSimilarity
原理:利用欧式距离d定义的相似度s,s=1 / (1+d)。
范围:[0,1],值越大,说明d越小,也就是距离越近,则相似度越大。
说明:同皮尔森相似度一样,该相似度也没有考虑重叠数对结果的影响,同样地,Mahout通过增加一个枚举类型(Weighting)的参数来使得重叠数也成为计算相似度的影响因子。
1.3 Cosine 相似度(Cosine Similarity)
Cosine 相似度被广泛应用于计算文档数据的相似度:
类名: UncenteredCosineSimilarity
原理:多维空间两点与所设定的点形成夹角的余弦值。
范围:[-1,1],值越大,说明夹角越大,两点相距就越远,相似度就越小。
说明:在数学表达中,如果对两个项的属性进行了数据中心化,计算出来的余弦相似度和皮尔森相似度是一样的,在mahout中,实现了数据中心化的过程,所以皮尔森相似度值也是数据中心化后的余弦相似度。另外在新版本中,Mahout提供了UncenteredCosineSimilarity类作为计算非中心化数据的余弦相似度。
1.4 Spearman秩相关系数--Spearman Correlation
类名:SpearmanCorrelationSimilarity
原理:Spearman秩相关系数通常被认为是排列后的变量之间的Pearson线性相关系数。
范围:{-1.0,1.0},当一致时为1.0,不一致时为-1.0。
说明:计算非常慢,有大量排序。针对推荐系统中的数据集来讲,用Spearman秩相关系数作为相似度量是不合适的。
1.5 Tanimoto 系数(Tanimoto Coefficient)
Tanimoto 系数也称为 Jaccard 系数,是 Cosine 相似度的扩展,也多用于计算文档数据的相似度:
类名:TanimotoCoefficientSimilarity
原理:又名广义Jaccard系数,是对Jaccard系数的扩展,等式为
范围:[0,1],完全重叠时为1,无重叠项时为0,越接近1说明越相似。
说明:处理无打分的偏好数据。
1.6 对数似然相似度
类名:LogLikelihoodSimilarity
原理:重叠的个数,不重叠的个数,都没有的个数
说明:处理无打分的偏好数据,比Tanimoto系数的计算方法更为智能。
1.7 曼哈顿距离
类名:CityBlockSimilarity
原理:曼哈顿距离的实现,同欧式距离相似,都是用于多维数据空间距离的测度
范围:[0,1],同欧式距离一致,值越小,说明距离值越大,相似度越大。
说明:比欧式距离计算量少,性能相对高。
2 各相似度计算方法优缺点分析
2.1 基于皮尔森相关性的相似度— Pearson correlation-based similarity
皮尔森相关系数反应了两个变量之间的线性相关程度,它的取值在[-1, 1]之间。当两个变量的线性关系增强时,相关系数趋于1或-1;当一个变量增大,另一个变量也增大时,表明它们之间是正相关的,相关系数大于0;如果一个变量增大,另一个变量却减小,表明它们之间是负相关的,相关系数小于0;如果相关系数等于0,表明它们之间不存在线性相关关系。用数学公式表示,皮尔森相关系数等于两个变量的协方差除于两个变量的标准差。
协方差(Covariance):在概率论和统计学中用于衡量两个变量的总体误差。如果两个变量的变化趋于一致,也就是说如果其中一个大于自身的期望值,另一个也大于自身的期望值,那么两个变量之间的协方差就是正值;如果两个变量的变化趋势相反,则协方差为负值。其中u表示X的期望E(X), v表示Y的期望E(Y)。
标准差(Standard Deviation):
方差(Variance):在概率论和统计学中,一个随机变量的方差表述的是它的离散程度,也就是该变量与期望值的距离
即方差等于误差的平方和的期望,基于皮尔森相关系数的相似度有两个缺点:
(1) 没有考虑用户间重叠的评分项数量对相似度的影响;
(2) 如果两个用户之间只有一个共同的评分项,相似度也不能被计算。
上表中,行表示用户(1~5)对项目(101~103)的一些评分值。直观来看,User1和User5用3个共同的评分项,并且给出的评分值差也不大,按理他们之间的相似度应该比User1和User4之间的相似度要高,可是User1和User4有一个更高的相似度1。
例子:同样的场景在现实生活中也经常发生,比如两个用户共同观看了200部电影,虽然不一定给出相同或完全相近的评分,他们之间的相似度也应该比另一位只观看了2部相同电影的相似度高吧!但事实并不如此,如果对这两部电影,两个用户给出的相似度相同或很相近,通过皮尔森相关性计算出的相似度会明显大于观看了相同的200部电影的用户之间的相似度。
Mahout对基于皮尔森相关系数的相似度给出了实现,它依赖一个DataModel作为输入。
同时,Mahout还针对缺点(1)进行了优化,只需要在构造PearsonCorrelationSimilarity时多传入一个Weighting.WEIGHTED参数,就能使有更多相同评分项目的用户之间的相似度更趋近于1或-1。
[java] :
- UserSimilarity similarity1 = new PearsonCorrelationSimilarity(model);
- double value1 = similarity1.userSimilarity(1, 4);
3. double value2= similarity1.userSimilarity(1, 5);
4. UserSimilarity similarity2 = new PearsonCorrelationSimilarity(model, Weighting.WEIGHTED);
5. double value3 = similarity1.userSimilarity(1, 4);
6. double value4 = similarity2.userSimilarity(1, 5);
结果:
Similarity of User1 and User4:0.9999999999999998
Similarity of User1 and User5: 0.944911182523068
Similarity of User1 and User4 with weighting: 0.9999999999999999
Similarity of User1 and User5 with weighting: 0.986227795630767
2.2 基于欧几里德距离的相似度 —— Euclidean Distance-based Similarity
欧几里德距离计算相似度是所有相似度计算里面最简单、最易理解的方法。它以经过人们一致评价的物品为坐标轴,然后将参与评价的人绘制到坐标系上,并计算他们彼此之间的直线距离。
图中用户A和用户B分别对项目X、Y进行了评分。用户A对项目X的评分为1.8,对项目Y的评分为4,表示到坐标系中为坐标点A(1.8, 4);同样用户B对项目X、Y的评分表示为坐标点B(4.5, 2.5),因此他们之间的欧几里德距离(直线距离)为:
计算出来的欧几里德距离是一个大于0的数,为了使其更能体现用户之间的相似度,可以把它规约到(0, 1]之间,具体做法为:1 / (1 + d)。参见上表。
只要至少有一个共同评分项,就能用欧几里德距离计算相似度;如果没有共同评分项,那么欧几里德距离也就失去了作用。其实照常理理解,如果没有共同评分项,那么意味着这两个用户或物品根本不相似。
2.3 余弦相似度 —— Cosine Similarity
余弦相似度用向量空间中两个向量夹角的余弦值作为衡量两个个体间差异的大小。相比距离度量,余弦相似度更加注重两个向量在方向上的差异,而非距离或长度上。
与欧几里德距离类似,基于余弦相似度的计算方法也是把用户的喜好作为n-维坐标系中的一个点,通过连接这个点与坐标系的原点构成一条直线(向量),两个用户之间的相似度值就是两条直线(向量)间夹角的余弦值。因为连接代表用户评分的点与原点的直线都会相交于原点,夹角越小代表两个用户越相似,夹角越大代表两个用户的相似度越小。同时在三角系数中,角的余弦值是在[-1, 1]之间的,0度角的余弦值是1,180角的余弦值是-1。借助三维坐标系来看下欧氏距离和余弦相似度的区别:
从图上可以看出距离度量衡量的是空间各点间的绝对距离,跟各个点所在的位置坐标(即个体特征维度的数值)直接相关;而余弦相似度衡量的是空间向量的夹角,更加的是体现在方向上的差异,而不是位置。如果保持A点的位置不变,B点朝原方向远离坐标轴原点,那么这个时候余弦相似度cos是保持不变的,因为夹角不变,而A、B两点的距离显然在发生改变,这就是欧氏距离和余弦相似度的不同之处。
余弦相似度的特点:
- 对用户的绝对的数值不敏感
- 计算时不考虑用户之间的共同评分项数量,即使仅仅有极少相同评分项,也有可能获得很大的相似度结果,例如上表中的uer3与user1.
- 只要各个评分项之间越趋向于对应成比例,而不论数值差异如何,则相似度越趋近于1.000.
根据欧氏距离和余弦相似度各自的计算方式和衡量特征,分别适用于不同的数据分析模型:欧氏距离能够体现个体数值特征的绝对差异,所以更多的用于需要从维度的数值大小中体现差异的分析,如使用用户行为指标分析用户价值的相似度或差异;而余弦相似度更多的是从方向上区分差异,而对绝对的数值不敏感,更多的用于使用用户对内容评分来区分用兴趣的相似度和差异,同时修正了用户间可能存在的度量标准不统一的问题(因为余弦相似度对绝对数值不敏感)。
注:
根据以上的分析,余弦相似度更适合于这样一类数据的挖掘工作:
- 计算结果对用户数据绝对值不敏感,例如在描述用户的兴趣、喜好、或用于情感分析时。
- 用户数据中的评分值其实是用户主观的评分结果,换言之,每个用户的评价标准是不一致的,有一些对于“好的”界定标准更为苛刻,而另一些则对于“好”、“不好”的界定则更为宽容。这种情况下,用余弦相似度来计算用户之间的相似度或差异,可以弱化度量标准不统一这一因素。Eg:
模糊度量标准 |
“很不好” |
“不好” |
“较好” |
“很好” |
User1的评价标准 |
1.0 |
2.0 |
3.5 |
4.0 |
User2的评价标准 |
2.0 |
3.0 |
4.0 |
5.0 |
User3的评价标准 |
1.0 |
2.0 |
3.0 |
4.0 |
上表中user1和user3的评价标准很相似,都是较为“苛刻的”,user2,相比之下显得更为“宽容”。
Item |
Item001 |
Item002 |
Item003 |
User1的评价 |
2.0 |
4.0 |
3.5 |
User2的评价 |
3.5 |
5.0 |
4.5 |
User3的评价 |
2.0 |
3.5 |
4.0 |
从数值上看,显然user1和user3的评分值更为接近,似乎相似度更高;而user2的评分值相较user1差异较大。
[java]:
1. UserSimilarity similarity1 = new UncenteredCosineSimilarity (model);
2. double value1 = similarity1.userSimilarity(1, 2);
3. double value2= similarity1.userSimilarity(1, 3);
4.UserSimilarity similarity2= new EuclideanDistanceSimilarity (model);
5. double value3 = similarity2.userSimilarity(1, 2);
6. double value4= similarity2.userSimilarity(1, 3);
计算结果:
Similarity of User1 and User2 using cos: 0.9927441515592047
Similarity of User1 and User3 using cos: 0.9801293311529091
Similarity of User1 and User2 using Euc:0.45657137141714005
Similarity of User1 and User3 using Euc:0.4721359549995794
但是,余弦相似度的计算则揭示了:
User2 与user1之间的相似度 > User3与user1之间的相似度。但如果用欧氏距离想速度则:User2 与user1之间的相似度 < User3与user1。
2.4 调整余弦相似度 —— Adjusted Cosine Similarity
在余弦相似度的介绍中说到:余弦相似度更多的是从方向上区分差异,而对绝对的数值不敏感。因此没法衡量每个维数值的差异,会导致这样一个情况:比如用户对内容评分,5分制,X和Y两个用户对两个内容的评分分别为(1,2)和(4,5),使用余弦相似度得出的结果是0.98,两者极为相似,但从评分上看X似乎不喜欢这两个内容,而Y比较喜欢,余弦相似度对数值的不敏感导致了结果的误差,需要修正这种不合理性,就出现了调整余弦相似度,即所有维度上的数值都减去一个均值,比如X和Y的评分均值都是3,那么调整后为(-2,-1)和(1,2),再用余弦相似度计算,得到-0.8,相似度为负值并且差异不小,但显然更加符合现实。
2.5 斯皮尔曼相关 —— Spearman Correlation
斯皮尔曼相关性可以理解为是排列后(Rank)用户喜好值之间的Pearson相关度。《Mahout in Action》中有这样的解释:假设对于每个用户,我们找到他最不喜欢的物品,重写他的评分值为“1”;然后找到下一个最不喜欢的物品,重写评分值为“2”,依此类推。然后我们对这些转换后的值求Pearson相关系数,这就是Spearman相关系数。
斯皮尔曼相关度的计算舍弃了一些重要信息,即真实的评分值。但它保留了用户喜好值的本质特性——排序(ordering),它是建立在排序(或等级,Rank)的基础上计算的。回顾前面表中User1~5对Item101~103的喜好(评分)值,通过斯皮尔曼相关系数计算出的相似度为:
我们发现,计算出来的相似度值要么是1,要么是-1,因为这依赖于用户的喜好值和User1的喜好值是否趋于“一致变化”还是呈“相反趋势变化"。Mahout对斯皮尔曼相关系数给出了实现,具体可参考SpearmanCorrelationSimilarity,它的执行效率不是非常高,因为斯皮尔曼相关性的计算需要花时间计算并存储喜好值的一个排序(Ranks),具体时间取决于数据的数量级大小。正因为这样,斯皮尔曼相关系数一般用于学术研究或者是小规模的计算。
[java] :
UserSimilarity similarity1 = new SpearmanCorrelationSimilarity(model);
// construct a Spearman Correlation-based Similarity
结果:
User1 to User1 : 1.0
User2 to User1 : -1.0
User3 to User1 : NaN
User4 to User1 : 1.0
User4 to User1 : 1.0
考虑到Spearman Correlation的效率,可以把SpearmanCorrelationSimilarity包装一层Cache,具体做法为:
[java]:
UserSimilarity similarity2 = new CachingUserSimilarity (new SpearmanCorrelationSimilarity (model), model);
这样,每次计算的结果会直接放入Cache,下一次计算的时候可以立即得到结果,而不是重新再计算一次。
Spearman相关系数的特点:
- Spearman相关是根据等级资料研究两个变量间相关关系的方法。它是依据两列成对等级的各对等级数之差来进行计算的,所以又称为“等级差数法”
- Spearman相关系数对原始变量的分布不做要求,属于非参数统计方法。因此它的适用范围比Pearson相关系数要广的多。即使原始数据是等级资料也可以计算Spearman相关系数。对于服从Pearson相关系数的数据也可以计算Spearman相关系数,
- 统计效能比Pearson相关系数要低一些(不容易检测出两者事实上存在的相关关系)。
- spearman只要两个变量的观测值是成对的等级评定资料,或者是由连续变量观测资料转化得到的等级资料,不论两个变量的总体分布形态、样本容量的大小如何,都可以用斯皮尔曼等级相关来进行研究。
注:spearman与pearson:
1. 连续数据,正态分布,线性关系,用pearson相关系数是最恰当,当然用spearman相关系数也可以,就是效率没有pearson相关系数高。
2. 上述任一条件不满足,就用spearman相关系数,不能用pearson相关系数。
3. 两个定序测量数据之间也用spearman相关系数,不能用pearson相关系数。
4 .只要在X和Y具有单调的函数关系的关系,那么X和Y就是完全Spearman相关的,这与Pearson相关性不同,后者只有在变量之间具有线性关系时才是完全相关的。
6. 基于谷本系数的相似性度量 —— Tanimoto Coefficient-based Similarity
Tanimoto Coefficient和前面的5中相关度计算方式有很大的不同,它不关心用户对物品的具体评分值是多少,它关心用户与物品之间是否存在关联关系。Tanimoto Coefficient依赖于用户和物品之间的这种Boolean关系作为输入。更准确的说法为:Tanimoto Coefficient主要用于计算符号度量或布尔值度量的个体间的相似度,因为个体的特征属性都是由符号度量或者布尔值标识,因此无法衡量差异具体值的大小,只能获得“是否相同”这个结果,所以Tanimoto Coefficient只关心个体间共同具有的特征是否一致这个问题。Tanimoto Coefficient又被叫做Jaccard Coefficient,其值等于两个用户共同关联(不管喜欢还是不喜欢)的物品数量除于两个用户分别关联的所有物品数量。
也就是关联的交集除于关联的并集,用公式表示为:
其值介于[0, 1]之间,如果两个用户关联的物品完全相同,交集等于并集,值为1;如果没有任何关联,交集为空,值为0。
注:本块中说到的关联指用户对物品有评分值。