生成与一个向量相关但彼此之间不相关的随机变量
Generating random variables that are correlated with one vector but not between each other
我有一个包含正态分布随机变量的向量 s1
。我想再生成 4 个正态分布的随机向量,每个向量都有自己与 s1
的相关性以及自己的方差。我们称它们为 s2
到 s5
.
如果我使用 mvrnorm()
和协方差矩阵,我必须指定 s1
和每个其他向量之间的协方差,这很好。但我还必须指定每个其他向量之间的协方差(例如 s2
和 s3
之间),这并不好。我最终会得到 s2
和 s3
之间的相关性,没有理由应该有一个相关性。
如何生成具有指定(和不同)标准差和指定协方差的 s2
到 s5
,而不强制 s2
到 s5
?
编辑:这是将 rho(3,2) 设置为零后的协方差矩阵
[,1] [,2] [,3]
[1,] 0.00022500 0.0002625 0.00044625
[2,] 0.00026250 0.0006250 0.00000000
[3,] 0.00044625 0.0000000 0.00122500
只需将协方差矩阵中的相应元素设置为0
:
library(MASS)
set.seed(1)
(sig <- matrix(c(5, .5, .8, .5, 1, 0, .8, 0, .5), 3))
# [,1] [,2] [,3]
# [1,] 5.0 0.5 0.8
# [2,] 0.5 1.0 0.0 ## <- 0 = covariance between s2 and s3
# [3,] 0.8 0.0 0.5
x <- mvrnorm(1e5, rep(0, 3), sig)
cov(x)
# [,1] [,2] [,3]
# [1,] 5.0356870 0.5100643820 0.8004814044
# [2,] 0.5100644 1.0042540190 0.0008037978
# [3,] 0.8004814 0.0008037978 0.4972328657
## with empirical = TRUE you can force the cov matrix to match exactly sig
cov(mvrnorm(1e5, rep(0, 3), sig, empirical = TRUE))
# [,1] [,2] [,3]
# [1,] 5.0 5.000000e-01 8.000000e-01
# [2,] 0.5 1.000000e+00 -2.267044e-15
# [3,] 0.8 -2.267044e-15 5.000000e-01
根据评论更新
如果问题是求正定相关矩阵,可以用Matrix::nearPD
求最近的正定矩阵:
set.seed(1)
sig <- structure(c(0.000225, 0.0002625, 0.00044625,
0.0002625 , 0.000625, 0,
0.00044625, 0 , 0.001225),
.Dim = c(3L, 3L))
cov(mvrnorm(1e5, rep(0, 3), Matrix::nearPD(sig, TRUE, TREU)$mat, empirical = TRUE))
# V1 V2 V3
# V1 1.00000000 2.625000e-04 4.462500e-04
# V2 0.00026250 1.000000e+00 3.614917e-15
# V3 0.00044625 3.614917e-15 1.000000e+00
我有一个包含正态分布随机变量的向量 s1
。我想再生成 4 个正态分布的随机向量,每个向量都有自己与 s1
的相关性以及自己的方差。我们称它们为 s2
到 s5
.
如果我使用 mvrnorm()
和协方差矩阵,我必须指定 s1
和每个其他向量之间的协方差,这很好。但我还必须指定每个其他向量之间的协方差(例如 s2
和 s3
之间),这并不好。我最终会得到 s2
和 s3
之间的相关性,没有理由应该有一个相关性。
如何生成具有指定(和不同)标准差和指定协方差的 s2
到 s5
,而不强制 s2
到 s5
?
编辑:这是将 rho(3,2) 设置为零后的协方差矩阵
[,1] [,2] [,3]
[1,] 0.00022500 0.0002625 0.00044625
[2,] 0.00026250 0.0006250 0.00000000
[3,] 0.00044625 0.0000000 0.00122500
只需将协方差矩阵中的相应元素设置为0
:
library(MASS)
set.seed(1)
(sig <- matrix(c(5, .5, .8, .5, 1, 0, .8, 0, .5), 3))
# [,1] [,2] [,3]
# [1,] 5.0 0.5 0.8
# [2,] 0.5 1.0 0.0 ## <- 0 = covariance between s2 and s3
# [3,] 0.8 0.0 0.5
x <- mvrnorm(1e5, rep(0, 3), sig)
cov(x)
# [,1] [,2] [,3]
# [1,] 5.0356870 0.5100643820 0.8004814044
# [2,] 0.5100644 1.0042540190 0.0008037978
# [3,] 0.8004814 0.0008037978 0.4972328657
## with empirical = TRUE you can force the cov matrix to match exactly sig
cov(mvrnorm(1e5, rep(0, 3), sig, empirical = TRUE))
# [,1] [,2] [,3]
# [1,] 5.0 5.000000e-01 8.000000e-01
# [2,] 0.5 1.000000e+00 -2.267044e-15
# [3,] 0.8 -2.267044e-15 5.000000e-01
根据评论更新
如果问题是求正定相关矩阵,可以用Matrix::nearPD
求最近的正定矩阵:
set.seed(1)
sig <- structure(c(0.000225, 0.0002625, 0.00044625,
0.0002625 , 0.000625, 0,
0.00044625, 0 , 0.001225),
.Dim = c(3L, 3L))
cov(mvrnorm(1e5, rep(0, 3), Matrix::nearPD(sig, TRUE, TREU)$mat, empirical = TRUE))
# V1 V2 V3
# V1 1.00000000 2.625000e-04 4.462500e-04
# V2 0.00026250 1.000000e+00 3.614917e-15
# V3 0.00044625 3.614917e-15 1.000000e+00