Ein Artikel zur Generierung zufälliger Korrelationsmatrizen auf der Basis von Reben und einer Methode mit erweiterten Zwiebeln von Lewandowski, Kurowicka und Joe (LKJ), 2009, bietet eine einheitliche Behandlung und Darstellung der beiden effizienten Methoden zur Generierung zufälliger Korrelationsmatrizen. Beide Methoden ermöglichen die Erzeugung von Matrizen aus einer gleichmäßigen Verteilung in einem bestimmten, nachstehend definierten Sinne, sind einfach zu implementieren, schnell und haben den zusätzlichen Vorteil, dass sie amüsante Namen haben.
Eine reelle symmetrische Matrix mit der Größe mit Einsen auf der Diagonale hat eindeutige Elemente außerhalb der Diagonale und kann daher als Punkt in parametrisiert werden. . Jeder Punkt in diesem Raum entspricht einer symmetrischen Matrix, aber nicht alle von ihnen sind positiv-definit (wie Korrelationsmatrizen sein müssen). Korrelationsmatrizen bilden daher eine Teilmenge von (eigentlich eine zusammenhängende konvexe Teilmenge), und beide Methoden können Punkte aus einer gleichmäßigen Verteilung über diese Teilmenge erzeugen.d ( d - 1 ) / 2 R d ( d - 1 ) / 2 R d ( d - 1 ) / 2d×dd(d−1)/2Rd(d−1)/2Rd(d−1)/2
Ich werde meine eigene MATLAB-Implementierung jeder Methode bereitstellen und sie mit veranschaulichen .d=100
Zwiebelmethode
Die Zwiebelmethode stammt aus einer anderen Veröffentlichung (Lit. 3 in LKJ) und hat ihren Namen der Tatsache zu verdanken, dass die Korrelationsmatrizen beginnend mit Matrix und spaltenweise und zeilenweise wachsen. Die resultierende Verteilung ist gleichmäßig. Ich verstehe die Mathematik hinter der Methode nicht wirklich (und bevorzuge sowieso die zweite Methode), aber hier ist das Ergebnis:1×1
Hier und unter dem Titel jedes Unterplots werden der kleinste und der größte Eigenwert sowie die Determinante (Produkt aller Eigenwerte) angezeigt. Hier ist der Code:
%// 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
Erweiterte Zwiebelmethode
LKJ modifizieren diese Methode geringfügig, um Korrelationsmatrizen aus einer Verteilung abtasten zu können, die proportional zu [ d e t istC[detC]η−1ηη=1η=1,10,100,1000,10000,100000
η=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
Rebe-Methode
d(d−1)/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
Weinbaumethode mit manueller Probenahme von Teilkorrelationen
±1[0,1][−1,1]α=β=50,20,10,5,2,1. Je kleiner die Parameter der Beta-Verteilung sind, desto stärker ist sie in Randnähe konzentriert.
Beachten Sie, dass in diesem Fall die Verteilung nicht garantiert permutationsinvariant ist, sodass ich Zeilen und Spalten nach der Generierung zusätzlich zufällig permutiere.
%// 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
So sehen die Histogramme der nicht diagonalen Elemente für die obigen Matrizen aus (Varianz der Verteilung steigt monoton an):
Update: unter Verwendung von Zufallsfaktoren
k<dWk×dWW⊤DB=WW⊤+DC=E−1/2BE−1/2EBk=100,50,20,10,5,1
Und der Code:
%// 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
Hier ist der Umhüllungscode, der zum Generieren der Zahlen verwendet wird:
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