当前位置: 首页 > 知识库问答 >
问题:

计算Mahalanobis距离时的Sency-nan

吴德辉
2023-03-14

当我试图用下面的python代码计算Mahalanobis距离时,我在结果中得到了一些楠条目。你知道为什么会这样吗?我的data.shape=(181,1500)

from scipy.spatial.distance import pdist, squareform

data_log = log2(data + 1) # A log transform that I usually apply to my data
data_centered = data_log - data_log.mean(0) # zero centering
D = squareform( pdist(data_centered, 'mahalanobis' ) )

我还尝试:

data_standard = data_centered / data_centered.std(0, ddof=1)
D = squareform( pdist(data_standard, 'mahalanobis' ) )

还有奶奶。输入没有损坏,其他距离,如相关距离,可以很好地计算。出于某种原因,当我减少功能的数量时,我就停止获得Nans。例如下面的例子没有得到任何楠:

D = squareform( pdist(data_centered[:,:200], 'mahalanobis' ) )
D = squareform( pdist(data_centered[:,180:480], 'mahalanobis' ) )

当其他人得到NAN时:

D = squareform( pdist(data_centered[:,:300], 'mahalanobis' ) )
D = squareform( pdist(data_centered[:,180:600], 'mahalanobis' ) )

有线索吗?如果输入的某些条件不满足,这是预期行为吗?

共有1个答案

欧阳炜
2023-03-14

观察值少于特征值,因此scipy代码计算的协方差矩阵V是奇异的。代码没有检查这一点,而是盲目地计算协方差矩阵的“逆”。因为这个数值计算的逆基本上是垃圾,乘积(x-y)*inv(V)*(x-y)(其中xy是观测值)可能是负数。然后该值的平方根产生nan

例如,此数组还会生成nan

In [265]: x
Out[265]: 
array([[-1. ,  0.5,  1. ,  2. ,  2. ],
       [ 2. ,  1. ,  2.5, -1.5,  1. ],
       [ 1.5, -0.5,  1. ,  2. ,  2.5]])

In [266]: squareform(pdist(x, 'mahalanobis'))
Out[266]: 
array([[ 0.        ,         nan,  1.90394328],
       [        nan,  0.        ,         nan],
       [ 1.90394328,         nan,  0.        ]])

这是“手工”完成的马氏计算:

In [279]: V = np.cov(x.T)

理论上,V是单数;以下值实际上为0:

In [280]: np.linalg.det(V)
Out[280]: -2.968550671342364e-47

但是inv没有看到问题,并返回一个反向:

In [281]: VI = np.linalg.inv(V)

让我们计算x[0]x[2]之间的距离,并验证在使用VI时,我们是否得到了pdist返回的相同非nan值(1.9039):

In [295]: delta = x[0] - x[2]

In [296]: np.dot(np.dot(delta, VI), delta)
Out[296]: 3.625

In [297]: np.sqrt(np.dot(np.dot(delta, VI), delta))
Out[297]: 1.9039432764659772

下面是当我们试图计算x[0]x[1]之间的距离时发生的情况:

In [300]: delta = x[0] - x[1]

In [301]: np.dot(np.dot(delta, VI), delta)
Out[301]: -1.75

然后该值的平方根给出nan

在sepi0.16(将于2015年6月发布)中,您将获得一个错误,而不是nan或垃圾。错误消息描述了问题:

In [4]: x = array([[-1. ,  0.5,  1. ,  2. ,  2. ],
   ...:        [ 2. ,  1. ,  2.5, -1.5,  1. ],
   ...:        [ 1.5, -0.5,  1. ,  2. ,  2.5]])

In [5]: pdist(x, 'mahalanobis')
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-a3453ff6fe48> in <module>()
----> 1 pdist(x, 'mahalanobis')

/Users/warren/local_scipy/lib/python2.7/site-packages/scipy/spatial/distance.pyc in pdist(X, metric, p, w, V, VI)
   1298                                      "singular. For observations with %d "
   1299                                      "dimensions, at least %d observations "
-> 1300                                      "are required." % (m, n, n + 1))
   1301                 V = np.atleast_2d(np.cov(X.T))
   1302                 VI = _convert_to_double(np.linalg.inv(V).T.copy())

ValueError: The number of observations (3) is too small; the covariance matrix is singular. For observations with 5 dimensions, at least 6 observations are required.
 类似资料:
  • 我需要计算汽车行驶的距离!不是距离,不是距离到否。如果我们通过谷歌提供的API计算,距离可以完全不同。谷歌可以提供从一个点到另一个点的1公里距离,但汽车可以按照骑手想要的方式行驶800米。使用加速计没有帮助。它适用于步行,但绝不适用于更快的速度。 我尝试过使用Google的位置API:距离到或距离之间根本不是一个选项。它可以给出与IN REAL截然不同的结果。在真实的汽车中,可以通过非常短的地方并

  • 我试图使用Scala类计算两点之间的距离。但它给出了一个错误说 类型不匹配;发现:其他。需要类型(具有基础类型点):?{def x:?}请注意,隐式转换不适用,因为它们是不明确的:在[A](x:A)类型的对象Predef中确保[A]的方法any2Ensuring和在[A](x:A)“ArroAssoc[A]类型的对象Predef中的方法Ani2ArrowasSoc都是可能的其他转换函数。输入到?{

  • 我有一个多边形类型的几何体,我正在计算一个点的最小距离可能在多边形几何体内部(由360个点组成,作为闭合几何体)或多边形几何体外部。使用postgis的ST_distance方法,当点在几何体外部时,我得到精确的距离,但如果点在几何体内部,则得到0作为距离,我想要与多边形几何体最近点的点之间的最小距离,无论该点位于几何体内部还是外部。

  • 我目前正在开发一个专注于健身的应用程序。我的基本想法是允许人们跟踪他们的速度、距离和时间。到目前为止,我已经通过使用位置管理器getSpeed()设法获得了速度。我想知道如何获得旅行的距离?我寻找了一些示例,但对我来说有点困惑,因为我刚刚开始使用android。我将感谢任何帮助或建议,谢谢

  • 问题内容: 我需要创建一个类来计算两点之间的距离。我被困住了,我是一个完全的初学者。这是我的课程: 第二课。 我不确定如何在两个定义的点之间获取点对象(中间点)。 我可以创建点对象,但不确定如何通过位于这两个点对象之间的方法返回点对象。 问题答案: 平面上的两个点(x1,y1)和(x2,y2)之间的距离为: 但是,如果您想要的只是两个点的中点,则应将中点函数更改为: 这将返回一个全新的点对象,其点

  • 问题内容: 我必须查询成千上万个条目的数据库,并按距指定点的距离对其进行排序。 问题是每个条目都有一个纬度和经度,我需要检索每个条目以计算其距离。对于大型数据库,我不想检索每一行,这可能需要一些时间。 有什么办法可以将其构建到mysql查询中,以便我只需要检索最近的15个条目。 例如 问题答案: 选项1:通过切换到支持GeoIP的数据库对数据库进行计算。 选项2:使用如下存储过程对数据库进行计算: