首页 > 解决方案 > 使用 scipy 的 cdist 函数时无法计算马氏距离

问题描述

我想计算矩阵的每一行与单行向量之间的马氏距离。最初,我曾经np.tile创建一个包含多个向量副本的矩阵,以创建一个形状相同的矩阵,然后用于sklearn.metrics.pairwise.paired_distances逐行计算距离。

我想知道是否有更易读的替代方案,这就是我几周前问这个问题的原因。用户Divakar想出了使用cdist(a,b).ravel(). 我发现这个替代方案更具可读性,因此使用了它。我测试了这两个函数,metric='euclidean'发现它们产生了相同的结果。但是,当我将指标切换到metric='mahalanobis'(我现在想使用)时,第一种方法似乎有效,但cdist另一种方法会引发以下错误:

ValueError:观察次数(3)太小;协方差矩阵是奇异的。对于 3 个维度的观测,至少需要 4 个观测。

有人可以解释这里发生了什么吗?为什么在使用欧几里德距离时函数给出相同的结果,但在使用马氏距离时却没有?

这是我的代码:

import numpy as np
from sklearn.metrics.pairwise import paired_distances
from scipy.spatial.distance import cdist

# get matrix a and vector b
a = np.array([[1,2,3],[4,5,6]])
b = np.array([[7],[8],[9]]).transpose()

# define metric
METRIC = 'mahalanobis'

# define distance function that computes the distance between each row of a matrix
# and another matrix that contains duplicates of the single input vector.
def vector_to_matrix_distance(matrix_array,vector_array,metric):
    vector_array_tiled = np.tile(vector_array,(matrix_array.shape[0],1))
    return paired_distances(matrix_array,vector_array_tiled)

# run distance function
distances_1 = vector_to_matrix_distance(matrix_array=a,
                                     vector_array=b,
                                     metric=METRIC)

# Use cdist to do the SAME calculation.This works when METRIC = 'euclidean' but
# not when METRIC = 'mahalanobis'
distances_2 = cdist(a,b,metric=METRIC).ravel()

标签: pythonnumpyscikit-learnscipydistance

解决方案


推荐阅读