ランダムな正半相関行列を効率的に生成する方法は?


38

正半値(PSD)相関行列を効率的に生成できるようにしたいと思います。生成する行列のサイズを大きくすると、私の方法は劇的に遅くなります。

  1. 効率的なソリューションを提案できますか?Matlabの例を知っているなら、私はとてもありがたいです。
  2. PSD相関行列を生成するとき、生成される行列を記述するパラメータをどのように選択しますか?平均相関、相関の標準偏差、固有値?

回答:


16

後方にそれを行うことができます:すべての行列 (すべての対称 PSD行列のセット)は次のように分解できます。 P × PCR++pp×p

C=OTDOここで、は正規直交行列ですO

取得するには、最初にランダムに生成する(典型的にはランダムなベクターである)。そこから、Gram-Schmidt直交化プロセスを使用してを取得しV 1のV PV I- 1 1 U 1U P= OO(v1,...,vp)vi(1,1)(u1,....,up)=O

Rは、ランダム基底のGS直交化を効率的に行うことができる多数のパッケージがあります。これは、たとえば「far」パッケージなどの大きな次元でも可能です。WikiでGSアルゴリズムを見つけることができますが、おそらく車輪を再発明してmatlabの実装に進まない方がよいでしょう(確かに存在しますが、お勧めできません)。

最後に、その要素がすべて正である対角行列である(これは簡単に生成するには、再び、次のとおりです。生成、乱数をそれらを二乗、並べ替え、それらをして身元の対角線がたにそれらを置くで行列)。p p pDppp


3
(1)結果のは、対角に1 を持たないため、相関行列(OPの要求どおり)にならないことに注意してください。もちろん、設定することで、対角に1を持つように再スケーリングできます。ここで、はと同じ対角を持つ対角行列です。(2)私が間違っていない場合、これはすべての非対角要素が近くに集中する相関行列になるため、OPが探していた柔軟性はありません(OPは「平均相関、相関の標準偏差、固有値」E - 1 / 2 C E - 1 / 2 E C 0CE1/2CE1/2EC0
amoebaによると、Reinstate Monica 14年

@amoeba:あなたが指摘しているように、(1)の解決は簡単なので、(2)を取り上げます。PSDマトリックス(および共分散および相関マトリックス)の「形状」(対角要素の内外の関係)の1つの数値特性は、その条件番号です。また、上記の方法により、それを完全に制御できます。「0を中心とする非対角要素の濃度」は、PSDマトリックスの生成に使用される方法の特徴ではなく、マトリックスがPSDであり、が大きいことを保証するために必要な制約の結果です。p
user603 14年

すべての大きなPSD行列の非対角要素がゼロに近いと言っていますか?私は同意しません、そうではありません。いくつかの例については、私の答えを確認してください:与えられた標準偏差でほぼ正規分布の非対角成分を持つランダム相関行列を生成する方法は?しかし、対角線上にすべて1を持ち、対角線上にないすべての場所で固定値を持つ正方行列はPSDであり、は任意に大きくなる可能性があるため(もちろん未満)、そうではないことが直接わかります。ρ 1ρρ1
アメーバは、モニカを復活

@amoeba:それから、正と負の両方が許可される場合、必然的に大きな相関行列のオフダイアゴナルが0に近いと仮定するのは間違っていました。啓発的な例に感謝します。
user603 14年

1
ランダム相関行列の生成に関する非常に素晴らしい論文を読んで、ここに自分自身の回答(およびそのリンクされたスレッドの別の回答)を提供しました。面白いと思うかもしれません。
アメーバは、モニカを復活

27

ブドウ拡張タマネギの方法に基づいてランダム相関行列生成 Lewandowskiの、Kurowicka、およびジョー(LKJ)、2009年には、ランダムな相関行列を生成する二効率的な方法の統一治療及び博覧会を提供します。どちらの方法でも、以下で定義する特定の正確な意味で均一な分布からマトリックスを生成でき、実装が簡単で高速で、名前が面白いという追加の利点があります。

対角線にをもつサイズの実対称行列は、一意の非対角要素を持ち、点としてパラメータ化できます。。この空間の各点は対称行列に対応しますが、すべてが正定値であるわけではありません(相関行列がそうであるように)。したがって、相関行列はサブセット(実際には接続された凸サブセット)を形成し、両方の方法はこのサブセット上の均一分布からポイントを生成できます。d d 1 / 2 R d d 1 / 2 R d d 1 / 2d×dd(d1)/2Rd(d1)/2Rd(d1)/2

各メソッドの独自のMATLAB実装を提供し、それらを説明します。d=100


タマネギ法

タマネギの方法は別の論文(LKJの参照#3)から来ており、マトリックスから始まり、列ごと、行ごとに相関行列が生成されるという事実にその名前を持っています。結果の分布は均一です。私はメソッドの背後にある数学を本当に理解していません(とにかく2番目のメソッドを好みます)が、結果は次のとおりです。1×1

タマネギ法

以下および各サブプロットのタイトルは、最小および最大の固有値、および行列式(すべての固有値の積)を示しています。コードは次のとおりです。

%// ONION METHOD to generate random correlation matrices distributed randomly
function S = onion(d)
    S = 1;
    for k = 2:d
        y = betarnd((k-1)/2, (d-k)/2); %// sampling from beta distribution
        r = sqrt(y);
        theta = randn(k-1,1);
        theta = theta/norm(theta);
        w = r*theta;
        [U,E] = eig(S);
        R = U*E.^(1/2)*U';             %// R is a square root of S
        q = R*w;
        S = [S q; q' 1];               %// increasing the matrix size
    end
end

拡張タマネギ法

比例する分布から相関行列をサンプリングできるようにするために、LKJはこのメソッドをわずかに変更します。大きいほど、行列式が大きくなります。つまり、生成された相関行列はますます恒等行列に近づきます。値は均一分布に対応します。以下の図では、マトリックスはます。 [ d e tC[detC]η1ηη=1η=1,10,100,1000,10000,100000

拡張タマネギ法

バニラオニオン法と同じ大きさの行列式を取得する何らかの理由で、私はではなくを配置する必要があります(LKJによると)。間違いがどこにあるかわからない。η=0η=1

%// EXTENDED ONION METHOD to generate random correlation matrices
%// distributed ~ det(S)^eta [or maybe det(S)^(eta-1), not sure]
function S = extendedOnion(d, eta)
    beta = eta + (d-2)/2;
    u = betarnd(beta, beta);
    r12 = 2*u - 1;
    S = [1 r12; r12 1];  

    for k = 3:d
        beta = beta - 1/2;
        y = betarnd((k-1)/2, beta);
        r = sqrt(y);
        theta = randn(k-1,1);
        theta = theta/norm(theta);
        w = r*theta;
        [U,E] = eig(S);
        R = U*E.^(1/2)*U';
        q = R*w;
        S = [S q; q' 1];
    end
end

つるの方法

つるの方法はもともとジョー(LKJのJ)によって提案され、LKJによって改善されました。概念的に簡単であり、変更も簡単だからです。アイデアは、偏相関(独立しており、制約なしで任意の値を持つことができます)を生成し、再帰式を介して生の相関に変換することです。計算を特定の順序で整理すると便利です。このグラフは「つる」として知られています。重要なのは、部分相関が特定のベータ分布(マトリックス内の異なるセルで異なる)からサンプリングされる場合、結果のマトリックスは均一に分布することです。ここでも、LKJは追加のパラメーターを導入して、d(d1)/2[1,1]η[detC]η1。結果は、拡張タマネギと同じです。

つるの方法

%// VINE METHOD to generate random correlation matrices
%// distributed ~ det(S)^eta [or maybe det(S)^(eta-1), not sure]
function S = vine(d, eta)
    beta = eta + (d-1)/2;   
    P = zeros(d);           %// storing partial correlations
    S = eye(d);

    for k = 1:d-1
        beta = beta - 1/2;
        for i = k+1:d
            P(k,i) = betarnd(beta,beta); %// sampling from beta
            P(k,i) = (P(k,i)-0.5)*2;     %// linearly shifting to [-1, 1]
            p = P(k,i);
            for l = (k-1):-1:1 %// converting partial correlation to raw correlation
                p = p * sqrt((1-P(l,i)^2)*(1-P(l,k)^2)) + P(l,i)*P(l,k);
            end
            S(k,i) = p;
            S(i,k) = p;
        end
    end
end

部分相関の手動サンプリングによるつる方法

上記からわかるように、均一な分布により、ほぼ対角の相関行列が得られます。しかし、一つは、簡単に(これはLKJ紙に説明するが、簡単ですされていない)に強い相関を持つようにつる方法を変更することができます。この1つは分布から部分的相関をサンプリングしなければならないの周りに濃縮。以下では、ベータ分布(からに再スケーリング)からそれらをサンプリングします。ベータ分布のパラメータが小さいほど、エッジ近くに集中します。±1[0,1][1,1]α=β=50,20,10,5,2,1

手動サンプリングによるつる法

この場合、分布は順列不変であることが保証されていないことに注意してください。したがって、生成後に行と列をさらにランダムに並べ替えます。

%// VINE METHOD to generate random correlation matrices
%// with all partial correlations distributed ~ beta(betaparam,betaparam)
%// rescaled to [-1, 1]
function S = vineBeta(d, betaparam)
    P = zeros(d);           %// storing partial correlations
    S = eye(d);

    for k = 1:d-1
        for i = k+1:d
            P(k,i) = betarnd(betaparam,betaparam); %// sampling from beta
            P(k,i) = (P(k,i)-0.5)*2;     %// linearly shifting to [-1, 1]
            p = P(k,i);
            for l = (k-1):-1:1 %// converting partial correlation to raw correlation
                p = p * sqrt((1-P(l,i)^2)*(1-P(l,k)^2)) + P(l,i)*P(l,k);
            end
            S(k,i) = p;
            S(i,k) = p;
        end
    end

    %// permuting the variables to make the distribution permutation-invariant
    permutation = randperm(d);
    S = S(permutation, permutation);
end

以下は、非対角要素のヒストグラムが上記のマトリックスをどのように探すかです(分布の分散は単調に増加します):

非対角要素


更新:ランダム係数の使用

@shabbychefの回答では、いくつかの強い相関を持つランダム相関行列を生成する非常に簡単な方法の1つを使用しましたが、ここでも説明します。アイデアは、いくつかの()因子負荷(サイズのランダム行列)をランダムに生成し、共分散行列(もちろんフルランクではない)を作成することです)、それに正の要素を持つランダム対角行列を追加して、フルランクにします。結果の共分散行列は、にすることにより、正規化して相関行列にすることができますW K × D W WD B = W W + D C = E - 1 / 2 B E - 1 / 2 E Bの K = 100 50 20 10 5 1k<dWk×dWWDB=WW+DC=E1/2BE1/2ここで、はと同じ対角をもつ対角行列です。これは非常に簡単で、トリックを行います。以下は、相関行列の例です。EBk=100,50,20,10,5,1

ランダム因子からのランダム相関行列

そしてコード:

%// FACTOR method
function S = factor(d,k)
    W = randn(d,k);
    S = W*W' + diag(rand(1,d));
    S = diag(1./sqrt(diag(S))) * S * diag(1./sqrt(diag(S)));
end

以下は、図の生成に使用されるラッピングコードです。

d = 100; %// size of the correlation matrix

figure('Position', [100 100 1100 600])
for repetition = 1:6
    S = onion(d);

    %// etas = [1 10 100 1000 1e+4 1e+5];
    %// S = extendedOnion(d, etas(repetition));

    %// S = vine(d, etas(repetition));

    %// betaparams = [50 20 10 5 2 1];
    %// S = vineBeta(d, betaparams(repetition));

    subplot(2,3,repetition)

    %// use this to plot colormaps of S
    imagesc(S, [-1 1])
    axis square
    title(['Eigs: ' num2str(min(eig(S)),2) '...' num2str(max(eig(S)),2) ', det=' num2str(det(S),2)])

    %// use this to plot histograms of the off-diagonal elements
    %// offd = S(logical(ones(size(S))-eye(size(S))));
    %// hist(offd)
    %// xlim([-1 1])
end

2
これは素晴らしいランダウンです。何か言ったことがうれしいです!
シャドウトーカー14年

つるベースの相関行列のmatlabコードをRに変換してテストすると、列1の相関密度は後の列とは常に異なりました。間違って翻訳したのかもしれませんが、おそらくこのメモは誰かの助けになるでしょう。
チャーリー

3
Rユーザーの場合、パッケージclusterGenerationの関数rcorrmatrix(W QuiおよびH. Joeによって作成)は、vineメソッドを実装します。
RNM

15

さらに簡単な特性評価は、実行列場合、は半正定です。なぜそうなのかを見るためには、すべてのベクトル(もちろん正しいサイズのに対してであることを証明するだけです。これは簡単です:これは非負です。だからMatlabでは、単に試してみてくださいAATAyT(ATA)y0yyT(ATA)y=(Ay)TAy=||Ay||

A = randn(m,n);   %here n is the desired size of the final matrix, and m > n
X = A' * A;

アプリケーションによっては、これで目的の固有値の分布が得られない場合があります。その点で、Kwakの答えははるかに優れています。Xこのコードスニペットによって生成される固有値は、マルチェンコパステル分布に従う必要があります。

たとえば、株式の相関行列をシミュレートするには、少し異なるアプローチが必要になる場合があります。

k = 7;      % # of latent dimensions;
n = 100;    % # of stocks;
A = 0.01 * randn(k,n);  % 'hedgeable risk'
D = diag(0.001 * randn(n,1));   % 'idiosyncratic risk'
X = A'*A + D;
ascii_hist(eig(X));    % this is my own function, you do a hist(eig(X));
-Inf <= x <  -0.001 : **************** (17)
-0.001 <= x <   0.001 : ************************************************** (53)
 0.001 <= x <   0.002 : ******************** (21)
 0.002 <= x <   0.004 : ** (2)
 0.004 <= x <   0.005 :  (0)
 0.005 <= x <   0.007 : * (1)
 0.007 <= x <   0.008 : * (1)
 0.008 <= x <   0.009 : *** (3)
 0.009 <= x <   0.011 : * (1)
 0.011 <= x <     Inf : * (1)

1
偶然ascii_hist関数を共有したいと思いますか?
btown

@btownマージンは小さすぎて収まらない!
みすぼらしいシェフ

1
はタイプミスがあります -最終的な正方形がありません!yT(ATA)y=(Ay)TAy=||Ay||
シルバーフィッシュ14

8

kwakの答えのバリエーションとして、選択した分布からランダムな非負の固有値を持つ対角行列を生成してから、相似変換と、Haar分布の擬似ランダム直交行列です。A = Q D Q T QDA=QDQTQ


M.:素敵なリファレンス:これは(漸近的に)最も効率的なソリューションのようです。
whuber

3
@whuber:へー、ゴラブとヴァンローン(もちろん)から拾いました。これを常に使用して、固有値/特異値ルーチンのストレステスト用のテストマトリックスを生成します。論文からわかるように、それはkwakが提案したようなランダム行列をQR分解することと本質的に同等ですが、より効率的に行われます。HighamのText Matrix Toolbox、BTWには、これのMATLAB実装があります。
JMは統計家ではありません

M。:> matlabの実装に感謝します。RのHaar擬似ランダムマトリックスジェネレーターを知っていますか?
user603

@kwak:わからないが、まだ実装がない場合、MATLABコードをRに変換するのはそれほど難しくないはずです(実際にコードがない場合は、1つ上げることができます)。唯一の前提条件は、疑似ランダム正規変量の適切なジェネレーターです。
JMは統計家ではありません

M。:>はい、多分それを自分で翻訳します。リンク、ありがとう。
user603

4

行列の分布を指定していません。2つの一般的なものは、ウィシャート分布と逆ウィシャート分布です。バートレット分解は、(効率よくランダム逆ウィシャート行列を得るために解決することができる)ランダムウィシャート行列のコレスキー因数分解を与えます。

実際、コレスキー空間は、対角線が非負であることを確認するだけでよいため、他のタイプのランダムPSD行列を生成する便利な方法です。


>ランダムではない:同じホイシャードから生成された2つのマトリックスは、互いに独立していません。世代ごとにウィシャートを変更する予定がある場合、そもそもそれらをどのように生成するつもりですか?
user603

@kwak:あなたの質問はわかりません。バートレット分解は、同じウィシャート分布から独立したドローを与えます。
サイモンバーン

>言い替えさせてください、どこからウィシャート分布のスケールマトリックスを取得しますか?
user603

1
@kwak:分布のパラメーターであるため、修正されました。分布の目的の特性(平均など)に基づいて、開始時に選択します。
サイモンバーン

3

UTSU


エントリが均一ではなく正規分布から生成される場合、言及する分解はSO(n)不変である必要があります(したがって、Haarメジャーに関連して均等に分散されます)。
whuber

面白い。これに関するリファレンスを提供できますか?
ギャップのある

1
>この方法の問題は、最小固有値と最大固有値の比を制御できないことです(ランダムに生成されたデータセットのサイズが無限大になると、この比は1に収束すると思います)。
-user603

1

生成された対称PSDマトリックスをさらに制御したい場合、たとえば合成検証データセットを生成したい場合、多数のパラメーターを使用できます。対称PSDマトリックスは、関連するすべての自由度を持つN次元空間の超楕円に対応します。

  1. 回転。
  2. 軸の長さ。

したがって、2次元マトリックス(2次元楕円)の場合、1つの回転+ 2つの軸= 3つのパラメーターがあります。

Σ=ODOTΣOD

Σ

figure;
mu = [0,0];
for i=1:16
    subplot(4,4,i)
    theta = (i/16)*2*pi;   % theta = rand*2*pi;
    U=[cos(theta), -sin(theta); sin(theta) cos(theta)];
    % The diagonal's elements control the lengths of the axes
    D = [10, 0; 0, 1]; % D = diag(rand(2,1));    
    sigma = U*D*U';
    data = mvnrnd(mu,sigma,1000);
    plot(data(:,1),data(:,2),'+'); axis([-6 6 -6 6]); hold on;
end

U


0

私がテストに使用した安価で陽気なアプローチは、m N(0,1)nベクトルV [k]を生成し、P = d * I + Sum {V [k] * V [k] '}を使用することです。 nxn psdマトリックスとして。m <nの場合、これはd = 0の場合に特異になり、小さいdの場合は条件数が高くなります。


2
>この方法の問題は、最小固有値と最大固有値の比を制御できないことです(ランダムに生成されたデータセットのサイズが無限大になると、この比は1に収束すると思います)。
-user603

>さらに、この方法はあまり効率的ではありません(計算の観点から)
user603

1
「ランダムマトリックス」は、「対角プラス1ランクマトリックス」(DR1マトリックス)と呼ばれる特別に構造化されたものなので、実際には適切なランダムマトリックスではありません。
JMは
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.