给定指定的相关值,创建正定 3x3 协方差矩阵

机器算法验证 相关性 协方差
2022-04-16 07:18:15

假设我有 3 个变量,ABC并且我想生成数据,其中AB相关r=xA并且C相关r=y,并且BC相关r=z

  1. 是否有任何算法可以告诉我,给定、 和的指定值x如果有 , 的任何一组方差并且会产生一个正定协方差矩阵?yzABC
  2. 鉴于这种算法的存在,是否还有另一种算法,在可能存在正定协方差矩阵情况下,会给我一组实现正定矩阵的方差?
2个回答

要跟进@cardinal 的评论:您的x,y, 和z定义一个(3×3)相关矩阵R. 由于相关矩阵也是(标准化变量的)可能的协方差矩阵,因此它必须是正定的。如果所有特征值都是>0. 如果R确实是正定的,那么所有方差向量(即数字)将把变成正定协方差矩阵,其中制成的对角矩阵s>0RΣ=Ds1/2RDs1/2Ds1/2s

因此,只需从构造并检查特征值是否都如果是这样,那么您很好,您可以将任何数据集转换为具有任意方差的相应协方差矩阵:Rx,y,z>0

x <- 0.5
y <- 0.3                            # changing this to -0.6 makes it not pos.def.
z <- 0.4
R <- matrix(numeric(3*3), nrow=3)   # will be the correlation matrix
diag(R) <- 1                        # set diagonal to 1
R[upper.tri(R)] <- c(x, y, z)       # fill in x, y, z to upper right
R[lower.tri(R)] <- c(x, y, z)       # fill in x, y, z to lower left
eigen(R)$values                     # get eigenvalues to check if pos.def.

[1] 1.8055810 0.7124457 0.4819732

所以我们是正定的。现在从任意方差构造相应的协方差矩阵。R

vars  <- c(4, 16, 9)                # the variances
Sigma <- diag(sqrt(vars)) %*% R %*% diag(sqrt(vars))

生成一些数据矩阵,我们稍后将转换为具有该协方差矩阵。X

library(mvtnorm)                    # for rmvnorm()
N  <- 100                           # number of simulated observations
mu <- c(1, 2, 3)                    # some arbitrary centroid
X  <- round(rmvnorm(n=N, mean=mu, sigma=Sigma))

为此,我们首先对矩阵进行正交归一化,给出矩阵和协方差矩阵(恒等式)。XYI

orthGS <- function(X) {             # implement Gram-Schmidt algorithm
    Id <- diag(nrow(X))
    for(i in 2:ncol(X)) {
        A <- X[ , 1:(i-1), drop=FALSE]
        Q <- qr.Q(qr(A))
        P <- tcrossprod(Q)
        X[ , i] <- (Id-P) %*% X[ , i]
    }
    scale(X, center=FALSE, scale=sqrt(colSums(X^2)))
}

Xctr <- scale(X, center=TRUE, scale=FALSE)  # centered version of X
Y    <- orthGS(Xctr)                        # Y is orthonormal

变换矩阵具有协方差矩阵和质心YΣμ

编辑:这里发生了什么:做一个谱分解,其中是归一化特征向量的矩阵是对应的特征值矩阵。现在矩阵有协方差矩阵,作为Σ=GDGtGΣDGD1/2YGD1/2Cov(Y)D1/2Gt=GDGt=ΣCov(Y)=I

eig    <- eigen(Sigma)
A      <- eig$vectors %*% sqrt(diag(eig$values))
XX1ctr <- t(A %*% t(Y)) * sqrt(nrow(Y))
XX1    <- sweep(XX1ctr, 2, mu, "+")         # move centroid to mu

检查相关矩阵是否真的是R

> all.equal(cor(XX1), R)
[1] TRUE

出于其他目的,现在的问题可能是:我如何找到一个与预先指定的非正定矩阵“非常相似”的正定矩阵。我不知道。

编辑:更正了一些平方根

如果您没有给出完整的相关集合,而只是部分集合,那么您可以构造一个半定规划可行性问题,该问题可用于确定是否存在具有指定相关性的相关矩阵。这可以通过各种 SDP 求解器解决,例如 SeDuMi 和 SDPT3。