协方差不是正定的

covariance isn't positive definite

我正在尝试计算给定数据的样本协方差。

我写的代码是:

def calcCov(x):
    m, n = x.shape

    mean = np.mean(x, axis=0)
    cov = np.zeros((n, n))
    for j in range(0, n):
        for k in range(0, n):
            sum = 0
            for i in range(0, m):
                sum += (x[i, j] - mean[j])*(x[i, k] - mean[k])
            cov[j, k] = sum / (m - 1.0)

    return cov

这不是最有效的方法,但它很简单,并且据我所知是 https://en.wikipedia.org/wiki/Sample_mean_and_covariance#Sample_covariance 的直接副本。

协方差矩阵总是半正定的。但是当我计算特征值时(np.eig)我有时会看到负特征值。

例如代码

data = np.random.rand(2, 2)
print data
cov = calcCov(data)
eigvals, eigvec = np.linalg.eig(cov)
print cov
print eigvals

打印输出

[[ 0.12873309  0.92079275]
 [ 0.90018866  0.73197021]]
[[ 0.29757185 -0.0728341 ]
 [-0.0728341   0.01782698]]
[  3.15398823e-01  -3.46944695e-18]

作为一个非常不安的数学家。为什么会这样?简单的数值错误?我计算协方差有误吗?

首先,我建议使用numpy的协方差函数,因为它会更有效率:https://docs.scipy.org/doc/numpy-1.10.1/reference/generated/numpy.cov.html

鉴于您拥有的 "negative" 特征值是 e-18,将其视为 0 是公平的,直到出现数值错误。