python中的Mahalanabois距离返回矩阵而不是距离

时间:2016-03-04 05:06:44

标签: python numpy math

这应该是一个简单的问题,要么我缺少信息,要么我错误地编码了这个。

我正在尝试在python中实现Mahalanabois距离,我将从python中的公式中进行跟踪。

我的代码如下:

a = np.array([[1, 3, 5]])
b = np.array([[4, 5, 6]])

X = np.empty((0,3), float)
X = np.vstack([X, [2,3,4]])
X = np.vstack([X, a])
X = np.vstack([X, b])

n = ((a-b).T)*(np.cov(X)**-1)*(a-b)
dist = np.sqrt(n)

dist返回一个3x3数组,但我不应该期望一个代表距离的数字吗?

dist = array([[ 1.5       ,  1.73205081,  1.22474487],
       [ 1.73205081       ,  2.        ,  1.41421356],
       [ 1.22474487       ,  1.41421356,  1.        ]])

维基百科没有建议(对我来说)它应该返回一个矩阵。谷歌搜索mahalanbois距离的实现我还没有找到可以比较它的东西。

1 个答案:

答案 0 :(得分:2)

从维基page您可以看到,ab是向量,但在您的情况下,它们是数组。所以你需要反向移调。而且应该有矩阵乘法。 numpy *表示逐元素乘法,对于矩阵,您应该使用.dot的{​​{1}}函数或np.array方法。对于您的情况,答案是:

n = (a-b).dot((np.cov(X)**-1).dot((a-b).T))
dist = np.sqrt(n)

In [54]: n
Out[54]: array([[ 25.]])

In [55]: dist
Out[55]: array([[ 5.]])

修改

正如@ roadrunner66注意到你应该使用逆矩阵而不是元素的逆矩阵。通常np.linalg.inv适用于这种情况,但为此你有奇异错误,你需要使用np.dot

n = (a-b).dot((np.linalg.pinv(np.cov(X))).dot((a-b).T))
dist = np.sqrt(n)

In [90]: n
Out[90]: array([[ 1.77777778]])

In [91]: dist
Out[91]: array([[ 1.33333333]])