【python】计算数学中各种距离

版权声明:可以转载奥 https://blog.csdn.net/Jiajikang_jjk/article/details/83474446

使用 python计算各种距离

前言

     这里主要是学习使用python计算各个距离,分别如下所示

  1. 余弦距离
  2. 欧氏距离
  3. 曼哈顿距离
  4. 明可夫斯基距离
  5. 切比雪夫距离
  6. 杰卡德距离
  7. 汉明距离
  8. 标准化欧式距离
  9. 皮尔逊相关系数

一、余弦距离

  • 公式化描述
                                                                           c o s θ = a × b a × a cos\theta=\frac{\overrightarrow{a}\times\overrightarrow{b}}{|\overrightarrow{a}|\times|\overrightarrow{a}|}
  • 代码实现计算其距离
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:维平面上两点 a ( x 1 , y 1 ) a(x_1,y_1) b ( x 2 , y 2 ) b(x_2,y_2) 间的欧式距离

                                                   d 12 = ( x 1 x 2 ) 2 + ( y 1 y 2 ) 2 d_{12}=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2}

        2:三维空间两点 a ( x 1 , y 1 , z 1 ) a(x_1,y_1,z_1) b ( x 2 , y 2 , z 2 ) b(x_2,y_2,z_2) 间的欧式距离

                                                   d 12 = ( x 1 x 2 ) 2 + ( y 1 y 2 ) 2 + ( z 1 z 2 ) 2 d_{12}=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2+(z_1-z_2)^2}

        3:两点 n 维向量 a 和 b 之间的欧式距离

                                                   d 12 = ( x 1 x 2 ) 2 + ( y 1 y 2 ) 2 + . . . + ( x n y n ) 2 = i = 1 n ( x i y i ) 2 d_{12}=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2+...+(x_n-y_n)^2}=\sqrt{\sum_{i=1}^{n}(x_i-y_i)^2}

         表示成向量形式就是
                                                   d 12 = ( a b ) ( a b ) T d_{12}=\sqrt{(a-b)(a-b)^T}

  • 代码实现
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))
  • 结果

在这里插入图片描述

三、哈曼顿距离

  • 公式化描述
           用一个例子来说明什么是哈曼顿距离。博主开兰博基尼从四号门到七彩云南第一城,但是那这两者的距离不是直线距离,而博主行驶的实际距离就称为哈曼顿距离。

       1:二维平面两点 a ( x 1 , y 1 ) a(x_1,y_1) b ( x 1 , y 1 ) b(x_1,y_1) 之间的哈曼顿距离

                                                   d 12 = ( x 1 x 2 ) + ( y 1 y 2 ) d_{12}=|(x_1-x_2)+|(y_1-y_2)|

       2:两个 n 维向量 a ( x 1 , x 2 ) , x 3 , x 4 , . . . x n a(x_1,x_2),x_3,x_4,...x_n b ( y 1 , y 2 , y 3 , . . . y n ) b(y_1,y_2,y_3,...y_n) 之间的哈曼顿距离

                                                   d 12 = i = 1 n ( x i y i ) d_{12}=\sum_{i=1}^{n}|(x_i-y_i)|

  • 代码
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))
  • 结果
    在这里插入图片描述

四、明可夫斯基距离

  • 公式化描述
           明氏距离也就是明可夫斯基距离,是欧式空间中的一种测度,被看做欧式距离和哈曼顿距离的一种推广。

       1:两个 n 维向量 a ( x 1 , x 2 ) , x 3 , x 4 , . . . x n a(x_1,x_2),x_3,x_4,...x_n b ( y 1 , y 2 , y 3 , . . . y n ) b(y_1,y_2,y_3,...y_n) 之间的哈曼顿距离

                                                   d 12 = p i = 1 n x i y i p d_{12}=p\sqrt{\sum_{i=1}^{n}|x_i-y_i|^p} 或者可以写成 d 12 = ( i = 1 n x i y i p ) 1 p d_{12}=(\sum_{i=1}^{n}|x_i-y_i|^p)^{\frac{1}{p}}

        其中 p 是一个参数
        A: 当 p = 1 时,就是曼哈顿距离
        B: 当 p = 2 时,就是欧式距离
        C: 当 p = n n \to \infty 时,就是切比雪夫距离

  • 代码
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))

  • 结果
    在这里插入图片描述

五 切比雪夫距离

  • 公式化描述
           通俗的来讲,切比雪夫距离就是两个点,各自代表一个坐标(二维,多维),各自的坐标点数值差的最大值,就是二点之间的距离。比如二维坐标 ( x 1 , y 1 ) (x_1,y_1) ( x 2 , y 2 ) (x_2,y_2) ,其切比雪夫距离就是 m a x ( x 2 x 1 , y 2 y 1 ) max(|x_2-x_1|,|y_2-y_1|)

       1:二维平面两点 a ( x 1 , y 1 ) a(x_1,y_1) b ( x 2 , y 2 ) b(x_2,y_2) 之间的切比雪夫距离
                                                   d 12 = m a x ( x 1 x 2 , y 2 y 1 ) d_{12=max(|x_1-x_2|,|y_2-y_1|)}

       2:两个 n 维向量 a ( x 1 , x 2 ) , x 3 , x 4 , . . . x n a(x_1,x_2),x_3,x_4,...x_n b ( y 1 , y 2 , y 3 , . . . y n ) b(y_1,y_2,y_3,...y_n) 之间的切比雪夫距离

                                                   d 12 = m a x i ( x i y i ) d_{12=max_i(|x_i-y_i|)} 还可以表示为 d 12 = lim n ( i = 1 n x i y i k ) 1 k d_{12}=\lim_{n \to \infty}(\sum_{i=1}^{n}|x_i-y_i|^k)^{}\frac{1}{k}

  • 代码
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))
  • 结果
    在这里插入图片描述

六 杰卡德距离

杰卡德距离:用两个集合中不同元素占所有元素的比例来衡量两个集合的区分度。
杰卡德相似系数:两个集合 A A B B 的交集元素在 A , B A,B 的并集中所占的比例,称为两个集合的n杰卡德相似系数,用符号 J ( A , B ) J(A,B) 表示。
杰卡德距离,系数的应用: 在衡量样本的相似度时可以使用杰卡德相似系列来实现。样本 A A 和样本 B B 是两个n维向量,而且所有维度的取值都是0或1.例如 A ( 0111 ) A(0111) B ( 1011 ) B(1011) .将样本看做是一个集合,1表示集合包含该元素,0表示集合不包含该元素。

  • 公式化描述
    杰卡德相似系数公式
                                                       J ( A , B ) = A B A B J(A,B)=\frac{A\bigcap B}{A\bigcup B}
    杰卡德距离
                                                       J ψ ( A , B ) = 1 J ( A , B ) = A B A B A B J_\psi(A,B)=1-J(A,B)=\frac{A\bigcup B-A\bigcap B}{A\bigcup B}

  • 代码

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 的 “标准化变量” 表示为

                                                   X = X m s X^*=\frac{X-m}{s}

标准化后的值 = (标准化前的值-分量的均值)/ 分量的标准差 。

  • 公式化描述
    两个 n 维向量 a ( x 1 , x 2 , x 3 , . . . x n ) a(x_1,x_2,x_3,...x_n) b ( y 1 , y 2 , y 3 , . . . y n ) b(y_1,y_2,y_3,...y_n) 之间的标准化欧氏距离的公式:

                                                   d 12 = k = 1 n ( x i y i S k ) 2 d_{12}=\sqrt{\sum_{k=1}^{n}(\frac{x_i-y_i}{S_k})^2}

  • 代码

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))
  • 结果
    在这里插入图片描述

九、皮尔逊相关系数

       在统计学中,皮尔逊积矩相关系数用于度量两个变量 X X Y Y 之间的相关程度(线性相关),其值介于-1和1之间。在自然科学领域,该系数广泛用于度量两个变量之间的相关程度。

  • 公式化描述

       计算相关系数:
                                                   C o r r ( x , y ) = i ( x i y i ) ( y i y ) ( x i x ) 2 ( y i y ) 2 = < x x , y y > x x y y > Corr(x,y)=\frac{\sum_i(x_i-y_i)(y_i-\overrightarrow{y})}{\sqrt{\sum(x_i-\overrightarrow x)^2\sqrt{\sum{(y_i-\overrightarrow{y})^2}}}}=\frac{<x-\overrightarrow{x,}y-\overrightarrow{y}>}{||x-\overrightarrow{x}||||y-\overrightarrow{y>}||}

  • 代码
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))
  • 结果
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Jiajikang_jjk/article/details/83474446