Python返回数组中的平方Mahalanobis距离函数 - 为什么?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python返回数组中的平方Mahalanobis距离函数 - 为什么?相关的知识,希望对你有一定的参考价值。

代码是:

import numpy as np
def Mahalanobis(x, covariance_matrix, mean):
    x = np.array(x)
    mean = np.array(mean)
    covariance_matrix = np.array(covariance_matrix)
    return (x-mean)*np.linalg.inv(covariance_matrix)*(x.transpose()-mean.transpose())

#variables x and mean are 1xd arrays; covariance_matrix is a dxd matrix
#the 1xd array passed to x should be multiplied by the (inverted) dxd array
#that was passed into the second argument
#the resulting 1xd matrix is to be multiplied by a dx1 matrix, the transpose of 
#[x-mean], which should result in a 1x1 array (a number)

但由于某种原因,当我输入参数时,我得到了输出矩阵

Mahalanobis([2,5], [[.5,0],[0,2]], [3,6])

输出:

out[]: array([[ 2. ,  0. ],
              [ 0. ,  0.5]])

看来我的函数只是给了我在第二个参数中输入的2x2矩阵的逆。

答案

假设*运算符正在进行矩阵乘法,你犯了经典的错误。在Python / numpy中不是这样(参见http://www.scipy-lectures.org/intro/numpy/operations.htmlhttps://docs.scipy.org/doc/numpy-dev/user/numpy-for-matlab-users.html)。我将其分解为中间步骤并使用了点功能

import numpy as np
def Mahalanobis(x, covariance_matrix, mean):

    x = np.array(x)
    mean = np.array(mean)
    covariance_matrix = np.array(covariance_matrix)

    t1 = (x-mean)
    print(f'Term 1 {t1}')

    icov = np.linalg.inv(covariance_matrix)
    print(f'Inverse covariance {icov}')

    t2 = (x.transpose()-mean.transpose())
    print(f'Term 2 {t2}')

    mahal = t1.dot(icov.dot(t2))

    #return (x-mean)*np.linalg.inv(covariance_matrix).dot(x.transpose()-mean.transpose())
    return mahal

#variables x and mean are 1xd arrays; covariance_matrix is a dxd matrix
#the 1xd array passed to x should be multiplied by the (inverted) dxd array
#that was passed into the second argument
#the resulting 1xd matrix is to be multiplied by a dx1 matrix, the transpose of 
#[x-mean], which should result in a 1x1 array (a number)


Mahalanobis([2,5], [[.5,0],[0,2]], [3,6])

产生

Term 1 [-1 -1]
Inverse covariance [[2.  0. ]
 [0.  0.5]]
Term 2 [-1 -1]
Out[9]:    2.5
另一答案

可以使用scipymahalanobis()函数来验证:

import scipy.spatial, numpy as np

scipy.spatial.distance.mahalanobis([2,5], [3,6], np.linalg.inv([[.5,0],[0,2]]))
# 1.5811388300841898
1.5811388300841898**2 # squared Mahalanobis distance
# 2.5000000000000004

def Mahalanobis(x, covariance_matrix, mean):
  x, m, C = np.array(x), np.array(mean), np.array(covariance_matrix)
  return (x-m)@np.linalg.inv(C)@(x-m).T

Mahalanobis([2,5], [[.5,0],[0,2]], [3,6])
# 2.5 

np.isclose(
   scipy.spatial.distance.mahalanobis([2,5], [3,6], np.linalg.inv([[.5,0],[0,2]]))**2, 
   Mahalanobis([2,5], [[.5,0],[0,2]], [3,6])
)
# True

以上是关于Python返回数组中的平方Mahalanobis距离函数 - 为什么?的主要内容,如果未能解决你的问题,请参考以下文章

python使用numpy的np.float_power函数计算numpy数组中每个数值的指定幂次(例如平方立方)np.power函数默认返回整数格式np.float_power函数返回浮点数

python 如何对ndarray 每个变量求平方根?

Leetcode刷题Python977. 有序数组的平方

对列表中的所有元素进行平方

python中的整数平方根

python如何求一个众数