回答:
後方にそれを行うことができます:すべての行列 (すべての対称 PSD行列のセット)は次のように分解できます。 P × P
ここで、は正規直交行列です
取得するには、最初にランダムに生成する(典型的にはランダムなベクターである)。そこから、Gram-Schmidt直交化プロセスを使用してを取得し(V 1、。。。、のV P)V I(- 1 、1 )(U 1、。。。。、U P)= O
は、ランダム基底のGS直交化を効率的に行うことができる多数のパッケージがあります。これは、たとえば「far」パッケージなどの大きな次元でも可能です。WikiでGSアルゴリズムを見つけることができますが、おそらく車輪を再発明してmatlabの実装に進まない方がよいでしょう(確かに存在しますが、お勧めできません)。
最後に、その要素がすべて正である対角行列である(これは簡単に生成するには、再び、次のとおりです。生成、乱数をそれらを二乗、並べ替え、それらをして身元の対角線がたにそれらを置くで行列)。p p p
紙ブドウ拡張タマネギの方法に基づいてランダム相関行列生成 Lewandowskiの、Kurowicka、およびジョー(LKJ)、2009年には、ランダムな相関行列を生成する二効率的な方法の統一治療及び博覧会を提供します。どちらの方法でも、以下で定義する特定の正確な意味で均一な分布からマトリックスを生成でき、実装が簡単で高速で、名前が面白いという追加の利点があります。
対角線にをもつサイズの実対称行列は、一意の非対角要素を持ち、点としてパラメータ化できます。。この空間の各点は対称行列に対応しますが、すべてが正定値であるわけではありません(相関行列がそうであるように)。したがって、相関行列はサブセット(実際には接続された凸サブセット)を形成し、両方の方法はこのサブセット上の均一分布からポイントを生成できます。d (d − 1 )/ 2 R d (d − 1 )/ 2 R d (d − 1 )/ 2
各メソッドの独自のMATLAB実装を提供し、それらを説明します。
タマネギの方法は別の論文(LKJの参照#3)から来ており、マトリックスから始まり、列ごと、行ごとに相関行列が生成されるという事実にその名前を持っています。結果の分布は均一です。私はメソッドの背後にある数学を本当に理解していません(とにかく2番目のメソッドを好みます)が、結果は次のとおりです。
以下および各サブプロットのタイトルは、最小および最大の固有値、および行列式(すべての固有値の積)を示しています。コードは次のとおりです。
%// 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 t
バニラオニオン法と同じ大きさの行列式を取得する何らかの理由で、私はではなくを配置する必要があります(LKJによると)。間違いがどこにあるかわからない。
%// 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は追加のパラメーターを導入して、。結果は、拡張タマネギと同じです。
%// 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つは分布から部分的相関をサンプリングしなければならないの周りに濃縮。以下では、ベータ分布(からに再スケーリング)からそれらをサンプリングします。ベータ分布のパラメータが小さいほど、エッジ近くに集中します。
この場合、分布は順列不変であることが保証されていないことに注意してください。したがって、生成後に行と列をさらにランダムに並べ替えます。
%// 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 W ⊤ D B = W W ⊤ + D C = E - 1 / 2 B E - 1 / 2 E Bの K = 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
さらに簡単な特性評価は、実行列場合、は半正定です。なぜそうなのかを見るためには、すべてのベクトル(もちろん正しいサイズのに対してであることを証明するだけです。これは簡単です:これは非負です。だからMatlabでは、単に試してみてください
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)
kwakの答えのバリエーションとして、選択した分布からランダムな非負の固有値を持つ対角行列を生成してから、相似変換と、Haar分布の擬似ランダム直交行列です。A = Q D Q T Q
行列の分布を指定していません。2つの一般的なものは、ウィシャート分布と逆ウィシャート分布です。バートレット分解は、(効率よくランダム逆ウィシャート行列を得るために解決することができる)ランダムウィシャート行列のコレスキー因数分解を与えます。
実際、コレスキー空間は、対角線が非負であることを確認するだけでよいため、他のタイプのランダムPSD行列を生成する便利な方法です。
生成された対称PSDマトリックスをさらに制御したい場合、たとえば合成検証データセットを生成したい場合、多数のパラメーターを使用できます。対称PSDマトリックスは、関連するすべての自由度を持つN次元空間の超楕円に対応します。
したがって、2次元マトリックス(2次元楕円)の場合、1つの回転+ 2つの軸= 3つのパラメーターがあります。
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
私がテストに使用した安価で陽気なアプローチは、m N(0,1)nベクトルV [k]を生成し、P = d * I + Sum {V [k] * V [k] '}を使用することです。 nxn psdマトリックスとして。m <nの場合、これはd = 0の場合に特異になり、小さいdの場合は条件数が高くなります。