关于python实现常用的相似度计算方法
作者:Together_CZ
相似度计算
相似度计算是很多具体的应用了里面都会使用到的一些东西,我们学过的有很多相似度计算的方法,最初的相似度计算是为了表征向量的重合程度的,在这里最经典的就是余弦相似度了,当然使用正弦或者是正切等等三角函数也都是可以的,只不过余弦使用的更广泛一些所以提到三角函数计算向量相似度的时候大家往往都会使用余弦来作为相似度的计算工具。
可能最开始会觉得相似度计算没有什么,因为现在已经有很多应用于了实践的相似度计算方法,但是你可能不太了解很多任务里面的核心工作就是在进行相似度计算。
比如文本情感分析、文本语义理解、商场系统里面的个性化推荐等等,相似度计算可以独立进行也可以是作为某一项具体任务里面的一部分进行,不同的业务场景里面会需要用到不同的相似度计算策略。
比如:给定两个字符串,想要计算两个字符串之间的相似度,那么可能最好的相似度计算方法就会是字符串的编辑距离了;
给定两个一维的向量数据,想要计算这一对向量之间的相似度,那么可能最直接的相似度计算策略就会是余弦相似度了;
给定两个商品,以及商品各自的很多属性,或者是给定两个人以及每个人各自的性格、兴趣、爱好等等,想要来计算商品或者是人物之间的相似度那么可能最好的相似度计算方法就会是杰卡德相似系数了。
因为Jaccard系数主要用于计算符号度量或布尔值度量的个体间的相似度,因为个体的特征属性都是由符号度量或者布尔值标识,因此无法衡量差异具 体值的大小,只能获得“是否相同”这个结果,所以Jaccard系数只关心个体间共同具有的特征是否一致这个问题。
类似上面的实例还会有很多,简单列举这些知识想说明:在不同的人物场景里面,为了完成特征的计算任务,我们选择的计算策略和方法往往都是不同的。
除此之外,还有距离计算方法可以用来计算相似度
比如:欧式距离、闵可夫斯基距离、切比雪夫距离等等,都是广泛用来计算相似度的工具
本文简单整理了一些统计学中常用的距离计算方法如下:
1、欧几里得距离
欧氏距离(Eucledian Distance)是最常用的距离计算公式,衡量的是多维空间中各个点之间的绝对距离。
2、曼哈顿距离
曼哈顿距离(Manhattan Distance)依赖坐标系统的转度,而非系统在坐标轴上的平移或映射,他是使用在几何度量空间的几何学用语,用以标明两个点在标准坐标系上的绝对轴距总和。
3、切比雪夫距离
在数学中,切比雪夫距离(Chebyshev distance)或是L∞度量,是向量空间中的一种度量,二个点之间的距离定义是其各坐标数值差绝对值的最大值。
以数学的观点来看,切比雪夫距离是由一致范数(uniform norm)(或称为上确界范数)所衍生的度量,也是超凸度量(injective metric space)的一种。
4、明可夫斯基距离(Minkowski distance)
明氏距离是欧氏距离的推广。闵氏距离不是一种距离,而是一组距离的定义。
闵氏距离的定义:两个n维变量a(x11,x12,…,x1n)与b(x21,x22,…,x2n)间的闵可夫斯基距离定义为: 其中p是一个变参数。
当p=1时,就是曼哈顿距离 当p=2时,就是欧氏距离 当p→∞时,就是切比雪夫距离 根据变参数的不同,闵氏距离可以表示一类的距离。
处理上面列举的一些距离方法之外还有一种经典的距离计算方法叫做:编辑距离。
编辑距离经常用于计算字符串之间的差异或者说是相似度,感兴趣的也可以去查一下相关的资料,这里就不再多解释了。
除此之外,还有统计学中的三大相关性系数:皮尔森系数、斯皮尔曼系数和肯德尔系数。
这些都是可以直接拿来计算向量之间的相似度的。另外还可以使用集合来计算相似度,杰卡德系数就是这一方面的实例,两个集合的交集除以两个集合的并集来作为两个集合的相似度。
本文对常用的一些相似度计算方法进行总结实现,具体内容如下:
#!usr/bin/env python #encoding:utf-8 from __future__ import division ''' __Author__:沂水寒城 功能: 相似度度量准则总结实现 ''' import math import numpy as np from scipy.stats import pearsonr,spearmanr,kendalltau import sys reload(sys) sys.setdefaultencoding('utf-8') def pearsonrSim(x,y): ''' 皮尔森相似度 ''' return pearsonr(x,y)[0] def spearmanrSim(x,y): ''' 斯皮尔曼相似度 ''' return spearmanr(x,y)[0] def kendalltauSim(x,y): ''' 肯德尔相似度 ''' return kendalltau(x,y)[0] def cosSim(x,y): ''' 余弦相似度计算方法 ''' tmp=sum(a*b for a,b in zip(x,y)) non=np.linalg.norm(x)*np.linalg.norm(y) return round(tmp/float(non),3) def eculidDisSim(x,y): ''' 欧几里得相似度计算方法 ''' return math.sqrt(sum(pow(a-b,2) for a,b in zip(x,y))) def manhattanDisSim(x,y): ''' 曼哈顿距离计算方法 ''' return sum(abs(a-b) for a,b in zip(x,y)) def minkowskiDisSim(x,y,p): ''' 明可夫斯基距离计算方法 ''' sumvalue=sum(pow(abs(a-b),p) for a,b in zip(x,y)) tmp=1/float(p) return round(sumvalue**tmp,3) def MahalanobisDisSim(x,y): ''' 马氏距离计算方法 ''' npvec1,npvec2=np.array(x),np.array(y) npvec=np.array([npvec1, npvec2]) sub=npvec.T[0]-npvec.T[1] inv_sub=np.linalg.inv(np.cov(npvec1, npvec2)) return math.sqrt(np.dot(inv_sub, sub).dot(sub.T)) def levenshteinDisSim(x,y): ''' 字符串编辑距离、相似度计算方法 ''' res=Levenshtein.distance(x,y) similarity=1-(res/max(len(x), len(y))) return similarity def jaccardDisSim(x,y): ''' 杰卡德相似度计算 ''' res=len(set.intersection(*[set(x),set(y)])) union_cardinality=len(set.union(*[set(x),set(y)])) return res/float(union_cardinality) if __name__=='__main__': x=[1,2,3,4,5] y=[2,4,0,8,9] print 'pearsonrSim:',pearsonrSim(x,y) print 'spearmanrSim:',spearmanrSim(x,y) print 'kendalltauSim:',kendalltauSim(x,y) print 'cosSim:',cosSim(x,y) print 'eculidDisSim:',eculidDisSim(x,y) print 'manhattanDisSim:',manhattanDisSim(x,y) print 'minkowskiDisSim:',minkowskiDisSim(x,y,2) print 'MahalanobisDisSim:',MahalanobisDisSim(x,y) print 'jaccardDisSim:',jaccardDisSim(x,y)
结果如下:
pearsonrSim: 0.7397954428741078
spearmanrSim: 0.7
kendalltauSim: 0.6
cosSim: 0.913
eculidDisSim: 6.78232998313
manhattanDisSim: 14
minkowskiDisSim: 6.782
MahalanobisDisSim: 0.637157868392
jaccardDisSim: 0.25
到此这篇关于关于python实现常用的相似度计算方法的文章就介绍到这了,更多相关python常用相似度计算内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!