scipy.spatial 模块提供了距离计算模块 - scipy.spatial.distance.
1. 距离度量函数
两个向量 u 和 v 间的距离度量函数. 输入参数 u 和 v 分别都是 n-dim 的向量,也可以是 (1, n)-dim 的(计算时会自动 squeeze 去掉维度为 1 的维度). 如果维度大于 1, 则出错.
1.1. 距离函数列表(数值)
两个数值向量 u 和 v 间的距离度量函数. 不过,直接采用如下函数计算较大规模的向量集合时,会比较低效的,此时可采用 pdist
函数.(Computing distances over a large collection of vectors is inefficient for these functions).
序号 | 函数名 | 函数说明 |
---|---|---|
1 | braycurtis (u, v[, w]) | 计算两个 1-D 数组间的 Bray-Curtis distance |
2 | canberra (u, v[, w]) | 计算两个 1-D 数组间的 Canberra distance |
3 | chebyshev (u, v[, w]) | 计算 Chebyshev distance |
4 | cityblock (u, v[, w]) | 计算 City Block (Manhattan) distance |
5 | correlation (u, v[, w, centered] | 计算 u 和 v 之间的相关系数 |
6 | cosine (u, v[, w]) | 计算两个 1-D 数组间的 Cosine distance |
7 | euclidean (u, v[, w]) | 计算两个 1-D 数组间的 Euclidean distance |
8 | jensenshannon (p, q[, base]) | 计算两个 1-D 数组间的 Jensen-Shannon distance (metric) |
9 | mahalanobis (u, v, VI) | 计算两个 1-D 数组间的 Mahalanobis distance |
10 | minkowski (u, v[, p, w]) | 计算两个 1-D 数组间的 Minkowski distance |
11 | seuclidean (u, v, V) | 计算两个 1-D 数组间的 standardized Euclidean distance |
12 | sqeuclidean (u, v[, w]) | 计算两个 1-D 数组间的 squared Euclidean distance |
13 | wminkowski (u, v, p, w) | 计算两个 1-D 数组间的 weighted Minkowski distance |
1.2. 距离函数列表(二值向量)
两个二值向量(boolean vectors) u 和 v 间的距离度量函数. 同样地,对于较大规模的向量集合的距离计算,pdist
效率更高.
序号 | 函数名 | 函数说明 |
---|---|---|
1 | dice (u, v[, w]) | 计算两个 1-D 布尔向量间的 Dice dissimilarity |
2 | hamming (u, v[, w]) | 计算两个 1-D 向量间的 Hamming distance |
3 | jaccard (u, v[, w]) | 计算两个 1-D 布尔向量间的 Jaccard-Needham dissimilarity |
4 | kulsinski (u, v[, w]) | 计算两个 1-D 布尔向量间的 Kulsinski dissimilarity |
5 | rogerstanimoto (u, v[, w]) | 计算两个 1-D 布尔向量间的 Rogers-Tanimoto dissimilarity |
6 | russellrao (u, v[, w]) | 计算两个 1-D 布尔向量间的 Russell-Rao dissimilarity |
7 | sokalmichener (u, v[, w]) | 计算两个 1-D 布尔向量间的 Sokal-Michener dissimilarity |
8 | sokalsneath (u, v[, w]) | 计算两个 1-D 布尔向量间的 Sokal-Sneath dissimilarity |
9 | yule (u, v[, w]) | 计算两个 1-D 布尔向量间的 Yule dissimilarity |
注:hamming
也可以用于离散数值向量间的距离度量.
1.3. cosine
计算两个 1-D 数组间的 Cosine 距离.
scipy.spatial.distance.cosine(u, v, w=None)
# u - 输入数组
# v - 输入数组
# w - u 和 v 中每个元素值的权重. 默认为 None,每个元素值的权重为 1.0
向量 u 和 v 间的余弦距离,计算公式为:
$$ dist = 1 - \frac{u \cdot v}{||u||_2 ||v||_2} $$
其中,$u \cdot v$ 为 u 和 v 的点积(dot product).
如:
from scipy.spatial import distance
distance.cosine([1, 0, 0],
[0, 1, 0])
# 1.0
distance.cosine([100, 0, 0],
[0, 1, 0])
# 1.0
distance.cosine([1, 1, 0],
[0, 1, 0])
# 0.29289321881345254
1.4. euclidean
计算两个 1-D 数组间的欧式距离.
scipy.spatial.distance.euclidean(u, v, w=None)
向量 u 和 v 间的欧式距离,计算公式为:
$$ dist = ||u - v||_2 = \sqrt{\sum(w_i|(u_i - v_i)|^2)} $$
如:
from scipy.spatial import distance
distance.euclidean([1, 0, 0],
[0, 1, 0])
# 1.4142135623730951
distance.euclidean([1, 1, 0],
[0, 1, 0])
# 1.0
1.5. dice
计算两个 1-D 二值向量间的 Dice 不相似性.
scipy.spatial.distance.dice(u, v, w=None)
向量 u 和 v 间的欧式距离,计算公式为:
$$ dice\_dissimilarity = \frac{c_{TF} + c_{FT}}{2c_{TT} + c_{FT} + c_{TF}} $$
其中,$c_{ij}$ 为 k<n 时 u[k]=i 和 v[k]=j 出现的频次.
如:
from scipy.spatial import distance
distance.dice([1, 0, 0],
[0, 1, 0])
# 1.0
distance.dice([1, 0, 0],
[1, 1, 0])
# 0.3333333333333333
distance.dice([1, 0, 0],
[2, 0, 0])
#-0.3333333333333333
1.6. hamming
计算两个 1-D 向量间的 hamming 距离.
向量 u 和 v 间的 hamming 距离是 u 和 v 之间的元素不一致性的比例. 如果 u 和 v 是二值向量,Hamming 距离的计算公式为:
$$ hamming\_dist = \frac{c_{01} + c_{10}}{n} $$
其中,$c_{ij}$ 为 k<n 时 u[k]=i 和 v[k]=j 出现的频次.
如:
from scipy.spatial import distance
distance.hamming([1, 0, 0],
[0, 1, 0])
# 0.66666666666666663
distance.hamming([1, 0, 0],
[1, 1, 0])
# 0.33333333333333331
distance.hamming([1, 0, 0],
[2, 0, 0])
# 0.33333333333333331
distance.hamming([1, 0, 0],
[3, 0, 0])
# 0.33333333333333331
2. 距离计算函数
以矩阵数据形式保存的向量集合见得距离矩阵计算(Distance matrix computation from a collection of raw observation vectors stored in a rectangular array.).
矩阵的每行表示一个观测向量值,计算结果为每行之间的距离.
scipy.spatial.distance 提供了几种距离计算函数:pdist, cdist, directed_hausdorff.
2.1. pdist
计算 n-dim 空间中观测值之间的成对距离(pairwise distances). 距离值越大,相关度越小.
定义如:
Y = scipy.spatial.distance.pdist(X, metric='euclidean', *args, **kwargs)
参数说明:
[1] - X
- n-dim 空间中 m 个观察值组成的 mxn 的数组.
[2] - metric
- 字符串或函数. 距离度量函数.
[3] - Y
- 距离矩阵. 对于每个 i 和 j,其中,i<j<m,m 为观察值数(样本数). 计算 dist(u=X[i], v=X[j])
度量值,并保存于 Y[ij]
.
注:距离转换成相似度时,由于样本自身之间的距离是不会计算的默认为0,故要先通过dist = spatial.distance.squareform(dist)转换成dense矩阵,再通过1 - dist计算相似度.
如:
参考:利用scipy求距离矩阵
import numpy as np
from scipy.spatial.distance import pdist
from scipy.spatial.distance import squareform
A=np.array([[1,2],
[3,4],
[5,6],
[7,8]])
# A是一个向量矩阵,distA 为数组形式
distA = pdist(A,metric='euclidean')
#array([2.82842712,
# 5.65685425,
# 8.48528137,
# 2.82842712,
# 5.65685425,
# 2.82842712])
# 将 distA 数组变成一个矩阵
distB = squareform(distA)
#array([[0. , 2.82842712, 5.65685425, 8.48528137],
# [2.82842712, 0. , 2.82842712, 5.65685425],
# [5.65685425, 2.82842712, 0. , 2.82842712],
# [8.48528137, 5.65685425, 2.82842712, 0. ]])
不同的距离度量方式,pdist
函数使用如:
2.2. cdist
计算两个输入集合(如,矩阵A和矩阵B)间每个向量对之间的距离.
Y = scipy.spatial.distance.cdist(XA, XB, metric='euclidean', *args, **kwargs)
返回值 Y
- 距离矩阵. 对于每个 i 和 j,计算 dist(u=XA[i], v=XB[j])
度量值,并保存于 Y[ij]
.
其他类似于 pdist
. Y[ij] 表示 A 中第 i 个向量到B中第 j 向量的距离.
如:
import numpy as np
from scipy.spatial.distance import cdist
A=np.array([[1,2],
[3,4],
[5,6]])
B=np.array([[7,8],
[9,10]])
distAB = cdist(A,B,metric='euclidean')
#array([[ 8.48528137, 11.3137085 ],
# [ 5.65685425, 8.48528137],
# [ 2.82842712, 5.65685425]])
2.3. squareform
将向量形式(vector-form) 距离向量转换方形(square-form) 距离矩阵. 反之.
scipy.spatial.distance.squareform(X, force='no', checks=True)