既存の変数と定義された相関関係を持つランダム変数を生成します


71

シミュレーション研究のために、既存の変数に対する事前定義された(母集団)相関を示すランダム変数を生成する必要があります。Y

私は、に見えたRパッケージcopulaCDVine特定の依存構造を持つランダムな多変量分布を生成することができました。ただし、結果の変数の1つを既存の変数に修正することはできません。

アイデアや既存の機能へのリンクを歓迎します!


結論: さまざまなソリューションで、2つの有効な答えが出ました。

  1. カラカルによるR スクリプト。事前定義された変数との正確な(サンプル)相関を持つランダム変数を計算します
  2. 事前定義された変数に対する定義された母集団相関を持つランダム変数を計算するR 関数

[@ttnphnsの追加:質問のタイトルを単一の固定変数の場合から任意の数の固定変数に拡大するために自由を取りました。すなわち、いくつかの固定された既存の変数と事前定義された相関を持つ変数を生成する方法]


2
この関連する質問stats.stackexchange.com/questions/13382/を参照してください。これはあなたの質問に直接対処します(少なくとも理論的な側面)。
マクロ

次のQも関連性が高く、興味深いものになります。相関乱数の生成方法(分散と相関度を意味する)
GUNG -モニカ元に戻し

回答:


56

もう1つあります。平均が0のベクトルの場合、相関は角度のコサインに等しくなります。したがって、角度対応する正確に望ましい相関持つベクトルを見つける1つの方法:のR θxrθ

  1. 固定ベクトルとランダムベクトル取得するx 2x1x2
  2. 両方のベクトルを中央に配置し(平均0)、ベクトル、を与える ˙ X 2x˙1x˙2
  3. 作るに直交(直交部分空間への投影)を与える ˙ X 1 ˙ X 2x˙2x˙1x˙2
  4. スケールと長さ1に対して、与え と ˙ X 2 ˉ X 1 ˉ X 2x˙1x˙2x¯1x¯2
  5. ˉ X 1θ ˉ X 1RX1x¯2+(1/tan(θ))x¯1は、に対する角度を持つベクトルです。 はであり、との相関 はです。線形変換は相関関係を変更しないため、これはへの相関関係でもあります。x¯1θx¯1rx1

コードは次のとおりです。

n     <- 20                    # length of vector
rho   <- 0.6                   # desired correlation = cos(angle)
theta <- acos(rho)             # corresponding angle
x1    <- rnorm(n, 1, 1)        # fixed given data
x2    <- rnorm(n, 2, 0.5)      # new random data
X     <- cbind(x1, x2)         # matrix
Xctr  <- scale(X, center=TRUE, scale=FALSE)   # centered columns (mean 0)

Id   <- diag(n)                               # identity matrix
Q    <- qr.Q(qr(Xctr[ , 1, drop=FALSE]))      # QR-decomposition, just matrix Q
P    <- tcrossprod(Q)          # = Q Q'       # projection onto space defined by x1
x2o  <- (Id-P) %*% Xctr[ , 2]                 # x2ctr made orthogonal to x1ctr
Xc2  <- cbind(Xctr[ , 1], x2o)                # bind to matrix
Y    <- Xc2 %*% diag(1/sqrt(colSums(Xc2^2)))  # scale columns to length 1

x <- Y[ , 2] + (1 / tan(theta)) * Y[ , 1]     # final new vector
cor(x1, x)                                    # check correlation = rho

ここに画像の説明を入力してください

正射影のための、Iを用い単にので、数値的安定性を改善する-decompositionを。Q R P = Q Q PQRP=QQ


コードをSPSS構文に書き直そうとしていました。20x1列を返すQR分解につまずきます。SPSSでは、Gram-Schmidt正規直交化(これもQR分解です)がありますが、結果のQ列を複製できません。QRアクションを噛んでください。または、プロジェクションを取得するための回避策を示します。ありがとう。
ttnphns

@caracalは、P <- X %*% solve(t(X) %*% X) %*% t(X)r = 0.6を生成しないため、回避策ではありません。私はまだ混乱しています。(Q <- qr.Q(qr(Xctr[ , 1, drop=FALSE]))SPSSであなたの表現を真似するのはうれしいが、方法はわからない。)
ttnphns

@ttnphns混乱して申し訳ありませんが、私のコメントは一般的なケースに対するものでした。例の状況にそれを適用する:QR分解を介して投影行列を取得することは、数値の安定性のためだけです。部分空間が行列列にまたがっている場合、投影行列はとして取得できます。Rでは、サブスペースがの最初の列にまたがっているので、ここで書くことができます。その場合、直交補数への投影の行列はIPです。 XP=X(XX)1XXXctr[ , 1] %*% solve(t(Xctr[ , 1]) %*% Xctr[ , 1]) %*% t(Xctr[ , 1])Xctr
カラカル

4
誰かが2つ以上のサンプルで同様のことを行う方法を明確にできますか?たとえば、rhoによってペアで相関する3つのサンプルが必要な場合、このソリューションをどのように変換してそれを達成できますか?
アンドレテラ

リミットケースのためにrho=1:私はこのような何かをすることが有用であることが分かっif (isTRUE(all.equal(rho, 1))) rho <- 1-10*.Machine$double.epsそう私はなっていた、NaNS
PatrickT

19

最も一般的な解決策を説明します。この一般性の問題を解決することにより、非常にコンパクトなソフトウェア実装を実現できます。2行のRコードで十分です。

ベクターの選択同じ長さで、、好きな分布に従います。 してみましょうの最小二乗回帰の残差もに対する:これは抽出からコンポーネントを。適切な複数のバック追加することによって、に、我々は、任意の所望の相関を有するベクトル生成することができると。任意の加法定数と正の乗法定数(任意の方法で自由に選択できます)までは、解はY Y X Y Y X Y Y ρ YXYYXYYXYYρY

XY;ρ=ρSD(Y)Y+1ρ2SD(Y)Y.

( " "は標準偏差に比例する計算を表します。)SD


これが作業Rコードです。を指定しない場合、コードは多変量標準正規分布から値を引き出します。X

complement <- function(y, rho, x) {
  if (missing(x)) x <- rnorm(length(y)) # Optional: supply a default if `x` is not given
  y.perp <- residuals(lm(x ~ y))
  rho * sd(y.perp) * y + y.perp * sd(y) * sqrt(1 - rho^2)
}

説明のために、コンポーネントを持つランダムを生成し、このとさまざまな指定された相関を持つを生成しました。それらはすべて同じ開始ベクトル作成されました。以下がその散布図です。各パネルの下部にある「ラグプロット」は、共通のベクトルを示しています。Y50XY;ρYX=(1,2,,50)Y

図

プロットには顕著な類似性がありますが、ありません:-)。


実験する場合は、これらのデータと図を生成したコードを以下に示します。(私は、結果をシフトおよびスケーリングする自由を使用することを気にしませんでした。これは簡単な操作です。)

y <- rnorm(50, sd=10)
x <- 1:50 # Optional
rho <- seq(0, 1, length.out=6) * rep(c(-1,1), 3)
X <- data.frame(z=as.vector(sapply(rho, function(rho) complement(y, rho, x))),
                rho=ordered(rep(signif(rho, 2), each=length(y))),
                y=rep(y, length(rho)))

library(ggplot2)
ggplot(X, aes(y,z, group=rho)) + 
  geom_smooth(method="lm", color="Black") + 
  geom_rug(sides="b") + 
  geom_point(aes(fill=rho), alpha=1/2, shape=21) +
  facet_wrap(~ rho, scales="free")

ところで、この方法は複数のに容易に一般化できます:数学的に可能な場合、が全体と指定された相関をますセット。通常の最小二乗法を使用して、からすべての効果を取り出し、と残差の適切な線形結合を形成します。(これは、双対基底の観点からこれを行うのに役立ちます。これは、疑似逆行列を計算することによって取得されます。次のコードは、のSVDを使用してそれを達成します。)YXY1,Y2,,Yk;ρ1,ρ2,,ρkYiYiXYiYY

ここでは、アルゴリズムのスケッチだR、行列の列として与えられているが。Yiy

y <- scale(y)             # Makes computations simpler
e <- residuals(lm(x ~ y)) # Take out the columns of matrix `y`
y.dual <- with(svd(y), (n-1)*u %*% diag(ifelse(d > 0, 1/d, 0)) %*% t(v))
sigma2 <- c((1 - rho %*% cov(y.dual) %*% rho) / var(e))
return(y.dual %*% rho + sqrt(sigma2)*e)

以下は、実験したい人のためのより完全な実装です。

complement <- function(y, rho, x) {
  #
  # Process the arguments.
  #
  if(!is.matrix(y)) y <- matrix(y, ncol=1)
  if (missing(x)) x <- rnorm(n)
  d <- ncol(y)
  n <- nrow(y)
  y <- scale(y) # Makes computations simpler
  #
  # Remove the effects of `y` on `x`.
  #
  e <- residuals(lm(x ~ y))
  #
  # Calculate the coefficient `sigma` of `e` so that the correlation of
  # `y` with the linear combination y.dual %*% rho + sigma*e is the desired
  # vector.
  #
  y.dual <- with(svd(y), (n-1)*u %*% diag(ifelse(d > 0, 1/d, 0)) %*% t(v))
  sigma2 <- c((1 - rho %*% cov(y.dual) %*% rho) / var(e))
  #
  # Return this linear combination.
  #
  if (sigma2 >= 0) {
    sigma <- sqrt(sigma2) 
    z <- y.dual %*% rho + sigma*e
  } else {
    warning("Correlations are impossible.")
    z <- rep(0, n)
  }
  return(z)
}
#
# Set up the problem.
#
d <- 3           # Number of given variables
n <- 50          # Dimension of all vectors
x <- 1:n         # Optionally: specify `x` or draw from any distribution
y <- matrix(rnorm(d*n), ncol=d) # Create `d` original variables in any way
rho <- c(0.5, -0.5, 0)          # Specify the correlations
#
# Verify the results.
#
z <- complement(y, rho, x)
cbind('Actual correlations' = cor(cbind(z, y))[1,-1],
      'Target correlations' = rho)
#
# Display them.
#
colnames(y) <- paste0("y.", 1:d)
colnames(z) <- "z"
pairs(cbind(z, y))

これは確かに素晴らしい解決策です。しかし、私は自分でそれを複数の変数(回答では固定変数)のケースに拡張することに失敗しました。、あなたが主張する。デモできますか?R以外のユーザーが読み取り可能な注釈付きコードを使用してください。YBTW, this method readily generalizes to more... Just use ordinary least squares... and form a suitable linear combination
ttnphns

1
@ttnphns私はそうしました。
whuberの

1
本当にありがとうございます!なるほど、私は今日、あなた自身のアプローチをSPSSでコーディングしました。あなたの本当に素晴らしい提案。私は、タスクを解決するために適用できる二重基底の概念を考えたことがありません。
ttnphns

同様のアプローチを使用して、均一に分布したベクトルを作成することは可能ですか?つまり、既存のベクトルがxあり、y相関する新しいベクトルを生成しxたいが、yベクトルを均一に分散させたいと考えています。
-Skumin

@Skumin 2つのベクトル間の関係を制御できるように、コピュラの使用を検討してください。
whuber

6

次に、別の計算アプローチを示します(このソリューションは、Enrico Schumannによるフォーラム投稿から採用されています)。Wolfgang(コメントを参照)によると、これはttnphnsによって提案されたソリューションと計算上同一です。

カラカルのソリューションとは対照的に、それは正確な相関関係を有するサンプルを生成しませんが、その二つのベクトル人口の相関関係に等しい。ρρ

次の関数は、指定された持つ母集団から引き出された2変量サンプル分布を計算できます。2つのランダム変数を計算するか、1つの既存の変数(パラメーターとして渡される)を受け取り、目的の相関関係を持つ2番目の変数を作成します。ρx

# returns a data frame of two variables which correlate with a population correlation of rho
# If desired, one of both variables can be fixed to an existing variable by specifying x
getBiCop <- function(n, rho, mar.fun=rnorm, x = NULL, ...) {
     if (!is.null(x)) {X1 <- x} else {X1 <- mar.fun(n, ...)}
     if (!is.null(x) & length(x) != n) warning("Variable x does not have the same length as n!")

     C <- matrix(rho, nrow = 2, ncol = 2)
     diag(C) <- 1

     C <- chol(C)

     X2 <- mar.fun(n)
     X <- cbind(X1,X2)

     # induce correlation (does not change X1)
     df <- X %*% C

     ## if desired: check results
     #all.equal(X1,X[,1])
     #cor(X)

     return(df)
}

この関数は、parameterを調整することにより、非正規周辺分布を使用することもできますmar.fun。ただし、1つの変数の修正は、正規分布変数でのみ機能するようですx!(これはマクロのコメントに関連している可能性があります)。

また、少なくともガウス分布とピアソン相関の場合は、結果の相関にバイアスをかけるように見えるため、元の投稿の「小さな補正係数」が削除されたことにも注意してください(コメントも参照)。


ρ

1
「rhoの小さな修正」(この文脈での目的は私にはわからない)を除いて、これはttnphnsが以前に提案したものとまったく同じであることを示すのは簡単です。この方法は、単純に相関行列のコレスキー分解に基づいて、目的の変換行列を取得します。たとえば、en.wikipedia.org / wiki / …を参照してください。そして、はい、これは母集団相関がに等しい2つのベクトルのみを提供しますrho
ヴォルフガング

「ローの小さな修正」は元の投稿にあり、ここで説明されています。実際、私はそれを本当に理解していません。しかし、rho = .3の50000のシミュレートされた相関の調査は、「小さな補正」なしで.299のrの平均が生成されることを示しいます。生産。したがって、その部分を関数から削除しました。
フェリックスS

私はこれが古いことを知っていますが、この方法は非正定相関行列では機能しないことにも注意したいです。たとえば、-1の相関。
zzk

1
ありがとう。:私は、x1が標準化平均= 0、SD = 1でない場合ということに気づいて、あなたではなくあなたが行を変更する必要があります、それを再スケーリングではないだろうX2 <- mar.fun(n)X2 <- mar.fun(n,mean(x),sd(x))X1とX2との間の所望の相関関係を得るために
デイブM

6

XYXrXrY=rX+EE0sd=1r2XYrXYXρ=r

rEXEXYX1,X2,X3,...

XrYYrY


2017年11月11日更新。今日、この古いスレッドに出くわしたので、最初に話していた反復フィッティングのアルゴリズムを示すことで、答えを広げることにしました。

これは、ランダムにシミュレートされた変数または既存の変数トレーニングして、指定された変数セット(必要に応じて反復回数に応じて)正確に相関または共変量する方法です(これらは変更できません)。Y X

Disclamer:私は発見に基づいて、優れたものに劣ることがわかりました。この反復解法双対基底を提案した今日このスレッドに@whuberで。@whuberのソリューションは反復的ではなく、私にとってより重要なことは、「私の」アルゴリズムよりもやや小さい入力「豚」変数の値に影響しているようです(タスクが「修正」する場合は資産になります既存の変数であり、ランダム変数をゼロから生成することはありません)。それでも、私は好奇心のために、それが機能するために公開しています(脚注も参照)。

したがって、変数、および変数をランダムに生成するか(値の「豚」)、または値を「修正」する必要がある既存のデータ変数である(固定)変数を指定しました。は相関関係(または共分散)と sに正確にします。すべてのデータは連続している必要があります。つまり、一意の値がたくさんあるはずです。X1,X2,...,XmYYr1,r2,...,rmX

アイデア:残差の反復近似を実行します。必要な(ターゲット)相関/共分散がわかっているので、を複数の線形予測子として使用して、予測値を計算できます。(現在のと理想的な予測から)初期残差を取得した後、予測子と相関しないように繰り返しトレーニングします。最後に、残差でを取り戻します。(この手順は、何年も前に理論をまったく知らなかったホイールの実験的な発明であり、SPSSでコーディングしました。)YXYY

  1. ターゲット sに:掛けて、クロス積の和に変換し。(は変数インデックスです。)rdf=n1Sj=rjdfjX

  2. すべての変数をZ標準化します(それぞれを中央に配置してから、上記の計算されたst。偏差で除算し)。したがって、およびは標準です。観測された平方和は、現在=です。dfYXdf

  3. 予測regressional係数計算することによっての目標に応じて複数の:S。YXrb=(XX)1S

  4. 計算は、の値を予測:。YY^=Xb

  5. E=YY^

  6. SSS=dfSSY^

  7. (反復を開始します。)現在のとすべての間のクロス積の観測合計を計算しますEXjCj=i=1nEiXij

  8. すべてのを近づける目的で値を修正します(はケースインデックスです)。EC0i

    Ei[corrected]=Eij=1mCjXijnj=1mXij2

    (分母は反復で変化せず、事前に計算します)

    または、代わりに、より効率的な式により、の平均がなることが保証され。最初に、ステップ7で sを事前に計算する各反復で中心を実行し、次にこのステップ8で次のように修正します。E0 EC

    Ei[corrected]=Eij=1mCjXij3i=1nXij2j=1mXij2

    (ここでも、分母は事前に知られています)1

  9. 持参その目標値に:SSEEi[corrected]=EiSSS/SSE

    ステップ7 にます。(たとえば、10〜20回の繰り返しが大きい、より多くの繰り返しが必要になります。ターゲット sが現実的である場合、は正であり、サンプルサイズが少なすぎる場合、常に繰り返し収束に直接。繰り返しを終了します。)mrSSSn

  10. 準備完了:すべてのがほぼゼロになりました。これは、残差がターゲットを復元するようにトレーニングされたことを意味します。フィッティング計算:。EのR Y Y [ 修正] = Y + ECErYY[corrected]=Y^+E

  11. 得られたはほぼ標準化されています。最後のストロークとして、ステップ2で行ったように、正確に標準化することができます。Y

  12. あなたは、供給することができるいずれかで分散し、意味あなたが好き。実際には、4つの統計-minmaxmeanstのうち DEV。-任意の2つの値を選択し、変数を線形に変換して、達成した s(相関)を変更せずにそれらをポーズすることができます(これはすべて線形再スケーリングと呼ばれます)。rYr

上記で述べたことを再度警告します。をに正確に引っ張ると、出力正規分布する必要がなくなります。r YYrY


Y X1補正式はさらに洗練されたものになる可能性があります。たとえば、相関を達成すると同時に、すべてのでより大きなホモ二乗性を保証することもできます-そのためのコードを実装しましたも。(そのような「ダブル」タスクがwhuberのようなよりきちんとした非反復的なアプローチを介して解決可能かどうかはわかりません。)YX


1
ご回答有難うございます。それも私が考えていた経験的/反復的な解決策です。ただし、シミュレーションには、費用のかかるフィッティング手順のない、より分析的なソリューションが必要です。幸い、私はちょうど...私はすぐに掲載する予定解決策を見つけた
フェリックスS

これは、2変量正規分布を生成するために機能しますが、任意の分布(または任意の非「加法」分布)には機能しません
マクロ

1
ソリューションのコーン全体を直接作成できる場合に、反復を提案する理由はわかりません。このアプローチには特別な目的がありますか?
whuberの

1
Y

1
@whuber、あなたのコメントは私が待っていたものです。実際、私の答え(私がリンクしている不均一分散性について)は、あなたへの挑戦を意図したものです。おそらく、あなたのソリューションを投稿するための招待状です。
ttnphns

4

私はプログラミングをしたいと思ったので、@ Adamの削除された答えを取り、Rで素敵な実装を書くことにしました。一般的な考え方は、2つのベクトルを使用して、特定の相関関係に到達するまで1つのベクトルをランダムに並べ替えることです。このアプローチは非常に強引ですが、実装は簡単です。

まず、入力ベクトルをランダムに並べ替える関数を作成します。

randomly_permute = function(vec) vec[sample.int(length(vec))]
randomly_permute(1:100)
  [1]  71  34   8  98   3  86  28  37   5  47  88  35  43 100  68  58  67  82
 [19]  13   9  61  10  94  29  81  63  14  48  76   6  78  91  74  69  18  12
 [37]   1  97  49  66  44  40  65  59  31  54  90  36  41  93  24  11  77  85
 [55]  32  79  84  15  89  45  53  22  17  16  92  55  83  42  96  72  21  95
 [73]  33  20  87  60  38   7   4  52  27   2  80  99  26  70  50  75  57  19
 [91]  73  62  23  25  64  51  30  46  56  39

...そしていくつかのサンプルデータを作成する

vec1 = runif(100)
vec2 = runif(100)

...入力ベクトルを置換し、それを参照ベクトルに関連付ける関数を作成します。

permute_and_correlate = function(vec, reference_vec) {
    perm_vec = randomly_permute(vec)
    cor_value = cor(perm_vec, reference_vec)
    return(list(vec = perm_vec, cor = cor_value))
  }
permute_and_correlate(vec2, vec1)
$vec
  [1] 0.79072381 0.23440845 0.35554970 0.95114398 0.77785348 0.74418811
  [7] 0.47871491 0.55981826 0.08801319 0.35698405 0.52140366 0.73996913
 [13] 0.67369873 0.85240338 0.57461506 0.14830718 0.40796732 0.67532970
 [19] 0.71901990 0.52031017 0.41357545 0.91780357 0.82437619 0.89799621
 [25] 0.07077250 0.12056045 0.46456652 0.21050067 0.30868672 0.55623242
 [31] 0.84776853 0.57217746 0.08626022 0.71740151 0.87959539 0.82931652
 [37] 0.93903143 0.74439384 0.25931398 0.99006038 0.08939812 0.69356590
 [43] 0.29254936 0.02674156 0.77182339 0.30047034 0.91790830 0.45862163
 [49] 0.27077191 0.74445997 0.34622648 0.58727094 0.92285322 0.83244284
 [55] 0.61397396 0.40616274 0.32203732 0.84003379 0.81109473 0.50573325
 [61] 0.86719899 0.45393971 0.19701975 0.63877904 0.11796154 0.26986325
 [67] 0.01581969 0.52571331 0.27087693 0.33821824 0.52590383 0.11261002
 [73] 0.89840404 0.82685046 0.83349287 0.46724807 0.15345334 0.60854785
 [79] 0.78854984 0.95770015 0.89193212 0.18885955 0.34303707 0.87332019
 [85] 0.08890968 0.22376395 0.02641979 0.43377516 0.58667068 0.22736077
 [91] 0.75948043 0.49734797 0.25235660 0.40125309 0.72147500 0.92423638
 [97] 0.27980561 0.71627101 0.07729027 0.05244047

$cor
[1] 0.1037542

...そして千回繰り返す:

n_iterations = lapply(1:1000, function(x) permute_and_correlate(vec2, vec1))

Rのスコープルールがそれを確保することを注意vec1し、vec2上記の使用匿名関数の外で、地球環境にあります。したがって、順列はすべて、生成した元のテストデータセットに関連しています。

次に、最大相関を見つけます。

cor_values = sapply(n_iterations, '[[', 'cor')
n_iterations[[which.max(cor_values)]]
$vec
  [1] 0.89799621 0.67532970 0.46456652 0.75948043 0.30868672 0.83244284
  [7] 0.86719899 0.55623242 0.63877904 0.73996913 0.71901990 0.85240338
 [13] 0.81109473 0.52571331 0.82931652 0.60854785 0.19701975 0.26986325
 [19] 0.58667068 0.52140366 0.40796732 0.22736077 0.74445997 0.40125309
 [25] 0.89193212 0.52031017 0.92285322 0.91790830 0.91780357 0.49734797
 [31] 0.07729027 0.11796154 0.69356590 0.95770015 0.74418811 0.43377516
 [37] 0.55981826 0.93903143 0.30047034 0.84776853 0.32203732 0.25235660
 [43] 0.79072381 0.58727094 0.99006038 0.01581969 0.41357545 0.52590383
 [49] 0.27980561 0.50573325 0.92423638 0.11261002 0.89840404 0.15345334
 [55] 0.61397396 0.27077191 0.12056045 0.45862163 0.18885955 0.77785348
 [61] 0.23440845 0.05244047 0.25931398 0.57217746 0.35554970 0.34622648
 [67] 0.21050067 0.08890968 0.84003379 0.95114398 0.83349287 0.82437619
 [73] 0.46724807 0.02641979 0.71740151 0.74439384 0.14830718 0.82685046
 [79] 0.33821824 0.71627101 0.77182339 0.72147500 0.08801319 0.08626022
 [85] 0.87332019 0.34303707 0.45393971 0.47871491 0.29254936 0.08939812
 [91] 0.35698405 0.67369873 0.27087693 0.78854984 0.87959539 0.22376395
 [97] 0.02674156 0.07077250 0.57461506 0.40616274

$cor
[1] 0.3166681

...または0.2の相関に最も近い値を見つけます。

n_iterations[[which.min(abs(cor_values - 0.2))]]
$vec
  [1] 0.02641979 0.49734797 0.32203732 0.95770015 0.82931652 0.52571331
  [7] 0.25931398 0.30047034 0.55981826 0.08801319 0.29254936 0.23440845
 [13] 0.12056045 0.89799621 0.57461506 0.99006038 0.27077191 0.08626022
 [19] 0.14830718 0.45393971 0.22376395 0.89840404 0.08890968 0.15345334
 [25] 0.87332019 0.92285322 0.50573325 0.40796732 0.91780357 0.57217746
 [31] 0.52590383 0.84003379 0.52031017 0.67532970 0.83244284 0.95114398
 [37] 0.81109473 0.35554970 0.92423638 0.83349287 0.34622648 0.18885955
 [43] 0.61397396 0.89193212 0.74445997 0.46724807 0.72147500 0.33821824
 [49] 0.71740151 0.75948043 0.52140366 0.69356590 0.41357545 0.21050067
 [55] 0.87959539 0.11796154 0.73996913 0.30868672 0.47871491 0.63877904
 [61] 0.22736077 0.40125309 0.02674156 0.26986325 0.43377516 0.07077250
 [67] 0.79072381 0.08939812 0.86719899 0.55623242 0.60854785 0.71627101
 [73] 0.40616274 0.35698405 0.67369873 0.82437619 0.27980561 0.77182339
 [79] 0.19701975 0.82685046 0.74418811 0.58667068 0.93903143 0.74439384
 [85] 0.46456652 0.85240338 0.34303707 0.45862163 0.91790830 0.84776853
 [91] 0.78854984 0.05244047 0.58727094 0.77785348 0.01581969 0.27087693
 [97] 0.07729027 0.71901990 0.25235660 0.11261002

$cor
[1] 0.2000199

より高い相関を得るには、反復回数を増やす必要があります。


2

Y1Y2,,YnR

解決:

  1. CCT=R
  2. 独立したランダムベクトル作成するX2,,XnY1
  3. Y1
  4. Y=CXYiY1

Pythonコード:

import numpy as np
import math
from scipy.linalg import toeplitz, cholesky
from statsmodels.stats.moment_helpers import cov2corr

# create the large correlation matrix R
p = 4
h = 2/p
v = np.linspace(1,-1+h,p)
R = cov2corr(toeplitz(v))

# create the first variable
T = 1000;
y = np.random.randn(T)

# generate p-1 correlated randoms
X = np.random.randn(T,p)
X[:,0] = y
C = cholesky(R)
Y = np.matmul(X,C)

# check that Y didn't change
print(np.max(np.abs(Y[:,0]-y)))

# check the correlation matrix
print(R)
print(np.corrcoef(np.transpose(Y)))

テスト出力:

0.0
[[ 1.   0.5  0.  -0.5]
 [ 0.5  1.   0.5  0. ]
 [ 0.   0.5  1.   0.5]
 [-0.5  0.   0.5  1. ]]
[[ 1.          0.50261766  0.02553882 -0.46259665]
 [ 0.50261766  1.          0.51162821  0.05748082]
 [ 0.02553882  0.51162821  1.          0.51403266]
 [-0.46259665  0.05748082  0.51403266  1.        ]]

Y1

@whuberそれはタイプミスだった
-Aksakal

0

与えられたSAMPLING共分散行列を使用して正規変数を生成します

covsam <- function(nobs,covm, seed=1237) {; 
          library (expm);
          # nons=number of observations, covm = given covariance matrix ; 
          nvar <- ncol(covm); 
          tot <- nvar*nobs;
          dat <- matrix(rnorm(tot), ncol=nvar); 
          covmat <- cov(dat); 
          a2 <- sqrtm(solve(covmat)); 
          m2 <- sqrtm(covm);
          dat2 <- dat %*% a2 %*% m2 ; 
          rc <- cov(dat2);};
          cm <- matrix(c(1,0.5,0.1,0.5,1,0.5,0.1,0.5,1),ncol=3);
          cm; 
          res <- covsam(10,cm)  ;
          res;

指定されたPOPULATION共分散行列を使用して通常の変数を生成します

covpop <- function(nobs,covm, seed=1237) {; 
          library (expm); 
          # nons=number of observations, covm = given covariance matrix;
          nvar <- ncol(covm); 
          tot <- nvar*nobs;  
          dat <- matrix(rnorm(tot), ncol=nvar); 
          m2 <- sqrtm(covm);
          dat2 <- dat %*% m2;  
          rc <- cov(dat2); }; 
          cm <- matrix(c(1,0.5,0.1,0.5,1,0.5,0.1,0.5,1),ncol=3);
          cm; 
          res <- covpop(10,cm); 
          res

2
あなたは答えのコードをフォーマットすることを学ぶ必要があります!テキストをコードフラグメントとしてマークする特定のオプションがあります。
kjetil bハルヴォルセン

-6

ランダムなベクトルを作成し、希望するrになるまで並べ替えます。


これは上記の解決策よりもどのような状況で望ましいでしょうか?
アンディW

ユーザーが簡単な答えを求めている状況。rフォーラムで同様の質問を読み、その答えが与えられました。
アダム

3
r

3
この回答がr-helpフォーラムで提供された場合、(a)皮肉な(つまり、冗談を意図した)か、(b)統計的にあまり洗練されていない人から提供されたと思われます。これをもっと簡潔に言えば、これは質問に対する貧弱な答えで​​す。-1
グン-モニカの復職
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.