机器学习领域 几种距离度量方法【2】

七、巴氏距离(Bhattacharyya Distance

八、余弦距离(Cosine Distance)

汉明距离(Hamming Distance)

杰卡德距离(Jaccard Distance)

十一相关距离(Correlation distance)

十二、卡方距离(Chi-square measure)

巴氏距离(Bhattacharyya Distance

在统计中,Bhattacharyya距离测量两个离散或连续概率分布的相似性。它与衡量两个统计样品或种群之间的重叠量的Bhattacharyya系数密切相关。Bhattacharyya距离和Bhattacharyya系数以20世纪30年代曾在印度统计研究所工作的一个统计学家A. Bhattacharya命名。同时,Bhattacharyya系数可以被用来确定两个样本被认为相对接近的,它是用来测量中的类分类的可分离性

 

对于离散概率分布 p和q在同一域 X,巴氏距离被定义为:

 

其中BC(p,q)是Bhattacharyya系数:

 

对于连续概率分布,Bhattacharyya系数被定义为:

因此,求得巴氏系数之后,就可以求得巴氏距离。

代码实现:

import numpy as np

p = np.asarray([0.65, 0.25, 0.07, 0.03])
q = np.array([0.6, 0.25, 0.1, 0.05])

BC = np.sum(np.sqrt(p * q))

# Hellinger距离:
h = np.sqrt(1 - BC)

# 巴氏距离:
b = -np.log(BC)
print(b)

余弦距离(Cosine Distance)

几何中,夹角余弦可用来衡量两个向量方向的差异;通常借用这一概念来衡量样本向量之间的差异

向量,是多维空间中有方向的线段,如果两个向量的方向一致,即夹角接近零,那么这两个向量就相近。而要确定两个向量方向是否一致,这就要用到余弦定理计算向量的夹角。

二维空间中向量A(x1,y1)与向量B(x2,y2)的夹角余弦公式:

两个n维样本点a(x11,x12,…,x1n)和b(x21,x22,…,x2n)的夹角余弦为:

即:

夹角余弦取值范围为[-1,1]。余弦越大表示两个向量的夹角越小,余弦越小表示两向量的夹角越大。当两个向量的方向重合时余弦取最大值1,当两个向量的方向完全相反余弦取最小值-1当两条新闻向量夹角余弦等于1时,这两条新闻完全重复(用这个办法可以删除爬虫所收集网页中的重复网页);当夹角的余弦值接近于1时,两条新闻相似(可以用作文本分类);夹角的余弦越小,两条新闻越不相关。

举一个具体的例子,假如新闻X和新闻Y对应向量分别是:x1, x2, ..., x6400和y1, y2, ..., y6400则,它们之间的余弦距离可以用它们之间夹角的余弦值来表示:

 

代码实现:

import numpy as np

x = np.random.random(10)
y = np.random.random(10)

# 方法一:根据公式求解
# np.linalg.norm求范数,默认是第二范数,即算数平方根
d1 = np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))

# 方法二:根据scipy库求解
from scipy.spatial.distance import pdist

X = np.vstack([x, y])
d2 = 1 - pdist(X, 'cosine')
print(d1)
print(d2)

汉明距离(Hamming Distance)

定义:两个等长字符串s1s2之间的汉明距离定义为将其中一个变为另外一个所需要作的最小替换次数。例如字符串“1111”与“1001”之间的汉明距离为2

汉明重量:是字符串相对于同样长度的零字符串的汉明距离,也就是说,它是字符串中非零的元素个数:对于二进制字符串来说,就是 1 的个数,所以 11101 的汉明重量是 4。因此,向量空间中的元素ab之间的汉明距离等于它们汉明重量的差a-b

应用:汉明重量分析在包括信息论、编码理论、密码学等领域都有应用。比如在信息编码过程中,为了增强容错性,应使得编码间的最小汉明距离尽可能大。但是,如果要比较两个不同长度的字符串,不仅要进行替换,而且要进行插入与删除的运算,在这种场合下,通常使用更加复杂的编辑距离等算法。

import numpy as np

from scipy.spatial.distance import pdist

x = np.random.random(10) > 0.5
y = np.random.random(10) > 0.5

x = np.asarray(x, np.int32)
y = np.asarray(y, np.int32)

# 方法一:根据公式求解
d1 = np.mean(x != y)

# 方法二:根据scipy库求解
X = np.vstack([x, y])
d2 = pdist(X, 'hamming')
print(d1)
print(d2)

杰卡德距离(Jaccard Distance)

(1)卡德相似系数
       两个集合A和B的交集元素在A,B的并集中所占的比例,称为两个集合的杰卡德相似系数,用符号J(A,B)表示

(2)杰卡德距离
 
 卡德相似系数是衡量两个集合的相似度一种指标
   杰卡德相似系数相反的概念是杰卡德距离(Jaccard distance)。杰卡德距离可用如下公式表示

杰卡德距离用两个集合中不同元素占所有元素的比例来衡量两个集合的区分度。

(3)杰卡德相似系数与杰卡德距离的应用           
          将杰卡德相似系数用在衡量样本的相似度上。
          样本A与样本B是两个n维向量,而且所有维度的取值都是0或1。例如:A(0111)和B(1011)。我们将样本看成是一个集合,1表示集合包含该元素,0表示集合不包含该元素。

代码实现:

import numpy as np
from scipy.spatial.distance import pdist

x = np.random.random(10) > 0.5
y = np.random.random(10) > 0.5

x = np.asarray(x, np.int32)
y = np.asarray(y, np.int32)

# 方法一:根据公式求解
up = np.double(np.bitwise_and((x != y), np.bitwise_or(x != 0, y != 0)).sum())
down = np.double(np.bitwise_or(x != 0, y != 0).sum())
d1 = (up / down)

# 方法二:根据scipy库求解
X = np.vstack([x, y])
d2 = pdist(X, 'jaccard')

print(d1)
print(d2)

相关距离(Correlation distance)

提到相关距离,首先介绍一下皮尔逊相关系数

皮尔逊相关系数的定义
                                                                              

前面提到的余弦相似度只与向量方向有关,但它会受到向量的平移影响,在夹角余弦公式中如果将 x 平移到 x+1, 余弦值就会改变。怎样才能实现平移不变性?这就要用到皮尔逊相关系数(Pearson correlation),有时候也直接叫相关系数

 

如果将夹角余弦公式写成

表示向量x和向量y之间的夹角余弦,则皮尔逊相关系数则可表示为

皮尔逊相关系数具有平移不变性和尺度不变性,计算出了两个向量(维度)的相关性。

相关距离:  

代码实现:

import numpy as np

x = np.random.random(10)
y = np.random.random(10)

# 马氏距离要求样本数要大于维数,否则无法求协方差矩阵
# 此处进行转置,表示10个样本,每个样本2维
X = np.vstack([x, y])

# 方法一:根据公式求解
S = np.cov(X)  # 两个维度之间协方差矩阵

bottom = (np.linalg.norm(x) * np.linalg.norm(y))
d1 = 1 - S/bottom

# 方法二:根据scipy库求解
from scipy.spatial.distance import pdist
d2 = pdist(X, 'correlation')

print(d2)

卡方距离(Chi-square measure)

代码实现:

import numpy as np
from scipy.stats import chisquare

list_observe = np.array([30, 14, 34, 45, 57, 20])
list_expect = np.array([20, 20, 30, 40, 60, 30])

# 方法一:根据公式求解(最后根据c1的值去查表判断)
c1 = np.sum(np.square(list_observe - list_expect) / list_expect)

# 方法二:使用scipy库来求解
c2, p = chisquare(f_obs=list_observe, f_exp=list_expect)
print(c1)
'''
返回NAN,无穷小
'''
if p > 0.05 or p == "nan":
    print("H0 win,there is no difference")
else:
    print("H1 win,there is difference")

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值