常见距离的度量及python实现

闵可夫斯基距离(Minkowski Distance)

Minkowski Distance不是一种距离,而是一组距离。两个n维变量A(a1,a2,…,an)与B(b1,b2,…,bn)间的闵可夫斯基距离定义为:

d i s t = ∑ k = 1 n ∣ a k − b k ∣ p p dist = \sqrt[p]{\sum_{k=1}^{n}|a_k-b_k|^p} dist=pk=1nakbkp

其中p是一个变参数,
当p=1时,就是曼哈顿距离
当p=2时,就是欧氏距离
当p→∞时,就是切比雪夫距离

def minkowski_distance(vec1, vec2, p=3):
    """
    
    :param vec1:
    :param vec2:
    :param p:
    :return:
    """
    return np.linalg.norm(vec1 - vec2, ord=p)

def euclidean_distance(vec1, vec2):
    """
    :param vec1:
    :param vec2:
    :return:
    """
    # return np.sqrt(np.sum(np.square(vec1 - vec2)))
    # return sum([(x - y) ** 2 for (x, y) in zip(vec1, vec2)]) ** 0.5
    return np.linalg.norm(vec1 - vec2, ord=2)

def manhattan_distance(vec1, vec2):
    """
    
    :param vec1:
    :param vec2:
    :return:
    """
    # return np.sum(np.abs(vec1 - vec1))
    return np.linalg.norm(vec1 - vec2, ord=1)

def chebyshev_distance(vec1, vec2):
    """
    
    :param vec1:
    :param vec2:
    :return:
    """
    # return np.abs(vec1 - vec2).max()
    return np.linalg.norm(vec1 - vec2, ord=np.inf)

堪培拉距离(Canberra Distance)

Canberra Distance(堪培拉距离)被用来衡量向量空间中两个点之间的距离,它是曼哈顿距离的加权版本。
d i s t ( p , q ) = ∑ k = 1 n ∣ a k − b k ∣ ∣ a k ∣ + ∣ b k ∣ dist(p,q)=\sum_{k=1}^{n} \frac{|a_k - b_k|}{|a_k|+|b_k|} dist(p,q)=k=1nak+bkakbk
通常Canberra distance对于接近于0(大于等于0)的值的变化非常敏感。

import scipy.spatial.distance as dist
def canberra_distance(vec1, vec2):
    """
    
    :param vec1:
    :param vec2:
    :return:
    """
    return dist.pdist(np.array([vec1, vec2]), 'canberra')

余弦距离(Cosine Distance)

夹角余弦可用来衡量两个向量方向的差异。夹角余弦取值范围为[-1,1],夹角余弦越大表示两个向量的夹角越小,夹角余弦越小表示两向量的夹角越大。当两个向量的方向重合时夹角余弦取最大值1,当两个向量的方向完全相反夹角余弦取最小值-1。

两个n维变量A(a1,a2,…,an)与B(b1,b2,…,bn)间的余弦距离为:
c o s ( θ ) = A ⋅ B ∣ A ∣ ∣ B ∣ cos(\theta)=\frac{A \cdot B}{|A||B|} cos(θ)=ABAB

c o s ( θ ) = ∑ k = 1 n a k ⋅ b k ∑ k = 1 n a k 2 ∑ k = 1 n b k 2 cos(\theta)=\frac{\sum_{k=1}^{n}a_k \cdot b_k}{\sqrt{\sum_{k=1}^{n}a_k^2} \sqrt{\sum_{k=1}^{n}b_k^2}} cos(θ)=k=1nak2 k=1nbk2 k=1nakbk

def cosine_distance(vec1, vec2):
    """
    
    :param vec1:
    :param vec2:
    :return:
    """
    vec1_norm = np.linalg.norm(vec1)
    vec2_norm = np.linalg.norm(vec2)
    return vec1.dot(vec2) / (vec1_norm * vec2_norm)

汉明距离(Hamming Distance)

在信息理论中,表示两个等长字符串在对应位置上不同字符的数目,比如:1011101 与 1001001 之间的汉明距离是 2。

def hamming_distance(vec1, vec2):
    """
    
    :param vec1:
    :param vec2:
    :return:
    """
    return np.shape(np.nonzero(vec1 - vec2)[0])[0]

简单匹配距离(Simple Matching Distance)

简单匹配系数(Simple Matching Coefficient,SMC),又称为兰德相似系数(Rand similarity coefficient),是用于比较样本之间相似性与多样性的统计量。

简单匹配距离(Simple Matching Distance,SMD)为1-SMC,用于量度样本集合间的不相似度。

给定两个n维二元向量A、B(A、B的每一维都只能是0或者1),计算简单匹配距离

  1. M00,代表向量A与向量B都是0的维度个数
  2. M01,代表向量A是0而向量B是1的维度个数
  3. M10,代表向量A是1而向量B是0的维度个数
  4. M11,代表向量A和向量B都是1的维度个数

S M D ( A , B ) = 1 − S M C ( A , B ) = 1 − M 00 + M 11 M 00 + M 01 + M 10 + M 11 = M 01 + M 10 M 00 + M 01 + M 10 + M 11 SMD(A,B)=1-SMC(A,B)=1-\frac{M00+M11}{M00+M01+M10+M11}=\frac{M01+M10}{M00+M01+M10+M11} SMD(A,B)=1SMC(A,B)=1M00+M01+M10+M11M00+M11=M00+M01+M10+M11M01+M10

import scipy.spatial.distance as dist
def jaccard_similarity_coefficient(vec1, vec2):
    """
    
    :param vec1:
    :param vec2:
    :return:
    """
    return dist.pdist(np.array([vec1, vec2]), 'matching')

杰卡德距离(Jaccard Distance)

杰卡德相似系数(Jaccard similarity coefficient),是用来衡量两个集合相似度的一种指标,他是两个集合A和B交集元素的个数在A和B并集中所占的比例。

杰卡德距离(Jaccard Distance)是用来衡量两个集合差异性的一种指标,它是杰卡德相似系数的补集,被定义为1减去Jaccard相似系数。

杰卡德距离(用JDist表示),杰卡德系数(用J表示),公式为:
J D i s t ( A , B ) = 1 − J ( A , B ) = 1 − ∣ A ∩ B ∣ ∣ A ∪ B ∣ JDist(A,B) = 1- J(A,B)= 1- \frac{|A \cap B|}{|A \cup B|} JDist(A,B)=1J(A,B)=1ABAB

给定两个n维二元向量A、B(A、B的每一维都只能是0或者1),利用Jaccard相似系数来计算二者的相似性:

  1. M00,代表向量A与向量B都是0的维度个数
  2. M01,代表向量A是0而向量B是1的维度个数
  3. M10,代表向量A是1而向量B是0的维度个数
  4. M11,代表向量A和向量B都是1的维度个数

n维向量的每一维都会落入这4类中的某一类,则Jaccard距离为:
J D i s t ( A , B ) = 1 − J ( A , B ) = 1 − M 11 M 01 + M 10 + M 11 = M 01 + M 10 M 01 + M 10 + M 11 JDist(A,B) = 1- J(A,B)= 1- \frac{M11}{M01+M10+M11} = \frac{M01 + M10}{M01 + M10 + M11} JDist(A,B)=1J(A,B)=1M01+M10+M11M11=M01+M10+M11M01+M10
比如A和B对于4部电影的评价为A(1,1,0,0)和B(1,0,1,0)(PS:1代表喜欢,0代表不喜欢)。可以得到JDist约为0.6667

import scipy.spatial.distance as dist
def jaccard_similarity_coefficient(vec1, vec2):
    """
    
    :param vec1:
    :param vec2:
    :return:
    """
    return dist.pdist(np.array([vec1, vec2]), 'jaccard')

Note

scipy包的 scipy.spatial.distance.pdist() 方法提供了20多种距离函数。

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值