Numpy Cholesky分解LinAlgError

时间:2014-02-06 13:34:16

标签: python numpy scipy linear-algebra covariance

在我尝试对方差边界条件的2D数组的方差 - 协方差矩阵执行cholesky分解时,在某些参数组合下,我总是得到LinAlgError: Matrix is not positive definite - Cholesky decomposition cannot be computed。不确定它是numpy.linalg还是实现问题,因为脚本很简单:

sigma = 3.
U = 4

def FromListToGrid(l_):
    i = np.floor(l_/U)
    j = l_ - i*U
    return np.array((i,j))

Ulist = range(U**2)

Cov = []
for l in Ulist:
    di = np.array([np.abs(FromListToGrid(l)[0]-FromListToGrid(i)[0]) for i, x in enumerate(Ulist)])
    di = np.minimum(di, U-di)

    dj = np.array([np.abs(FromListToGrid(l)[1]-FromListToGrid(i)[1]) for i, x in enumerate(Ulist)])
    dj = np.minimum(dj, U-dj)

    d = np.sqrt(di**2+dj**2)
    Cov.append(np.exp(-d/sigma))
Cov = np.vstack(Cov)

W = np.linalg.cholesky(Cov)

尝试删除潜在的奇点也未能解决问题。非常感谢任何帮助。

2 个答案:

答案 0 :(得分:10)

深入研究问题,我尝试打印Cov矩阵的特征值。

print np.linalg.eigvalsh(Cov)

答案结果是这个

[-0.0801339  -0.0801339   0.12653595  0.12653595  0.12653595  0.12653595 0.14847999  0.36269785  0.36269785  0.36269785  0.36269785  1.09439988 1.09439988  1.09439988  1.09439988  9.6772531 ]

啊哈!注意前两个负特征值?现在,当且仅当所有特征值都为正时,矩阵才是正定的。因此,矩阵的问题并不是它接近于“零”,而是“负面”。为了扩展@duffymo类比,这是线性代数相当于试图取负数的平方根。

现在,让我们尝试执行相同的操作,但这次是scipy。

scipy.linalg.cholesky(Cov, lower=True)

那说不出更多的话

numpy.linalg.linalg.LinAlgError: 12-th leading minor not positive definite

这说明了更多,(虽然我真的不明白为什么它抱怨第12个未成年人)。

底线,矩阵不是非常接近'零',而是更像'负'

答案 1 :(得分:2)

问题在于您正在为其提供数据。根据求解器,矩阵是单数的。这意味着零或接近零的对角线元素,因此无法进行反转。

如果你能提供一个小版本的矩阵,那么更容易诊断。

零对角线不是创建奇点的唯一方法。如果两行彼此成比例,则解决方案中不需要两行;他们是多余的。它比在对角线上寻找零更复杂。

如果矩阵正确,则您有一个非空的空格。您需要将算法更改为SVD之类的内容。

请参阅下面的评论。