numpy:零行列式矩阵是否可逆?

3

根据定义,行列式为零的方阵不应是可逆矩阵。然而,在生成协方差矩阵后,我成功地取了其逆,但是取协方差矩阵的行列式却得到了0.0的输出。

可能出了什么问题?我应该不相信行列式的输出,还是不应该相信逆协方差矩阵?还是两者都不应该相信?

以下是我的代码片段:

cov_matrix = np.cov(data)
adjusted_cov = cov_matrix + weight*np.identity(cov_matrix.shape[0]) # add small weight to ensure cov_matrix is non-singular
inv_cov = np.linalg.inv(adjusted_cov) # runs with no error, outputs a matrix
det = np.linalg.det(adjusted_cov) # ends up being 0.0

你能给我们展示一个输入和输出的例子吗?你的评论意味着你正在尝试使矩阵非奇异,这意味着该矩阵应该具有有效的逆。 - BobChao87
嗯,我的数据集由28x28的图像组成,其中我使用原始像素作为特征,因此输入输出太大无法复制,我认为(784x487协方差矩阵)。我相信添加权重确实会导致具有有效逆 - 但是,为什么行列式为零呢?如果我不添加权重,我会得到奇异线性代数错误。舍入误差是否应用于行列式,使其舍入为0.0? - kk415kk
@kk415kk,由于协方差矩阵的数字很小(根据您的评论),您可能遇到了精度问题而不是舍入问题。784个数字的乘积,平均大小仅为0.3,太小了,无法保存在Python浮点数中。如果numpy有一种计算矩阵逆而不计算行列式的方法,则可能会导致您所描述的行为。 - BobChao87
啊,好的。我问题的背景是我试图将这些(分类)图像建模为多元高斯分布,这需要我计算协方差矩阵及其逆矩阵。如果精度是一个问题,是否有更好的方法来完成这个任务? - kk415kk
如果您需要行列式的值以进行其他操作,我建议尝试将numpy与支持任意精度的decimal.Decimal类集成。这将为使用该方法进行的任何计算添加很多开销,因此我建议仅在绝对必要时使用Decimal - BobChao87
显示剩余3条评论
1个回答

3

矩阵的数值求逆不需要计算行列式。(对于大型矩阵,Cramer's formula求逆不实用。) 因此,行列式计算结果为0(由于浮点数精度不足),并不会影响矩阵求逆例程。

接下来是BobChao87评论的一个简化测试案例(Python 3.4控制台,已导入numpy作为np)

A = 0.2*np.identity(500)
np.linalg.inv(A)

输出:一个在主对角线上为5的矩阵,这是A的正确逆矩阵。
np.linalg.det(A)

输出结果为0.0,因为行列式(0.2^500)太小,无法以双精度表示。一种可能的解决方案是一种预处理方法(在这里,只是重新缩放):在计算行列式之前,将矩阵乘以一个因子,使其条目平均接近于1。在我的例子中,np.linalg.det(5*A)返回1。当然,在这里使用5的因子是欺骗行为,但np.linalg.det(3*A)也返回非零值(约为1.19e-111)。如果您尝试对k运行适度正整数的np.linalg.det(2 ** k * A),您可能会遇到返回非零值的矩阵。然后,您将知道原始矩阵的行列式大约是输出的2 **(-kn)倍,其中n是矩阵大小。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接