[最近の質問で、Rでランダムなベクトルを生成することを検討しており、その「研究」を特定のポイントに関する独立したQ&Aとして共有したいと思いました。]
相関してランダムなデータを生成する相関行列のコレスキー分解を用いて行うことができるここでの前記事に反映されるように、ここで及びここ。
私が対処したいのは、Rの異なる周辺分布から相関乱数を生成するために均一分布を使用する方法です。
[最近の質問で、Rでランダムなベクトルを生成することを検討しており、その「研究」を特定のポイントに関する独立したQ&Aとして共有したいと思いました。]
相関してランダムなデータを生成する相関行列のコレスキー分解を用いて行うことができるここでの前記事に反映されるように、ここで及びここ。
私が対処したいのは、Rの異なる周辺分布から相関乱数を生成するために均一分布を使用する方法です。
回答:
質問は
"均一分布を使用して異なる周辺分布から相関乱数を生成する方法"
そして、通常のランダム変量だけでなく、上記の答えは、周辺分布の任意のペアに対して意図された相関を持つシミュレーションを生成しません。
その理由は、ほとんどのcdfsおよび、標準正規累積分布関数を表します。、G Y COR (X 、Y )≠ COR (G - 1 X(Φ (X )、G - 1 Y(Φ (Y ))、(X 、Y )〜N 2(0 、Σ )、Φ
つまり、ここでは、周辺分布のペアとしてExp(1)とGamma(.2,1)を使用した反例を示します。
library(mvtnorm)
#correlated normals with correlation 0.7
x=rmvnorm(1e4,mean=c(0,0),sigma=matrix(c(1,.7,.7,1),ncol=2),meth="chol")
cor(x[,1],x[,2])
[1] 0.704503
y=pnorm(x) #correlated uniforms
cor(y[,1],y[,2])
[1] 0.6860069
#correlated Exp(1) and Ga(.2,1)
cor(-log(1-y[,1]),qgamma(y[,2],shape=.2))
[1] 0.5840085
別の明らかな反例は、がコーシーである場合です。この場合、相関は定義されません。
全体像を示すために、と両方が任意であるRコードをます。G Y
etacor=function(rho=0,nsim=1e4,fx=qnorm,fy=qnorm){
#generate a bivariate correlated normal sample
x1=rnorm(nsim);x2=rnorm(nsim)
if (length(rho)==1){
y=pnorm(cbind(x1,rho*x1+sqrt((1-rho^2))*x2))
return(cor(fx(y[,1]),fy(y[,2])))
}
coeur=rho
rho2=sqrt(1-rho^2)
for (t in 1:length(rho)){
y=pnorm(cbind(x1,rho[t]*x1+rho2[t]*x2))
coeur[t]=cor(fx(y[,1]),fy(y[,2]))}
return(coeur)
}
異なるcdf を、分布との対数正規分布のこの特別なケースを。 G X 、G Y
rhos=seq(-1,1,by=.01)
trancor=etacor(rho=rhos,fx=function(x){qchisq(x,df=3)},fy=qlnorm)
plot(rhos,trancor,ty="l",ylim=c(-1,1))
abline(a=0,b=1,lty=2)
これは、対角線からどれだけ離れているかを示しています。
最後の警告 2つの任意の分布および与えられた場合、の可能な値の範囲は必ずしもはありません 。したがって、問題には解決策がない可能性があります。、G Y COR (X 、Y )(- 1 、1 )
correlate
パッケージを書きました。人々はそれが有望であると言った(Journal of Statistical Softwareに掲載する価値がある)が、私は学術的なキャリアを追求しないことを選択したので、そのための論文を書いたことがなかった。
メンテナンスされていないcorrelate
パッケージはまだCRAN にあると思います。
インストールすると、次のことができます。
require('correlate')
a <- rnorm(100)
b <- runif(100)
newdata <- correlate(cbind(a,b),0.5)
結果は、単変量の分布を変化させずに、そのNEWDATAは0.5の相関関係を持つことになりますですa
とb
(同じ値が、彼らはただ、多変量0.5相関が達成されるまでの周りに移動します、があります。
ドキュメントが不足していることをお詫びします。
所定の相関に従って、標準正規ランダム分布から相関データの2つのサンプルを生成します。
例として、相関r = 0.7を選び、次のような相関行列をコーディングします。
(C <- matrix(c(1,0.7,0.7,1), nrow = 2))
[,1] [,2]
[1,] 1.0 0.7
[2,] 0.7 1.0
mvtnorm
これで、これらの2つのサンプルを2変量ランダムベクトルとして生成できます。
set.seed(0)
SN <- rmvnorm(mean = c(0,0), sig = C, n = 1e5)
〜として配布2つのベクトル成分をもたらすとを有します。両方のコンポーネントは、次のように抽出できます。cor(SN[,1],SN[,2])= 0.6996197 ~ 0.7
X1 <- SN[,1]; X2 <- SN[,2]
これが回帰直線が重なっているプロットです:
使用する確率積分を変換し 、ここで取得するために周辺分布を持つ二変数のランダムなベクトルを〜と同じ相関:
U <- pnorm(SN)
-したがってpnorm
、(または)SN
を見つけるためにベクターにフィードしています。その過程で、を保存します。Φ (S N )cor(U[,1], U[,2]) = 0.6816123 ~ 0.7
再び、ベクトルU1 <- U[,1]; U2 <- U[,2]
を分解して、エッジに周辺分布がある散布図を作成し、均一な性質を明確に示すことができます。
ここで逆変換サンプリング法を適用して、再現しようと試みたどの分布族に属する等しく相関したポイントのバイベクトルを最終的に取得します。
ここから、正規分布で、分散が等しいか異なる 2つのベクトルを生成できます。:例えばY1 <- qnorm(U1, mean = 8,sd = 10)
、およびY2 <- qnorm(U2, mean = -5, sd = 4)
、所望の相関を維持していますcor(Y1,Y2) = 0.6996197 ~ 0.7
。
または、別のディストリビューションを選択します。選択した分布が非常に異なる場合、相関関係はそれほど正確ではない可能性があります。たとえば、3 dfの分布と、 = 1:およびTheの指数関数U1
を追跡してみましょう。それぞれのヒストグラムは次のとおりです。λU2
Z1 <- qt(U1, df = 3)
Z2 <- qexp(U2, rate = 1)
cor(Z1,Z2) [1] 0.5941299 < 0.7
以下は、プロセス全体と通常のマージナルのコードの例です。
Cor_samples <- function(r, n, mean1, mean2, sd1, sd2){
C <- matrix(c(1,r,r,1), nrow = 2)
require(mvtnorm)
SN <- rmvnorm(mean = c(0,0), sig = C, n = n)
U <- pnorm(SN)
U1 <- U[,1]
U2 <- U[,2]
Y1 <<- qnorm(U1, mean = mean1,sd = sd1)
Y2 <<- qnorm(U2, mean = mean2,sd = sd2)
sample_measures <<- as.data.frame(c(mean(Y1), mean(Y2), sd(Y1), sd(Y2), cor(Y1,Y2)), names<-c("mean Y1", "mean Y2", "SD Y1", "SD Y2", "Cor(Y1,Y2)"))
sample_measures
}
比較のために、コレスキー分解に基づく関数をまとめました。
Cholesky_samples <- function(r, n, mean1, mean2, sd1, sd2){
C <- matrix(c(1,r,r,1), nrow = 2)
L <- chol(C)
X1 <- rnorm(n)
X2 <- rnorm(n)
X <- rbind(X1,X2)
Y <- t(L)%*%X
Y1 <- Y[1,]
Y2 <- Y[2,]
N_1 <<- Y[1,] * sd1 + mean1
N_2 <<- Y[2,] * sd2 + mean2
sample_measures <<- as.data.frame(c(mean(N_1), mean(N_2), sd(N_1), sd(N_2), cor(N_1, N_2)),
names<-c("mean N_1", "mean N_2", "SD N_1", "SD N_2","cor(N_1,N_2)"))
sample_measures
}
両方の方法を試して、分散した相関(たとえば、)サンプルを生成します。取得したおよびサンプルを設定します。N (97 、23 )N (32 、8 )set.seed(99)
制服の使用:
cor_samples(0.7, 1000, 97, 32, 23, 8)
c(mean(Y1), mean(Y2), sd(Y1), sd(Y2), cor(Y1, Y2))
mean Y1 96.5298821
mean Y2 32.1548306
SD Y1 22.8669448
SD Y2 8.1150780
cor(Y1,Y2) 0.7061308
およびコレスキーの使用:
Cholesky_samples(0.7, 1000, 97, 32, 23, 8)
c(mean(N_1), mean(N_2), sd(N_1), sd(N_2), cor(N_1, N_2))
mean N_1 96.4457504
mean N_2 31.9979675
SD N_1 23.5255419
SD N_2 8.1459100
cor(N_1,N_2) 0.7282176