用户想要对var / covar矩阵中每对变量之间的相关性施加一个独特的,非平凡的上/下界限。
例如:我想要一个方差矩阵,其中所有变量都有0.9> | RHO(X_I,x_j)| > 0.6,rho(x_i,x_j)是变量x_i和x_j之间的相关性。
感谢。
好的,已经发现了一些快速和肮脏的解决方案,如果有人知道更多完全的方式,那么它将受到欢迎。
我丢失了原来的登录信息,因此我将在新登录时重新发布该问题。 The previous iteration得到了以下答案
*你的意思是伪随机,这是半随机的正确术语 - 罗伯特古尔德
*好点,但我认为他的意思是半伪随机(在谈论计算机随机性时假设伪:-p) - fortran
*“关联”是指“协方差”吗? - 斯万特
*不,我的确意味着相关性。我想生成一个正定矩阵,使所有相关性都比平凡边界更紧密。 - vak
*看我的回答。您是否坚持样本相关性在指定范围内,或仅仅是生成样本的总体相关性?如果您的问题是前者,我建议您提出一个可行的建议。 - woodchips
* woodship:不,我担心你的解决方案不起作用,请在原始威胁中查看我的答案(上面的链接)。感谢。
答案 0 :(得分:2)
以下是您对原始帖子中我的回答的回复:
“来吧,人们必须有更简单的事情”
对不起,但没有。想要赢得彩票是不够的。要求小熊队赢得系列赛是不够的。你也不能要求解决数学问题,突然发现它很容易。
产生伪随机偏差与指定范围内的样本参数的问题是非常重要的,至少如果偏差在任何意义上都是真正的伪随机的话。根据范围,一个人可能是幸运的。我提出了拒绝计划,但也表示它不太可能成为一个好的解决方案。如果相关性存在许多维度和紧密范围,那么成功的可能性就很小。同样重要的是样本大小,因为这将推动所得相关性的样本方差。
如果你真的想要一个解决方案,你需要坐下来,明确而准确地指定你的目标。您是否想要一个具有标称指定相关结构的随机样本,但是对相关性有严格的界限?任何满足目标界限的样本相关矩阵是否令人满意?是否也给出了差异?
答案 1 :(得分:2)
您可以创建一组大小为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);
答案 2 :(得分:1)
也许这个答案有助于实现它:
具有非负定性属性的一类矩阵是Wishart Distribution。来自~W()的样本使得所有非对角线条目都在某些边界[l,u]之间,这符合您的问题。但是,我不认为这与[l,u]中所有带有非对角线的正定矩阵的分布相同。
在维基百科页面上有一个从~W()计算的算法。
一个更简单,更具刺激性的解决方案(可能与此类似)是:
(假设你> l和l> 0)
所以这真的回答似乎并不重要!
正如其他海报所建议的,您可以从Wishart生成,然后保留您想要的属性为真的那些,但您可能会长时间采样!如果排除那些0-definite(那是一个单词?)那么这应该适用于生成好的矩阵。然而,这不是所有pos-def矩阵的真实分布,其off-diags在[l,u]中。
上面提出的哑采样方案的代码(在R中)
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
答案 3 :(得分:1)
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)]))
基本上,这是一个想法(比如上限= .8并降低它的界限= .6),它具有足够好的接受率,这不是100%,但它会在项目的这个阶段完成。