Numpy 在计算归一化马氏距离时指出该无效值

Posted

技术标签:

【中文标题】Numpy 在计算归一化马氏距离时指出该无效值【英文标题】:Numpy stateing that invalid value while calculating normalized mahalanobis distance 【发布时间】:2013-04-12 09:57:08 【问题描述】:

注意

这是我的数据挖掘课的家庭作业。

我将把相关代码 sn-ps 放在这个 SO 帖子上,但你可以在 http://pastebin.com/CzNFbLJ2 找到我的整个程序

我用于这个程序的数据集可以在http://archive.ics.uci.edu/ml/datasets/Iris找到


所以我得到:RuntimeWarning:sqrt 中遇到的无效值 返回 np.sqrt(m)

我正在尝试查找给定虹膜数据集(原始数据集和标准化数据集)的平均马氏距离。该错误仅发生在数据集的规范化版本上,这让我想知道我是否错误地理解了规范化的含义(在代码和数学上)。

我认为归一化意味着向量的每个分量都除以它的向量长度(导致向量加起来为 1)。我发现了这个 SO question How to normalize a 2-dimensional numpy array in python less verbose? 并认为它符合我的规范化概念。但是现在我的代码报告说标准化数据集上的马氏距离是 NAN

def mahalanobis(data):
   import numpy as np;
   import scipy.spatial.distance;
   avg   = 0
   count = 0

   covar = np.cov(data, rowvar=0);
   invcovar = np.linalg.inv(covar)

   for i in range(len(data)):
      for j in range(i + 1, len(data)):
         if(j == len(data)):
            break
         avg += scipy.spatial.distance.mahalanobis(data[i], data[j], invcovar)
         count += 1
   return avg / count


def normalize(data):
   import numpy as np
   row_sums = data.sum(axis=1)
   norm_data = np.zeros((50, 4))
   for i, (row, row_sum) in enumerate(zip(data, row_sums)):
      norm_data[i,:] = row / row_sum
   return norm_data

【问题讨论】:

向量长度是其点积的平方根。您可以通过将第二行更改为 row_sums = (data*data).sum(axis=1) 来修改您的规范化功能 嗯,改行有什么好处? 【参考方案1】:

可能为时已晚,但请查看我们的教科书“数据挖掘简介”中的第 64-65 页。有一节叫做“标准化或标准化”,它解释了 Hearne 正在寻找的标准化数据的概念。

基本上标准化的数据集x' = (x - mean(x)) / standardDeviation(x)

由于我看到您使用的是 python,以下是使用 SciPy 的方法:

normalizedData = (data - data.mean(axis=0)) / data.std(axis=0, ddof=1)

来源:http://mail.scipy.org/pipermail/numpy-discussion/2011-April/056023.html

【讨论】:

书中还说规范化可以表示(data - data.mean / (data.max - data.min))。我会尝试两个。【参考方案2】:

您可以使用pdist() 进行距离计算,无需 for 循环:

from sklearn import datasets
iris = datasets.load_iris()
from scipy.spatial.distance import pdist, squareform
print squareform(pdist(iris.data, 'mahalanobis'))

【讨论】:

【参考方案3】:

在这种情况下,归一化可能确实意味着减去均值和缩放,因此数据具有单位协方差矩阵。

但是,要将数据集中的每个向量缩放到单位范数,请使用:norm_data=data/np.sqrt(np.sum(data*data,1))[:,None]

您需要除以每个向量的 L2 范数,这意味着将每个元素的值平方,然后取和的平方根。广播允许您避免显式编码循环(请参阅您引用的问题的答案:https://***.com/a/8904762/1149913)。

【讨论】:

以上是关于Numpy 在计算归一化马氏距离时指出该无效值的主要内容,如果未能解决你的问题,请参考以下文章

超过2组的R上的马氏距离

最小马氏距离分类器

最小马氏距离分类器

如何使用 Keras 计算马氏距离?

马氏距离在SLAM中的应用

在opencv中,使用Mat类型计算马氏距离太慢了。如何提高效率?