文章目录
- 使用 python计算各种距离
- 前言
- 一、余弦距离
- 二、欧式距离
- 三、哈曼顿距离
- 四、明可夫斯基距离
- 五 切比雪夫距离
- 六 杰卡德距离
- 七、汉明距离
- 八、标准化欧式距离
- 九、皮尔逊相关系数
使用 python计算各种距离
前言
这里主要是学习使用python计算各个距离,分别如下所示
- 余弦距离
- 欧氏距离
- 曼哈顿距离
- 明可夫斯基距离
- 切比雪夫距离
- 杰卡德距离
- 汉明距离
- 标准化欧式距离
- 皮尔逊相关系数
一、余弦距离
- 公式化描述
- 代码实现计算其距离
import numpy as np
# 测试数据
vec1 = [1,2,3,4]
vec2 = [5,6,7,8]
# 方案一
# 根据公式求解
dist1 = np.dot(vec1,vec2)/(np.linalg.norm(vec1)*np.linalg.norm(vec2)) # 根据公式写出计算方程
print('余弦测试距离结果:' + str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
Vec = np.vstack([vec1,vec2])
dist2 = 1-pdist(Vec,'cosine')
print('余弦测试距离结果:' + str(dist2))
- 结果
二、欧式距离
- 公式化描述
欧几里得距离或者欧几里得度量是欧几里得空间中两点间“普通”(直线)距离。使用这个距离,欧式空间成为度量空间。
1:维平面上两点 与
与
3:两点 n 维向量 a 和 b 之间的欧式距离
表示成向量形式就是
- 代码实现
import numpy as np
# 测试数据
vec1 = np.mat([1,2,3,4])
vec2 = np.mat([5,6,7,8])
# 方案一
# 根据公式求解
dist1 = np.sqrt(np.square(vec1-vec2))
print('欧氏距离测试结果是:' + str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
Vec = np.vstack([vec1,vec2])
dist2 = pdist(Vec)
print('欧氏距离测试结果是:' + str(dist1))
- 结果
三、哈曼顿距离
- 公式化描述
用一个例子来说明什么是哈曼顿距离。博主开兰博基尼从四号门到七彩云南第一城,但是那这两者的距离不是直线距离,而博主行驶的实际距离就称为哈曼顿距离。
与
与
- 代码
import numpy as np
# 测试数据
vec1 = np.mat([1,2,3,4])
vec2 = np.mat([5,6,7,8])
# 方案一
# 根据公式求解
dist1 = np.sum(np.abs(vec1-vec2))
print('曼哈顿距离测试结果是:' + str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
Vec = np.vstack([vec1,vec2])
dist2 = pdist(Vec,'cityblock')
print('曼哈顿距离测试结果是:' + str(dist2))
# 方案三
from numpy import *
dist3 = sum(abs(vec1-vec2))# abs()绝对值
print('曼哈顿距离测试结果是:' + str(dist3))
- 结果
四、明可夫斯基距离
- 公式化描述
明氏距离也就是明可夫斯基距离,是欧式空间中的一种测度,被看做欧式距离和哈曼顿距离的一种推广。
与
或者可以写成
其中 p 是一个参数
A: 当 p = 1 时,就是曼哈顿距离
B: 当 p = 2 时,就是欧式距离
C: 当 p =
- 代码
import numpy as np
# 测试数据
# sqrt() 函数时开方
# sum() 函数时求和
# square() 函数时绝对值
vec1 = np.mat([1,2,3,4])
vec2 = np.mat([5,6,7,8])
# 方案一
# 根据公式求解 p=2
dist1 = np.sqrt(np.sum(np.square(vec1-vec2)))
print('当P=2时就是欧氏距离,测试结果是:' + str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
Vec = np.vstack([vec1,vec2])
dist2 = pdist(Vec,'cityblock',p=1)
print('当P=1时就是曼哈顿距离,测试结果是:' + str(dist2))
# 方案三
# 根据公式求解,p=1
from numpy import *
dist3 = sum(abs(vec1-vec2))# abs()绝对值
print('当p=1时就是曼哈顿距离,测试结果是:' + str(dist3))
- 结果
五 切比雪夫距离
- 公式化描述
通俗的来讲,切比雪夫距离就是两个点,各自代表一个坐标(二维,多维),各自的坐标点数值差的最大值,就是二点之间的距离。比如二维坐标 和 ,其切比雪夫距离就是
与 之间的切比雪夫距离
与
还可以表示为
- 代码
import numpy as np
# 测试数据
# sqrt() 函数时开方
# sum() 函数时求和
# square() 函数时绝对值
vec1 = np.mat([1,2,3,4])
vec2 = np.mat([5,6,7,8])
# 方案一
# 根据公式求解
dist1 = np.max(np.abs(vec1-vec2))
print('切比雪夫距离测试结果是:' + str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
Vec = np.vstack([vec1,vec2])
dist2 = pdist(Vec,'chebyshev')
print('切比雪夫距离测试结果是:' + str(dist2))
- 结果
六 杰卡德距离
杰卡德距离:用两个集合中不同元素占所有元素的比例来衡量两个集合的区分度。
杰卡德相似系数:两个集合 和 的交集元素在 的并集中所占的比例,称为两个集合的n杰卡德相似系数,用符号 表示。
杰卡德距离,系数的应用: 在衡量样本的相似度时可以使用杰卡德相似系列来实现。样本 和样本是两个n维向量,而且所有维度的取值都是0或1.例如: 和
- 公式化描述
杰卡德相似系数公式
杰卡德距离
- 代码
import numpy as np
# 测试数据
# sqrt() 函数时开方
# sum() 函数时求和
# square() 函数时绝对值
# 生成10个大于0.5的随机数
v1 = np.random.random(10)>0.5
v2 = np.random.random(10)>0.5
# 将输入数值转化为矩阵形式
vec1 = np.asarray(v1,np.int32)
vec2 = np.asarray(v2,np.int32)
# 方案一
# 根据公式求解
up = np.double(np.bitwise_and((vec1!=vec2),np.bitwise_or(vec1!=0,vec2!=0)).sum())
down = np.double(np.bitwise_or(vec1!=0,vec2!=0).sum())
dist1=(up/down)
print("杰卡德距离测试结果是:"+str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
Vec = np.vstack([vec1,vec2])
dist2 = pdist(Vec,'jaccard')
print("杰卡德距离测试结果是:"+str(dist2))
- 结果
七、汉明距离
在信息论中,两个等长的字符串之间的汉明距离就是这两个字符串对应位置的不同字符的个数。换言之,它就是将一个字符串转换为另外一个字符串所需要替换的字符个数。
- 公式化描述
1:11110234 与 11134468 之间的汉明距离是 5
2:438585 与 446468 之间的汉明距离是 5
3:jiajikang 与 jiadandan 之间的汉明距离是 6 - 代码
import numpy as np
# 测试数据
# sqrt() 函数时开方
# sum() 函数时求和
# square() 函数时绝对值
# 生成10个大于0.5的随机数
v1 = np.random.random(10)>0.5
v2 = np.random.random(10)>0.5
# 将输入数值转化为矩阵形式
vec1 = np.asarray(v1,np.int32)
vec2 = np.asarray(v2,np.int32)
# 方案一
# 根据公式求解
dist1 = np.mean(vec1!=vec2)
print("汉明距离测试结果是:\t"+str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
Vec = np.vstack([vec1,vec2])
dist2 = pdist(Vec,'hamming')
print("汉明距离测试结果是:"+str(dist2))
- 结果
八、标准化欧式距离
标准化欧式距离是针对于简单欧氏距离的缺点而做的一种改进方案。
标准化欧式距离思路:既然数据各维度分量的分布不一样,那先将各个分量都“标准化”到均值,方差相等。 假设样本集合X的均值为m,标准差为s,那么 X 的 “标准化变量” 表示为
标准化后的值 = (标准化前的值-分量的均值)/ 分量的标准差 。
- 公式化描述
两个 n 维向量 与
- 代码
import numpy as np
# 测试数据
# sqrt() 函数时开方
# sum() 函数时求和
# square() 函数时绝对值
# 生成10个大于0.5的随机数
v1 = np.random.random(10)>0.5
v2 = np.random.random(10)>0.5
# 将输入数值转化为矩阵形式
vec1 = np.array(v1,np.int32)
vec2 = np.array(v2,np.int32)
Vec = np.vstack([vec1,vec2])
# 方案一
# 根据公式求解
sk = np.var(Vec,axis=0,ddof=1)
dist1 = np.sqrt(((vec1-vec2) ** 2/sk).sum())
print('标准化欧式距离测试结果:'+str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
dist2 = pdist(Vec,'seuclidean')
print('标准化欧式距离测试结果:'+str(dist2))
- 结果
九、皮尔逊相关系数
和
- 公式化描述
计算相关系数:
- 代码
import numpy as np
# 测试数据
# sqrt() 函数时开方
# sum() 函数时求和
# square() 函数时绝对值
# 生成10个大于0.5的随机数
v1 = np.random.random(10)>0.5
v2 = np.random.random(10)>0.5
# 将输入数值转化为矩阵形式
vec1 = np.array(v1,np.int32)
vec2 = np.array(v2,np.int32)
# Vec = np.vstack([vec1,vec2])
# 方案一
# 根据公式求解
vec1_ = vec1-np.mean(vec1)
vec2_ = vec2-np.mean(vec2)
dist1 = np.dot(vec1_,vec2_)/(np.linalg.norm(vec1_)*np.linalg.norm(vec2_))
print("皮尔逊相关系数测试结果:" + str(dist1))
# 方案二
# 根据scipy库求解
from scipy.spatial.distance import pdist
Vec = np.vstack([vec1,vec2])
dist2 = np.corrcoef(Vec)[0][1]
print("皮尔逊相关系数测试结果:" + str(dist2))
- 结果