确保正定协方差矩阵

Der*_*erk 5 numpy linear-algebra neural-network deep-learning tensorflow

我的神经网络的输出充当协方差矩阵的入口。但是,输出和条目之间的一对一对应关系不会导致正定协方差矩阵。

因此,我阅读了https://www.quora.com/When-carrying-out-the-EM-algorithm-how-do-I-ensure-that-the-covariance-matrix-is-positive-definite-at-始终避免回合问题https://en.wikipedia.org/wiki/Cholesky_decomposition,更具体地说,“当A具有真实条目时,L也具有真实条目,并且因式分解可以写成A = LL^T”。

现在,我的输出对应于L矩阵的项,然后我将其乘以转置来生成协方差矩阵。

但是,有时我仍然会遇到非正定矩阵的错误。这怎么可能?

我发现了一个会产生错误的矩阵,请参见

print L.shape
print Sigma.shape

S = Sigma[1,18,:,:] # The matrix that gives the error
L_ = L[1,18,:,:]
print L_
S = np.dot(L_,np.transpose(L_))
print S
chol = np.linalg.cholesky(S)
Run Code Online (Sandbox Code Playgroud)

给出作为输出:

(3, 20, 2, 2)
(3, 20, 2, 2)
[[ -1.69684255e+00   0.00000000e+00]
 [ -1.50235415e+00   1.73807144e-04]]
[[ 2.87927461  2.54925847]
 [ 2.54925847  2.25706792]]
.....
LinAlgError: Matrix is not positive definite
Run Code Online (Sandbox Code Playgroud)

但是,此代码可复制值,但效果很好(但可能不会完全相同的值,因为并非所有小数点都被打印出来)

B = np.array([[-1.69684255e+00, 0.00000000e+00], [-1.50235415e+00, 1.73807144e-04]])
A = np.dot(B,B.T)
chol_A = np.linalg.cholesky(A)
Run Code Online (Sandbox Code Playgroud)

所以问题是:

  • 使用Sigma = LL'的方法(带有'转置)是否正确?
  • 如果是,为什么我会出错?这可能是由于四舍五入问题造成的吗?

编辑:我也计算了特征值

print np.linalg.eigvalsh(S)
[ -7.89378944432428397703915834426880e-08
   5.13634252548217773437500000000000e+00]
Run Code Online (Sandbox Code Playgroud)

对于第二种情况

print np.linalg.eigvalsh(A)
[  1.69341869415973178547574207186699e-08
   5.13634263409323210680668125860393e+00]
Run Code Online (Sandbox Code Playgroud)

因此,在第一种情况下,存在一个轻微的负特征值,它声明了非正定性。但是如何解决呢?

lej*_*lot 5

这看起来像是一个数值问题,但总的来说,LL' 总是正定的(如果 L 是可逆的,它将是真的)是不正确的。例如,将 L 作为矩阵,其中每一列都是 [1 0 0 0 ... 0] (或者甚至更极端 - 将 L 视为任意维数的零矩阵),则 LL' 不会是 PD。一般来说,我会建议做

S = LL' + eps I
Run Code Online (Sandbox Code Playgroud)

它解决了这两个问题(对于小 eps),并且是“正则化”协方差估计。您甚至可以使用 Ledoit-Wolf 估算器来获得 eps 的“最佳”(在某些假设下)值。