【问题标题】:Mahalanobis distance not equal to Euclidean distance after PCA主成分分析后的马氏距离不等于欧几里得距离
【发布时间】:2021-11-02 14:04:54
【问题描述】:

我试图用 PCA 转换后将马氏距离计算为欧几里得距离,但是,我没有得到相同的结果。以下代码:

import numpy as np
from scipy.spatial.distance import mahalanobis
from sklearn.decomposition import PCA

X = [[1,2], [2,2], [3,3]]

mean = np.mean(X, axis=0)
cov = np.cov(X, rowvar=False)
covI = np.linalg.inv(cov)

maha = mahalanobis(X[0], mean, covI)
print(maha)

pca = PCA()

X_transformed = pca.fit_transform(X)

stdev = np.std(X_transformed, axis=0)
X_transformed /= stdev

print(np.linalg.norm(X_transformed[0]))

打印

1.1547005383792515
1.4142135623730945

据我了解,PCA 与维度不相关,除以标准差对每个维度的权重均等,因此欧几里得距离应等于马氏距离。我哪里错了?

【问题讨论】:

    标签: python pca mahalanobis


    【解决方案1】:

    根据this discussion,PCA 与马氏距离之间的关系仅适用于具有单位方差的 PCA 分量。这可以通过对白化数据应用 PCA 来获得(更多信息here)。

    一旦你这样做了,原始空间中的马氏距离等于 PCA 空间中的欧几里得距离。您可以在下面的代码中看到它的演示:

    import numpy as np
    from scipy.spatial.distance import mahalanobis,euclidean
    from sklearn.decomposition import PCA
    from sklearn.preprocessing import StandardScaler
    
    X = np.array([[1,2], [2,2], [3,3]])
    
    cov = np.cov(X, rowvar=False)
    covI = np.linalg.inv(cov)
    mean=np.mean(X)
    maha = mahalanobis(X[0], X[1], covI)
    
    pca = PCA(whiten=True)
    X_transformed= pca.fit_transform(X)
    
    print('Mahalanobis distance: '+str(maha))
    print('Euclidean distance: '+str(euclidean(X_transformed[0],X_transformed[1])))
    

    输出给出:

    Mahalanobis distance: 2.0
    Euclidean distance: 2.0000000000000004
    

    【讨论】:

    • 行得通,谢谢。你能解释一下为什么我的按列标准差 (stdev = np.std(X_transformed, axis=0) X_transformed /= stdev) 的划分不满足“PCA 和马氏距离之间的关系只适用于具有单位方差的 PCA 组件“?
    • 我不确定将非白化 PCA 投影数据除以标准偏差有何帮助。我的理解是,数据的标准化必须在应用 PCA 之前进行。可能有一种方法可以将非白化 PCA 投影数据转换为白化 PCA 投影数据,但我不知道该怎么做。
    猜你喜欢
    • 1970-01-01
    • 2013-03-02
    • 2015-07-15
    • 2014-02-04
    • 1970-01-01
    • 2021-10-01
    • 2012-12-21
    相关资源
    最近更新 更多