- こちらの続き
- 複数の確率変数がそれぞれ正規分布に従うときに、その同時分布は、変数間の相関の程度に応じて、「球」を「楕円」にすることで実現できる。それが、こちらで、正規分布だったらいいのにな、という話
- 球の楕円化は、行列でコレスキー分解とか固有値分解して正規直交基底の取り方を変えつつ、基底軸方向に伸び縮みさせること。いうれにしろ線形代数
- 以下の操作は、線形代数処理を使って、相互に相関のある正規分布変数に関して、多サンプルのデータを作った上で、その累積確率密度相当値を用いて、正規分布以外の確率変数に変換するというもの
- 例として指数分布でやってみたもの
- 10000サンプル、10変数、平均値が1:10 (したがって分散はその2乗の(1:10)^2)であって、変数相互の相関は相関係数として正規分布だったら0.7となるようにして発生させたもの
- 発生させた個々の変数の平均と分散は、指定したものになっていることを確認し
- 個々の変数の分布が指数分布様であることを1変数の度数分布で確認し
- 2変数の同時分布を2次元ヒストグラムとして描いてある
- 結果として得られた相関係数はだいたい、0.87くらい
- さらに、変数間の相関の程度をばらばらにしてやっても、まずまず、うまく相関がとれる
mvrexp = function(n=10000, m=20, r=0.1, method="eigen", af=NULL){
rho<-NULL
ER<-NULL
if(is.matrix(r)){
ER = sin(pi*r/2)
}else{
ER = matrix(rep(sin(pi*r/2), m^2), m,m)
diag(ER) = 1
}
X = matrix(rnorm(n*m),n)
if(method=="cholesky"){
X = X%*%chol(ER)
}else if(method=="eigen"){
ER.e=eigen(ER)
ER.e[[1]][ER.e[[1]]<0]=0
X = X%*%diag(sqrt(ER.e[[1]]))%*%t(ER.e[[2]])
}
if(is.null(af)){
af = rep(1, m)
}else if(length(af)==1){
af = rep(af, m)
}
for(i in 1:m){
X[,i] = qexp(pnorm(X[,i]),af[i])
}
return(X)
}
n<-10000
m<-10
af<-1:m
r<-0.7
tmpdata<-matrix(runif(n*m),n,m)
for(i in 1:m){
tmpdata[,i]<-tmpdata[,i]+tmpdata[,sample(1:m,1)]*rpois(1,4)
}
rmat<-cor(tmpdata)
X<-mvrexp(n=n,m=m,af=1/af,r=rmat)
layout(matrix(c(1,2,3,4,5,6,6,7,7,7,6,6,7,7,7),3,5,byrow=TRUE))
cor(X)
image(rmat)
image(cor(X))
plot(c(cor(X)),c(rmat))
apply(X,2,mean)
apply(X,2,var)
plot(af,apply(X,2,mean))
plot(apply(X,2,mean),sqrt(apply(X,2,var)))
hist(X[,1])
library(gregmisc)
h2d <- hist2d(X[,1],X[,2], show=FALSE,same.scale=TRUE,nbins=c(10,10))
persp( h2d$x, h2d$y, h2d$counts,ticktype="detailed",theta=50, phi=30,shade=0.5, col="red")
par(mfcol=c(1,1))