9

これは楽しいものです:ピアソンの積率相関係数 (ピアソン r )の特定の値で相関するランダムな x/y ペアを生成する必要があります。これは、配列 X と配列 Y の 2 つの配列として想像できます。ここで、配列 X と配列 Y の値は、ピアソン r の特定のレベルで相互に相関するまで、再生成、再順序付け、または変換する必要があります。キッカーは次のとおりです。配列 X と配列 Y は一様分布でなければなりません。

正規分布でこれを行うことができますが、分布を歪めずに値を変換すると困惑します。配列内の値を並べ替えて相関を高めようとしましたが、並べ替えだけでは配列が 1.00 または -1.00 に相関することはありません。

何か案は?

--

これは、車輪を回転させるためのランダム相関ガウスの AS3 コードです。

public static function nextCorrelatedGaussians(r:Number):Array{             
         var d1:Number;
         var d2:Number;
         var n1:Number;
         var n2:Number;
         var lambda:Number;
         var r:Number;
         var arr:Array = new Array();
         var isNeg:Boolean; 

        if (r<0){
            r *= -1;
              isNeg=true;
        }            
        lambda= (   (r*r)  -  Math.sqrt(  (r*r) - (r*r*r*r)  )     )   /   ((  2*r*r ) - 1  );

        n1 = nextGaussian();
        n2 = nextGaussian();           
        d1 = n1;            
        d2 = ((lambda*n1) + ((1-lambda)*n2)) / Math.sqrt( (lambda*lambda) + (1-lambda)*(1-lambda));

        if (isNeg) {d2*= -1}           
        arr.push(d1);
        arr.push(d2);
        return arr;
    }
4

6 に答える 6

6

私はこれについて短い論文を書くことになった

ソート方法は含まれていませんが(実際には、最初の方法と遠回しに似ていると思います)、反復を必要としない2つの方法について説明しています。

于 2009-11-22T22:33:23.637 に答える
1

この一見単純な質問が、昨日の夕方から頭を悩ませていました。依存関係のある分布をシミュレートするトピックを探しましたが、見つけた最高のものは、依存する確率変数をシミュレートすることです。その要点は、与えられた相関を持つ2つの法線を簡単にシミュレートでき、これらの非独立法線を変換する方法の概要を示していますが、これは相関を維持しません。変換の相関は、いわば相関しますが、同一ではありません。「順位相関係数」の段落を参照してください。

編集: 記事の第 2 部から収集したものから、コピュラ メソッドを使用すると、ランク相関を使用して確率変数をシミュレート/生成できます。

于 2009-11-12T18:15:53.327 に答える
1

以下は、Actionscript 3 で記述された twolfe18 のアルゴリズムの実装です。

for (var j:int=0; j < size; j++) {
 xValues[i]=Math.random());
}
var varX:Number = Util.variance(xValues);
var varianceE:Number = 1/(r*varX) - varX;

for (var i:int=0; i < size; i++) {
 yValues[i] = xValues[i] + boxMuller(0, Math.sqrt(varianceE));
}

boxMuller引数(平均、stdDev)を使用してランダムなガウス分布を生成する単なるメソッドです。 size分布のサイズです。

サンプル出力

Target p: 0.8
Generated p: 0.04846346291280387
variance of x distribution: 0.0707786253165176
varianceE: 17.589920412141158

ご覧のとおり、私はまだ途中です。助言がありますか?

于 2009-11-12T05:51:42.367 に答える
1

1 の相関を取得するには、X と Y の両方が同じである必要があるため、X を Y にコピーすると、1 の相関が得られます。-1 の相関を取得するには、Y = 1 - X とします。(X の値が [0, 1]))

于 2009-11-17T20:12:08.807 に答える
1

がエラー (通常の確率変数)y = x + eであるモデルから始めます。平均が 0 で分散が k である必要があります。ee

簡単に言うと、ピアソンの期待値の式を k で書き、k について解くことができます。ピアソンが特定の値と正確に等しいデータをランダムに生成することはできず、特定の値の期待されるピアソンのみを使用してデータを生成できないことに注意してください。

紙にアクセスできるようになったら、この投稿を編集してクローズド フォーム ソリューションを含めるようにします。

編集:わかりました、私はおそらく正しい手波の解決策を持っています(ただし、確認するにはテストが必要です)。今のところ、望ましいと仮定しますPearson = p > 0(ケースは理解できますp < 0)。先に述べたように、モデルをY = X + E( Xis uniform, Eis normal ) に設定します。

  1. あなたのxを取得するためのサンプル
  2. var(x) を計算する
  3. E の分散は次のようになります。(1/(rsd(x)))^2 - var(x)
  4. xに基づいてyを生成し、通常のランダム変数からサンプルを生成しますE

p < 0、セットY = -X + E。それに応じて進みます。

基本的に、これは Pearson の定義に従います: cov(x,y)/var(x)*var(y)。x の ( Y = X + E) にノイズを追加すると、予想される共分散 cov(x,y) はノイズのない場合と変わらないはずです。var(x) は変化しません。var(y) は var(x) と var(e) の合計であるため、私の解決策です。

2番目の編集:わかりました、定義をよりよく読む必要があります。ピアソンの定義は cov(x, y)/(sd(x) sd(y)) です。それから、var(E) の真の値は (1/(r sd(x)))^2 - var(x) であるべきだと思います。それが機能するかどうかを確認してください。

于 2009-11-11T21:19:53.790 に答える
1

奇妙な問題には奇妙な解決策が必要です。これが私が解決した方法です。

-配列 X を生成する

-配列 X を複製して配列 Y を作成する

- 配列 X の並べ替え (配列 X の並べ替えには、任意の方法を使用できます。クイックソート、ヒープソートなど、安定したものなら何でも使用できます。)

- ソートされた配列 X とソートされていない配列 Y を使用して、ピアソンの R の開始レベルを測定します。

WHILE the correlation is outside of the range you are hoping for

   IF the correlation is to low
         run one iteration of CombSort11 on array Y then recheck correlation
   ELSE IF the correlation is too high
         randomly swap two values and recheck correlation

以上です!Combsort が真の鍵であり、ゆっくりと着実に相関を高める効果があります。Jason Harrison のデモをチェックして、私の言いたいことを確認してください。負の相関関係を取得するには、プロセス全体が完了した後で並べ替えを反転するか、配列の 1 つを反転します。

AS3での私の実装は次のとおりです。

public static function nextReliableCorrelatedUniforms(r:Number, size:int, error:Number):Array {
        var yValues:Array = new Array;
        var xValues:Array = new Array;
        var coVar:Number = 0;
        for (var e:int=0; e < size; e++) { //create x values            
            xValues.push(Math.random());
    }
    yValues = xValues.concat();
    if(r != 1.0){
        xValues.sort(Array.NUMERIC);
    }
    var trueR:Number = Util.getPearson(xValues, yValues);

        while(Math.abs(trueR-r)>error){
            if (trueR < r-error){   // combsort11 for y     
                var gap:int = yValues.length;
                var swapped:Boolean = true; 
                while (trueR <= r-error) {
                    if (gap > 1) {
                        gap = Math.round(gap / 1.3);
                    }
                    var i:int = 0;
                    swapped = false;
                    while (i + gap < yValues.length  &&  trueR <= r-error) {
                        if (yValues[i] > yValues[i + gap]) {
                            var t:Number = yValues[i];
                            yValues[i] = yValues[i + gap];
                            yValues[i + gap] = t;
                            trueR = Util.getPearson(xValues, yValues)
                            swapped = true;
                        }
                        i++;
                    }
                }
            }

            else { // decorrelate
                while (trueR >= r+error) {
                    var a:int = Random.randomUniformIntegerBetween(0, size-1);
                    var b:int = Random.randomUniformIntegerBetween(0, size-1);
                    var temp:Number = yValues[a];
                    yValues[a] = yValues[b];
                    yValues[b] = temp;
                    trueR = Util.getPearson(xValues, yValues)
               }                
            }
        }
        var correlates:Array = new Array;
        for (var h:int=0; h < size; h++) {
            var pair:Array = new Array(xValues[h], yValues[h]);
            correlates.push(pair);}
        return correlates;
    }
于 2009-11-19T20:35:33.960 に答える