确保正定的协方差矩阵

时间:2016-11-13 11:49:35

标签: numpy neural-network tensorflow deep-learning linear-algebra

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

因此,我更详细地阅读了https://www.quora.com/When-carrying-out-the-EM-algorithm-how-do-I-ensure-that-the-covariance-matrix-is-positive-definite-at-all-times-avoiding-rounding-issueshttps://en.wikipedia.org/wiki/Cholesky_decomposition"当A有实际条目时,L也有实际条目,并且可以写出分解A = LL^T&# 34。

现在我的输出对应于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)

作为输出:

(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

但是,复制值的代码工作正常(但可能不完全相同,因为并非所有小数都打印出来)

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)

所以问题是:

  • 使用Sigma = LL'的方法是什么?正确(使用'转置)?
  • 如果是,为什么我收到错误?这可能是因为四舍五入问题吗?

编辑:我还计算了特征值

print np.linalg.eigvalsh(S)
[ -7.89378944432428397703915834426880e-08
   5.13634252548217773437500000000000e+00]

对于第二种情况

print np.linalg.eigvalsh(A)
[  1.69341869415973178547574207186699e-08
   5.13634263409323210680668125860393e+00]

因此第一种情况存在轻微的负特征值,它表示非正定性。但是如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

这看起来像一个数字问题,但总的来说,LL'总是肯定是肯定的。例如,将L作为矩阵,其中每列为[1 0 0 0 ... 0](或甚至更极端 - 将L设为任意维度的零矩阵),LL'将不是PD。一般来说,我建议你做

S = LL' + eps I

负责两个问题(对于小eps),并且是'正则化的'协方差估计。您甚至可以通过使用Ledoit-Wolf估算器来获得eps的“最佳”(在某些特定情况下)值。

答案 1 :(得分:1)

我怀疑L*L'的计算是在第一种情况下使用浮点数并且在第二种情况下使用双精度计算。我尝试将你的L作为浮点矩阵,计算L*L'并找到它的特征值,我得到你在第一种情况下所做的相同的值,但如果我将L转换为双精度矩阵,计算L*L'并找到特征值,我得到的值与你在第二种情况下的值相同情况下。

这是有道理的,因为在L*L' [1,1]的计算中,1.75807144e-04的平方在浮点数中将与-1.50235415e + 00的平方相比是可忽略的。

如果我是对的,解决方法是在任何计算之前将L转换为双精度矩阵。