生成具有非正定协方差矩阵的正态分布随机数


15

我估计了样本的样本协方差矩阵C并得到了一个对称矩阵。使用C,我想创建ñ变量正态分布rn,但是因此我需要的Cholesky分解C。如果C不是正定的怎么办?


1

1
正半定矩阵具有多个平方根(例如,请参阅stats.stackexchange.com/a/71303/919末尾的说明)。您不一定需要由Cholesky分解生成的那个。这就是问题的核心所在:找到一种即使在矩阵为奇数时也可以计算平方根的方法。@amoeba标题表明您的解释是正确的。
ub

Answers:


8

该问题涉及如何生成从多元正态分布的随机变元具有(可能)奇异协方差矩阵C。该答案说明了一种适用于任何协方差矩阵的方法。它提供了一种R测试其准确性的实现。


协方差矩阵的代数分析

因为C是协方差矩阵,所以它必然是对称且正定的。为了完成背景信息,让μ为期望均值的向量。

由于是对称的,因此其奇异值分解(SVD)及其本征分解将自动具有以下形式C

C=Vd2V

对于一些正交矩阵和对角矩阵D 2。通常,D 2的对角元素是非负的(暗示它们都具有实平方根:选择正的根以形成对角矩阵D)。关于C的信息表明,这些对角元素中的一个或多个为零-但这不会影响任何后续操作,也不会阻止SVD的计算。Vd2d2dC

生成多元随机值

有一个标准的多元正态分布:每个部件都有零均值,单位方差,并且所有协方差为零:它的协方差矩阵是。然后,随机变量Y = V D X具有协方差矩阵X一世ÿ=VdX

Cov(Y)=E(YY)=E(VDXXDV)=VDE(XX)DV=VDIDV=VD2V=C.

因此,随机变量具有均值μ和协方差矩阵C的多元正态分布。μ+YμC

计算和示例代码

以下R代码生成给定维度和等级的协方差矩阵,使用SVD分析(或在注释掉的代码中使用特征分解),使用该分析生成指定数量的实现(均值向量0) ,然后将这些数据的协方差矩阵与预期的协方差矩阵进行数值和图形比较。如图所示,它产生10 000的实现,其中的维数ÿ100和的秩Ç50。输出是Y010000ÿ100C50

        rank           L2 
5.000000e+01 8.846689e-05 

即,数据的秩也是和作为从数据中估计的协方差矩阵是距离内8 × 10 - 5Ç,可呈现接近。作为更详细的检查,将C的系数与其估计的系数作图。它们都接近平等线:508×10-5CC

数字

该代码与前面的分析完全相同,因此应该是不言自明的(即使对于非R用户而言,他们也可能会在自己喜欢的应用程序环境中进行模拟)。它揭示的一件事是在使用浮点算法时需要谨慎:由于不精确,的项很容易为负(但很小)。在计算平方根以找到D本身之前,需要将此类条目清零。d2d

n <- 100         # Dimension
rank <- 50
n.values <- 1e4  # Number of random vectors to generate
set.seed(17)
#
# Create an indefinite covariance matrix.
#
r <- min(rank, n)+1
X <- matrix(rnorm(r*n), r)
C <- cov(X)
#
# Analyze C preparatory to generating random values.
# `zapsmall` removes zeros that, due to floating point imprecision, might
# have been rendered as tiny negative values.
#
s <- svd(C)
V <- s$v
D <- sqrt(zapsmall(diag(s$d)))
# s <- eigen(C)
# V <- s$vectors
# D <- sqrt(zapsmall(diag(s$values)))
#
# Generate random values.
#
X <- (V %*% D) %*% matrix(rnorm(n*n.values), n)
#
# Verify their covariance has the desired rank and is close to `C`.
#
s <- svd(Sigma <- cov(t(X)))
(c(rank=sum(zapsmall(s$d) > 0), L2=sqrt(mean(Sigma - C)^2)))

plot(as.vector(C), as.vector(Sigma), col="#00000040",
     xlab="Intended Covariances",
     ylab="Estimated Covariances")
abline(c(0,1), col="Gray")

2
+1,但是当您在第一句话中说“不确定”时,您的意思是什么?我在Wikipedia上进行了检查它说正半定值不是不确定的,即,不定意味着C具有正负特征值。那是你的意思吗?
变形虫说恢复莫妮卡

2
@amoeba是的,那是一个单据。感谢您的关注。“不确定”表示矩阵的签名同时具有正号和负号,而“半明确”表示签名仅具有一个符号。
ub

6

解决方法A

  1. 如果C不对称,则将其对称。D < 0.5(C+CT)
  2. 将身份矩阵的倍数添加到对称C上,足以使其具有任意余量m的正定值,即,使得新矩阵的最小特征值具有最小特征值= m。具体来说,D < ,其中I是单位矩阵。D包含所需的正定协方差矩阵。D+(mmin(eigenvalue(D)))I

在MATLAB中,代码为

D = 0.5 * (C + C');
D =  D + (m - min(eig(CD)) * eye(size(D));

求解方法B:制定并求解一个凸SDP(半确定程序),以根据它们的差的弗罗伯尼斯范数来找到最接近矩阵D到C,以使D为正定的,并具有指定的最小特征值m。

在MATLAB下使用CVX,代码将为:

n = size(C,1);
cvx_begin
variable D(n,n)
minimize(norm(D-C,'fro'))
D -m *eye(n) == semidefinite(n)
cvx_end

求解方法的比较:求解方法A除了对称化初始矩阵外,仅将对角元素调整(增加)一些共同的量,而使非对角元素保持不变。求解方法B从正定矩阵D和原始矩阵C之差的最小frobenius范数的意义上,找到具有指定最小特征值的最接近(距原始矩阵)正定矩阵。 D-C所有元素的平方差,以包括非对角元素。因此,通过调整非对角线元素,可以减少需要增加对角线元素的数量,并且对角线元素不必全部增加相同的数量。


2

我将从考虑您要估计的模型开始。

如果协方差矩阵不是正半定值,则可能表明您的变量中存在共线性问题,这将表明模型存在问题,不一定必须通过数值方法解决。

如果矩阵不是半正定进行数值的原因,然后有一些解决方案可以读到这里


1
假设该模型是线性混合模型。对于这种情况,为数据找到正确的模型无关紧要,而是以数据为例进行一些计算。现在,您有可能获得一个非正半定矩阵作为波罗涅夫估计。那么,如果我想从数据所来自的正态分布总体中找出协方差,该怎么做。假设样本是正态分布的。
克劳斯

1

一种方法是根据特征值分解来计算矩阵。现在,我承认我对这些过程背后的数学知识不太了解,但是从我的研究看来,看一下此帮助文件似乎很有成果:

http://stat.ethz.ch/R-manual/R-patched/library/Matrix/html/chol.html

和R中的其他一些相关命令。

另外,在Matrix软件包中检出“ nearPD”。

抱歉,我没有更多帮助,但是我希望我的搜索可以帮助您朝正确的方向发展。


嗨,谢谢。分别对应于特征值分解,这种分解无济于事,因为从那里可以获得平方根矩阵的复杂特征值,但是我需要转售价值矩阵。
克劳斯

1

您可以从R的Matrix包中的nearPD函数获得结果。这将为您提供一个真正有价值的矩阵。

library(Matrix)
A <- matrix(1, 3,3); A[1,3] <- A[3,1] <- 0
n.A <- nearPD(A, corr=T, do2eigen=FALSE)
n.A$mat

# 3 x 3 Matrix of class "dpoMatrix"
#           [,1]      [,2]      [,3]
# [1,] 1.0000000 0.7606899 0.1572981
# [2,] 0.7606899 1.0000000 0.7606899
# [3,] 0.1572981 0.7606899 1.0000000

对于R ..的用户,在我的答案中,这可能不是解决方法B的“穷人”版本(控制较少)。
马克·L·斯通

我同意这不是最佳选择,但有时可以达到目的。
迈克博士
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.