No.10589 相関を持つランダムウオークの素?  【のざわ】 2009/08/05(Wed) 12:47

以前に相関を持つ二つのランダム列の作り方で質問したものです。

先生のHPで紹介されていたコレスキー分解を使った方法だと発生する乱数の総和が0になってしまい,自分の希望するものが取り出せなかったのですが,以下のように解決しました。

library(fCopulae)
a<-rnorm2d(1000, rho = 0.5) #相関が0.5の乱数を1000個作れ!
lm(a[,1]~a[,2]+0) #一列目と2列目の相関係数を求めよ。
mean(a[,1]) #平均は?
mean(a[,2])
sd(a[,1]) #標準偏差は?
sd(a[,2])
sum(a[,1]) #合計は?
sum(a[,2])

コピュラ関数のライブラリの中に,分布を指定した,相関を持つ乱数列の発生関数があったので,それを使いました。

各々の列が,N(0,1^2)に従い,相関係数0.5を持っています。また総和も,発生させるたびに変化します。

お世話になりました。

No.10590 Re: 相関を持つランダムウオークの素?  【青木繁伸】 2009/08/05(Wed) 13:47

要するに,わずかの誤差が加わっているだけですね。
総和は変化しますが,その期待値は0になると思いますよ。総和は0ではないが,期待値は0。
それで良いのなら,jitter(gendat2(n, r), amount=b) で同じような結果になるでしょう。b によって,誤差の大きさを制御できます。
> b <- jitter(gendat2(1000, 0.5), amount=0.5)
> colMeans(b)
[1] 0.007336982 -0.002774689
> colSums(b)
[1] 7.336982 -2.774689
> sd(b)
[1] 1.037291 1.047597
> cor(b[,1], b[,2])
[1] 0.4493309
あるいは,母集団からのサンプリングによるサンプリング誤差を利用して総和が0にならないようにということなら,gendat2 を使って多めにデータを生成し,そこから必要なだけサンプリングするというやり方もありますね。
> b <- gendat2(2000, 0.5)
> b <- b[sample(2000, 1000),] # 2000個発生させた内から1000個を抽出
> colMeans(b)
[1] 0.008418455 0.031340145
> sd(b)
[1] 1.010507 1.008196
> colSums(b)
[1] 8.418455 31.340145
> cor(b[,1], b[,2])
[1] 0.4848518
なお,rnorm2d は,MASS ライブラリの mvrnorm 関数で,empirical=FALSE を指定する(デフォルト)のと同じになるでしょう。
> library(MASS)
> b <- mvrnorm(1000, mu=c(0,0), Sigma=matrix(c(1,0.5,0.5,1),2), empirical=FALSE)
> colMeans(b)
[1] 0.01817952 0.02084953
> sd(b)
[1] 0.9988818 1.0019586
> colSums(b)
[1] 18.17952 20.84953
> cor(b[,1], b[,2])
[1] 0.5293974
なお,empirical=TRUE とすれば,指定した平均値,標準偏差(相関係数)を持つ乱数列を返し,その場合は gendat2 と同じ性質を持つことになります。
> b <- mvrnorm(1000, mu=c(0,0), Sigma=matrix(c(1,0.5,0.5,1),2), empirical=TRUE)
> colMeans(b)
[1] -9.742207e-18 -2.105607e-17
> sd(b)
[1] 1 1
> colSums(b)
[1] -9.742207e-15 -2.105607e-14
> cor(b[,1], b[,2])
[1] 0.5

● 「統計学関連なんでもあり」の過去ログ--- 042 の目次へジャンプ
● 「統計学関連なんでもあり」の目次へジャンプ
● 直前のページへ戻る