Math 如何生成对非对角元素有约束的伪随机正定矩阵?
用户希望对var/covar矩阵中每对变量之间的相关性施加一个唯一的、非平凡的上/下界 例如:我想要一个方差矩阵,其中所有变量都有0.9>rho(x|I,x|j)>0.6,rho(x|I,x|j)是变量x|I和x|j之间的相关性 谢谢Math 如何生成对非对角元素有约束的伪随机正定矩阵?,math,statistics,matrix,linear-algebra,Math,Statistics,Matrix,Linear Algebra,用户希望对var/covar矩阵中每对变量之间的相关性施加一个唯一的、非平凡的上/下界 例如:我想要一个方差矩阵,其中所有变量都有0.9>rho(x|I,x|j)>0.6,rho(x|I,x|j)是变量x|I和x|j之间的相关性 谢谢 好吧,我们已经找到了一个快速而肮脏的解决方案,不过如果有人知道更准确的方法,我们还是欢迎的 我丢失了我原来的登录名,所以我正在用新的登录名重新发布这个问题。 我得到了下面的答案 *你是说伪随机,这是半随机的正确术语——罗伯特·古尔德 *很好的观点,但我认为他的
好吧,我们已经找到了一个快速而肮脏的解决方案,不过如果有人知道更准确的方法,我们还是欢迎的
我丢失了我原来的登录名,所以我正在用新的登录名重新发布这个问题。 我得到了下面的答案 *你是说伪随机,这是半随机的正确术语——罗伯特·古尔德 *很好的观点,但我认为他的意思是半伪随机(伪随机是在谈论计算机随机性时假定的:-p)-fortran *“相关性”是指“协方差”吗斯万特 *不,我是说相关性。我想生成一个正定矩阵,这样所有的关联都比平凡的界限更紧瓦克 *看看我的答案。您坚持样本相关性在指定的范围内,还是仅仅是生成样本的总体相关性?如果你的问题是前者,我确实提出了一个可行的想法木片
*woodship:不,恐怕你的解决方案行不通,请在原始威胁中看到我的答案(上面的链接)。谢谢。以下是您对我在原始帖子中回答的回复: “来吧,伙计们,一定有更简单的事情” 对不起,没有。仅仅想中彩票是不够的。要求小熊队赢得系列赛是不够的。你也不能仅仅要求一道数学题的答案,然后突然发现它很容易 使用指定范围内的样本参数生成伪随机偏差的问题非常重要,至少在偏差在任何意义上都是真正的伪随机的情况下。取决于范围,一个人可能是幸运的。我提出了一个拒绝方案,但也表示这不太可能是一个好的解决方案。如果相关性有很多维度和很窄的范围,那么成功的概率很低。同样重要的是样本量,因为这将驱动产生相关性的样本方差
如果你真的想要一个解决方案,你需要坐下来,明确而准确地指定你的目标。您是否希望随机样本具有名义上指定的相关结构,但对相关有严格的限制?任何满足目标界限的样本相关矩阵都是令人满意的吗?是否也给出了差异?也许这个答案将有助于操作它: 一类具有非负确定性性质的矩阵是。以及~W()中的样本,这样所有非对角项都在某个界限[l,u]之间,这将符合您的问题。然而,我不相信这和所有非对角正定矩阵在[l,u]中的分布是一样的 在wikipedia页面上有一个从~W()计算的算法 一个更简单的、黑客式的解决方案(可能近似于此)是: (假设u>l且l>0)
sigma1 <- function(n,sigma) {
out <- matrix(sigma,n,n)
diag(out) <- 1
return (out)
}
library(mvtnorm)
sample_around_sigma <- function(size, upper,lower, tight=500) {
# size: size of matrix
# upper, lower: bounds on the corr, should be > 0
# tight: number of samples to use. ideally this
# would be calcuated such that the odd-diags will
# be "pretty likely" to fall in [lower,upper]
sigma <- sigma1(size,mean(c(upper,lower)))
means <- 0*1:size
samples <- rmvnorm(n=tight, mean=means,sigma=sigma)
return (cor(samples))
}
> A <- sample_around_sigma(5, .3,.5)
> A
[,1] [,2] [,3] [,4] [,5]
[1,] 1.0000000 0.3806354 0.3878336 0.3926565 0.4080125
[2,] 0.3806354 1.0000000 0.4028188 0.4366342 0.3801593
[3,] 0.3878336 0.4028188 1.0000000 0.4085453 0.3814716
[4,] 0.3926565 0.4366342 0.4085453 1.0000000 0.3677547
[5,] 0.4080125 0.3801593 0.3814716 0.3677547 1.0000000
>
> summary(A[lower.tri(A)]); var(A[lower.tri(A)])
Min. 1st Qu. Median Mean 3rd Qu. Max.
0.3678 0.3808 0.3902 0.3947 0.4067 0.4366
[1] 0.0003949876
sigma1好了,太棒了格雷格:我们有进展了。将您的想法与木片的想法结合起来,可以产生这种替代方法。从数学上讲,它非常脏,但似乎有效:
library(MCMCpack)
library(MASS)
p<-10
lb<-.6
ub<-.8
zupa<-function(theta){
ac<-matrix(theta,p,p)
fe<-rwish(100*p,ac%*%t(ac))
det(fe)
}
ba<-optim(runif(p^2,-10,-5),zupa,control=list(maxit=10))
ac<-matrix(ba$par,p,p)
fe<-rwish(100*p,ac%*%t(ac))
me<-mvrnorm(p+1,rep(0,p),fe)
A<-cor(me)
bofi<-sqrt(diag(var(me)))%*%t(sqrt((diag(var(me)))))
va<-A[lower.tri(A)]
l1=100
while(l1>0){
r1<-which(va>ub)
l1<-length(r1)
va[r1]<-va[r1]*.9
}
A[lower.tri(A)]<-va
A[upper.tri(A)]<-va
vari<-bofi*A
mk<-mvrnorm(10*p,rep(0,p),vari)
pc<-sign(runif(p,-1,1))
mf<-sweep(mk,2,pc,"*")
B<-cor(mf)
summary(abs(B[lower.tri(B)]))
库(MCMCpack)
图书馆(弥撒)
p您可以创建一组大小为M、单位方差的N个随机向量。然后将一个随机向量(大小N和单位方差)乘以某个数字k。
然后取所有向量之间的相关性,这将是一个正定矩阵。如果M非常大,则相关性分布中不会出现方差,相关性为:k^2/(1+k^2)。M越小,非对角元素的分布越宽。
或者,您可以让M非常大,并将“公共向量”分别乘以不同的k。如果正确使用这些参数,您可能会得到更严格的控制。下面是一些Matlab代码:
clear all;
vecLarg=10;
theDim=1000;
corrDist=0*randn(theDim,1);
Baux=randn(vecLarg,theDim)+ (corrDist*randn(1,vecLarg))'+(k*ones(theDim,1)*randn(1,vecLarg))' ;
A=corrcoef(Baux);
hist(A(:),100);
Woodchips,非常感谢您的投入。请允许我澄清一下,你从我的回答中引用的内容是关于你在文章末尾提出的QP方法,而不是拒绝方案。你提出的拒绝方案有点棘手b/c我不确定在对特征值施加什么影响之前(除了明显的事实,它们应该是正的),有什么想法吗?TiaPS:Woodship,可以说,我对您原始输入的回答包含m