我在 R 中有以下代码,它计算 Iris 数据集上的马氏距离并返回一个具有 150 个值的数值向量,一个用于数据集中的每个观察值。
x=read.csv("Iris Data.csv")
mean<-colMeans(x)
Sx<-cov(x)
D2<-mahalanobis(x,mean,Sx)
我尝试使用'scipy.spatial.distance.mahalanobis(u, v, VI)'函数在Python中实现相同的功能,但似乎这个函数只接受一维数组作为参数。
我在 R 中有以下代码,它计算 Iris 数据集上的马氏距离并返回一个具有 150 个值的数值向量,一个用于数据集中的每个观察值。
x=read.csv("Iris Data.csv")
mean<-colMeans(x)
Sx<-cov(x)
D2<-mahalanobis(x,mean,Sx)
我尝试使用'scipy.spatial.distance.mahalanobis(u, v, VI)'函数在Python中实现相同的功能,但似乎这个函数只接受一维数组作为参数。
我使用了 R 中的 Iris 数据集,我想它与您使用的相同。
首先,这是我的 R 基准,用于比较:
x <- read.csv("IrisData.csv")
x <- x[,c(2,3,4,5)]
mean<-colMeans(x)
Sx<-cov(x)
D2<-mahalanobis(x,mean,Sx)
然后,在 python 中你可以使用:
from scipy.spatial.distance import mahalanobis
import scipy as sp
import pandas as pd
x = pd.read_csv('IrisData.csv')
x = x.ix[:,1:]
Sx = x.cov().values
Sx = sp.linalg.inv(Sx)
mean = x.mean().values
def mahalanobisR(X,meanCol,IC):
m = []
for i in range(X.shape[0]):
m.append(mahalanobis(X.iloc[i,:],meanCol,IC) ** 2)
return(m)
mR = mahalanobisR(x,mean,Sx)
我定义了一个函数,以便您可以在其他集合中使用它,(注意我使用 pandas DataFrames 作为输入)
比较结果:
在 R 中
> D2[c(1,2,3,4,5)]
[1] 2.134468 2.849119 2.081339 2.452382 2.462155
在 Python 中:
In [43]: mR[0:5]
Out[45]:
[2.1344679233248431,
2.8491186861585733,
2.0813386639577991,
2.4523816316796712,
2.4621545347140477]
请注意,您在 R 中得到的是平方马氏距离。
一个更简单的解决方案是:
from scipy.spatial.distance import cdist
x = ...
mean = x.mean(axis=0).reshape(1, -1) # make sure 2D
vi = np.linalg.inv(np.cov(x.T))
cdist(mean, x, 'mahalanobis', VI=vi)