[英]scipy.stats.multivariate_normal error: input matrix must be symmetric positive definite
i'm trying to compute the cumulative distribution function of a multivariate normal using scipy.我正在尝试使用 scipy 计算多元正态分布的累积分布 function。
i'm having trouble with the "input matrix must be symmetric positive definite" error.我遇到了“输入矩阵必须是对称正定”错误的问题。
to my knowledge, a diagonal matrix with positive diagonal entries is positive definite ( see page 1 problem 2 )据我所知,具有正对角线项的对角矩阵是正定的(参见第 1 页问题 2 )
However, for different (relatively) small values of these diagonal values, the error shows up for the smaller values.但是,对于这些对角线值的不同(相对)较小的值,错误会出现在较小的值上。
For example, this code:例如,这段代码:
import numpy as np
from scipy.stats import multivariate_normal
std = np.array([0.001, 2])
mean = np.array([1.23, 3])
multivariate_normal(mean=mean, cov=np.diag(std**2)).cdf([2,1])
returns 0.15865525393145702 while changing the third line with:返回 0.15865525393145702 同时更改第三行:
std = np.array([0.00001, 2])
causes the error to show up.导致错误显示。
i'm guessing that it has something to do with computation error of floats.我猜这与浮点数的计算错误有关。 The problem is, when the dimension of the cov matrix is larger, the accepted positive values on the diagoanal are bigger and bigger.问题是,当cov矩阵的维数越大时,对角线上可接受的正值越来越大。
I tried multiple values on the diagonal of the covariance matrix of dimension 9x9.我在维度 9x9 的协方差矩阵的对角线上尝试了多个值。 It seems that when other diagonal values are very large, small values cause the error.似乎当其他对角线值非常大时,小值会导致错误。
Examining the stack trace you will see that it assumes the condition number as检查堆栈跟踪,您会发现它假定条件编号为
1e6*np.finfo('d').eps ~ 2.2e-10
in _eigvalsh_to_eps 1e6*np.finfo('d').eps ~ 2.2e-10
in _eigvalsh_to_eps
In your example the difference the smaller eigenvalue is 5e-6**2
times smaller than the largest eigenvalue so it will be treated as zero.在您的示例中,较小特征值的差异比最大特征值小5e-6**2
倍,因此它将被视为零。
You can pass allow_singular =True to get it working你可以通过allow_singular =True 让它工作
import numpy as np
from scipy.stats import multivariate_normal
std = np.array([0.000001, 2])
mean = np.array([1.23, 3])
multivariate_normal(mean=mean, cov=np.diag(std**2), allow_singular=True).cdf([2,1])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.