2016-03-04 226 views
0

这应该是一个简单的问题,或者我缺少信息,或者我错误地编码了这个。python中的Mahalanabois距离返回矩阵而不是距离

我想在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返回一个3×3阵列,但应予不能期待表示距离的单个数字?

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

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

回答

2

从维基page你可以看到,ab是矢量,但在你的情况下,他们是数组。所以你需要反向转置。还应该有矩阵乘法。在numpy *表示单元乘法,对于矩阵,您应该使用np.dot函数或.dot方法的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.linalg.pinv

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]]) 
+1

不应该是这样的矩阵求逆'numpy.linalg.inv'而不是点聪明反? – roadrunner66

+0

@ roadrunner66偏离它当然应该。错过了。 Hovewer'np.linalg.inv(np.cov(X))'给出错误'LinAlgError:奇异矩阵.. .. –

+0

是的,使用的矩阵可能没有很好地形成。 – roadrunner66