我正在尝试找到这个 9x9 协方差矩阵的逆矩阵,这样我就可以将它与马哈拉诺比斯距离一起使用。然而,我从 matrix inverse 得到的结果是一个充满
1.02939420e+16
的矩阵。我一直在试图找出原因,考虑到 Wolfram 会给我正确的答案,这似乎与矩阵的条件数有关,在本例中为 3.98290435292e+16
。
虽然我想了解其背后的数学原理,但此时我真正需要的只是这个问题的解决方案,以便我可以继续实施。有没有办法找到这样的矩阵的逆矩阵?或者是否可以直接从数据中找到逆协方差矩阵?
编辑:矩阵数据(与pastebin链接相同)
[[ 0.46811097 0.15024959 0.01806486 -0.03029948 -0.12472314 -0.11952018 -0.14738093 -0.14655549 -0.06794621]
[ 0.15024959 0.19338707 0.09046136 0.01293189 -0.05290348 -0.07200769 -0.09317139 -0.10125269 -0.12769464]
[ 0.01806486 0.09046136 0.12575072 0.06507481 -0.00951239 -0.02944675 -0.05349869 -0.07496244 -0.13193147]
[-0.03029948 0.01293189 0.06507481 0.12214787 0.04527352 -0.01478612 -0.02879678 -0.06006481 -0.1114809 ]
[-0.12472314 -0.05290348 -0.00951239 0.04527352 0.164018 0.05474073 -0.01028871 -0.02695087 -0.03965366]
[-0.11952018 -0.07200769 -0.02944675 -0.01478612 0.05474073 0.13397166 0.06839442 0.00403321 -0.02537928]
[-0.14738093 -0.09317139 -0.05349869 -0.02879678 -0.01028871 0.06839442 0.14424203 0.0906558 0.02984426]
[-0.14655549 -0.10125269 -0.07496244 -0.06006481 -0.02695087 0.00403321 0.0906558 0.17054466 0.14455264]
[-0.06794621 -0.12769464 -0.13193147 -0.1114809 -0.03965366 -0.02537928 0.02984426 0.14455264 0.32968928]]
您提供的矩阵
m
有一个行列式0
,因此从数值角度来看是不可逆的(这解释了您拥有的巨大值往往会撞到Inf
):
In [218]: np.linalg.det(m)
Out[218]: 2.8479946613617788e-16
如果您开始进行线性代数运算/解决问题,我强烈建议您检查一些基本概念,这将避免出现数值错误/错误: https://en.wikipedia.org/wiki/Invertible_matrix
你面临着一个非常重要且基本的数学问题。如果您的方法给出不可逆矩阵,则该方法就会出现问题。该方法试图解决“不适定问题”。也许所有适定问题都已在十九世纪得到解决。解决不适定问题的最常见方法是“正则化”。有时Moore-Penrose伪逆可能很方便。 Scipy.linalg 有伪逆。但伪逆并不是捷径。使用伪逆,你可以用可解的问题 B 代替不可解的问题 A。有时,问题 B 的解可以成功地代替问题 A 不存在的解,但这是一个数学研究的问题。 零行列式意味着您的矩阵具有线性相关的行(或列)。换句话说,模型中的某些信息是多余的(它包含过多或重复的信息)。重新开发模型以排除冗余。
计算协方差并进行逆运算
就像这里import numpy as np
from scipy.spatial.distance import mahalanobis,euclidean
from sklearn.decomposition import PCA
from sklearn.preprocessing import StandardScaler
X = np.array([[ 0.46811097, 0.15024959, 0.01806486, -0.03029948, -0.12472314, -0.11952018, -0.14738093, -0.14655549, -0.06794621],
[ 0.15024959 , 0.19338707, 0.09046136, 0.01293189, -0.05290348, -0.07200769, -0.09317139, -0.10125269, -0.12769464],
[0.01806486, 0.09046136, 0.12575072, 0.06507481, -0.00951239, -0.02944675, -0.05349869, -0.07496244, -0.13193147],
[-0.03029948, 0.01293189, 0.06507481, 0.12214787, 0.04527352, -0.01478612, -0.02879678, -0.06006481, -0.1114809 ],
[-0.12472314, -0.05290348, -0.00951239, 0.04527352, 0.164018, 0.05474073, -0.01028871, -0.02695087, -0.03965366],
[-0.11952018, -0.07200769, -0.02944675, -0.01478612, 0.05474073, 0.13397166, 0.06839442, 0.00403321, -0.02537928],
[-0.14738093, -0.09317139, -0.05349869, -0.02879678, -0.01028871, 0.06839442, 0.14424203, 0.0906558, 0.02984426],
[-0.14655549, -0.10125269, -0.07496244, -0.06006481, -0.02695087, 0.00403321, 0.0906558, 0.17054466, 0.14455264],
[-0.06794621, -0.12769464, -0.13193147, -0.1114809, -0.03965366, -0.02537928, 0.02984426, 0.14455264, 0.32968928]])
cov = np.cov(X, rowvar=False)
covI = np.linalg.inv(cov)
mean=np.mean(X)
md = mahalanobis(X[0], X[1], covI)
pca = PCA(whiten=True) # !!
X_transformed= pca.fit_transform(X)
print('Mahalanobis distance: '+str(md))
print('Euclidean distance: '+str(euclidean(X_transformed[0],X_transformed[1])))
## Mahalanobis distance: 4.094095146671607
## Euclidean distance: 3.999999999999999
或者可以与
算法一起使用这里
附注马哈拉诺比斯距离与欧几里德距离,或者
这里因此,我认为可能存在一些冗余
参数(或者这里是相关特征)