【问题标题】:How to use mahalanobis distance in sklearn DistanceMetrics?如何在 sklearn DistanceMetrics 中使用马氏距离?
【发布时间】:2016-01-06 21:54:19
【问题描述】:

也许这是基本的,但我找不到在sklearn 中使用mahalanobis 距离的好例子。

我什至无法获得这样的指标:

from sklearn.neighbors import DistanceMetric
DistanceMetric.get_metric('mahalanobis')

这会引发错误:TypeError: 0-dimensional array given. Array must be at least two-dimensional

但是,我什至无法让它接受一个数组:

DistanceMetric.get_metric('mahalanobis', [[0.5],[0.7]])

抛出:

TypeError: get_metric() takes exactly 1 positional argument (2 given)

我查看了文档 herehere。但是,我看不出它期待什么类型的参数。
有没有使用我可以看到的马氏距离的例子?

【问题讨论】:

    标签: python arrays scikit-learn mahalanobis


    【解决方案1】:

    MahalanobisDistance 需要一个参数 V,它是协方差矩阵,以及可选的另一个参数 VI,它是协方差矩阵的逆矩阵。此外,这两个参数都是命名的而不是位置的。

    还要检查sklearn repo 中文件scikit-learn/sklearn/neighbors/dist_metrics.pyx 中类MahalanobisDistance 的文档字符串。

    例子:

    In [18]: import numpy as np
    In [19]: from sklearn.datasets import make_classification
    In [20]: from sklearn.neighbors import DistanceMetric
    In [21]: X, y = make_classification()
    In [22]: DistanceMetric.get_metric('mahalanobis', V=np.cov(X))
    Out[22]: <sklearn.neighbors.dist_metrics.MahalanobisDistance at 0x107aefa58>
    

    编辑:

    由于某些原因(错误?),您不能将距离对象传递给NearestNeighbor 构造函数,而是需要使用距离度量的名称。此外,设置algorithm='auto'(默认为'ball_tree')似乎不起作用;所以从上面的代码中给出X,你可以这样做:

    In [23]: nn = NearestNeighbors(algorithm='brute', 
                                   metric='mahalanobis', 
                                   metric_params={'V': np.cov(X)})
    # returns the 5 nearest neighbors of that sample
    In [24]: nn.fit(X).kneighbors(X[0, :])     
    Out[24]: (array([[ 0., 3.21120892, 3.81840748, 4.18195987, 4.21977517]]), 
              array([[ 0, 36, 46,  5, 17]])) 
    

    【讨论】:

    • 您如何使用距离度量,例如nearest neighbors 或聚类?当我尝试使用它时,我得到ValueError: Metric not valid for algorithm 'auto'
    • @Sother 我在答案中添加了NearestNeighbor 示例。
    • 适用于NearestNeighbors,但我没有看到DBSCAN"metric_params" 和聚类算法?
    • 我尝试使用dm = DistanceMetric.get_metric('mahalanobis',VI=icov) 距离函数,然后使用db = DBSCAN(eps=x, min_samples=1, metric='pyfunc', func='dm', algorithm='brute').fit(np.array(X_train_numeric)),但它无法将"func" 识别为参数。
    • @Sother 我从来没有使用过mahalanobis 距离和DBSCAN,但它看起来好像还没有得到DBSCAN 的正确支持——我建议在github上打开一个问题或在sklearn 邮件列表中询问。
    【解决方案2】:

    在使用矩阵 M (X x Y) 创建 cov 矩阵时,您需要转置矩阵 M。 马氏公式是 (x-x1)^t * 逆 covmatrix * (x-x1)。如您所见,第一个参数已转置,这意味着矩阵 XY 更改为 YX。为了将第一个参数和cov矩阵相乘,cov矩阵应该是YY的形式。

    如果你只使用 np.cov(M),它将是 XX, 使用 np.cov(M.T),它将是 YY。

    【讨论】:

      猜你喜欢
      • 2018-06-29
      • 1970-01-01
      • 2016-04-21
      • 2013-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-25
      相关资源
      最近更新 更多