Scipy中计算距离的模块是scipy.spatial.distance,最常用的方法是计算距离矩阵,换句话说,从存储在矩形数组中的观测向量集合中进行距离矩阵的计算。
一,两两距离
在n维空间中的观测值,计算两两之间的距离。距离值越大,相关度越小。
scipy.spatial.distance.pdist(X, metric='euclidean', **kwargs)
函数名是Pairwise DISTance的简写,pairwise是指两两的,对于一个二维数组,pdist()计算任意两行之间的距离。
参数注释:
- X:ndarray类型,n维空间中m个观测值构成的 m行*n列 的数组
- metric:计算距离的函数,有效值是 ‘braycurtis’, ‘canberra’, ‘chebyshev’, ‘cityblock’, ‘correlation’, ‘cosine’, ‘dice’, ‘euclidean’, ‘hamming’, ‘jaccard’, ‘jensenshannon’, ‘kulsinski’, ‘mahalanobis’, ‘matching’, ‘minkowski’, ‘rogerstanimoto’, ‘russellrao’, ‘seuclidean’, ‘sokalmichener’, ‘sokalsneath’, ‘sqeuclidean’, ‘yule’
- **kwargs:dick类型,metric的额外参数,大致有:
- p : scalar The p-norm to apply for Minkowski, weighted and unweighted. Default: 2.
- w : ndarray The weight vector for metrics that support weights (e.g., Minkowski).
- V : ndarray The variance vector for standardized Euclidean. Default: var(X, axis=0, ddof=1)
- VI : ndarray The inverse of the covariance matrix for Mahalanobis. Default: inv(cov(X.T)).T
- out : ndarray. The output array If not None, condensed distance matrix Y is stored in this array. Note: metric independent, it will become a regular keyword arg in a future scipy version
二,配对记算距离
从两个输入的集合中配对,计算每对中两个数据集的距离:
scipy.spatial.distance.cdist(XA, XB, metric='euclidean', *args, **kwargs)
XA和XB都是ndarray类型,在n维空间中,XA和XB进行配对,计算一队中两个数据集合之间的距离。
举个例子,XA是8行3列的数组,XB是1行3列的数组,XA的每一行都和XB进行配对,计算对中两个数据之间的距离:
>>> a = np.array([[0, 0, 0], ... [0, 0, 1], ... [0, 1, 0], ... [0, 1, 1], ... [1, 0, 0], ... [1, 0, 1], ... [1, 1, 0], ... [1, 1, 1]]) >>> b = np.array([[ 0.1, 0.2, 0.4]]) >>> distance.cdist(a, b, 'cityblock') array([[ 0.7], [ 0.9], [ 1.3], [ 1.5], [ 1.5], [ 1.7], [ 2.1], [ 2.3]])
三,距离向量和距离矩阵的转换
把向量形式的距离向量表示转换成方形的距离矩阵(dense matrix)形式,也可以把方形的距离矩阵转换为距离向量:
scipy.spatial.distance.squareform(X, force='no', checks=True)
在计算样本集中的样本之间的距离矩阵时,squareform()函数和 pdist()函数经常同时出现, squareform()函数的参数就是 pdist()函数的 的返回值,把 pdist() 返回的一维形式,拓展为矩阵。
举个例子,对于矩阵a,沿对角线对称 ,一般是距离矩阵,对角线元素都为0,
from scipy.spatial import distance as dist a array([[ 0, 2, 3, 4], [ 2, 0, 7, 8], [ 3, 7, 0, 12], [ 4, 8, 12, 0]])
调用函数squareform(),按照a的下三角线的元素一列一列展开成一维数组,首先是下三角的第一列元素,2,3,4;其次是第二列元素7,8;最后是第三列元素12,所以输出v是array([ 2, 3, 4, 7, 8, 12])
v=dist.squareform(a)
v
array([ 2, 3, 4, 7, 8, 12])
相反,把v作为输入参数传递给函数squareform(),得到冗余矩阵b,也就是把数组还原为距离矩阵a。
b=dist.squareform(v) b array([[ 0, 2, 3, 4], [ 2, 0, 7, 8], [ 3, 7, 0, 12], [ 4, 8, 12, 0]])
参考文档: