这应该是一个简单的问题,要么我缺少信息,要么我错误地编码了这个。
我正在尝试在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距离的实现我还没有找到可以比较它的东西。
答案 0 :(得分:2)
从维基page您可以看到,a
和b
是向量,但在您的情况下,它们是数组。所以你需要反向移调。而且应该有矩阵乘法。 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]])