Ho prima fornito quella che ora credo sia una risposta non ottimale; quindi ho modificato la mia risposta per iniziare con un suggerimento migliore.
Usando il metodo della vite
In questo thread: come generare in modo efficiente matrici di correlazione semidefinite positive casuali? - Ho descritto e fornito il codice per due algoritmi efficienti di generazione di matrici di correlazione casuali. Entrambi provengono da un articolo di Lewandowski, Kurowicka e Joe (2009).
Si prega di vedere la mia risposta lì per un sacco di cifre e codice matlab. Qui vorrei solo dire che il metodo vine consente di generare matrici di correlazione casuali con qualsiasi distribuzione di correlazioni parziali (si noti la parola "parziale") e può essere utilizzato per generare matrici di correlazione con grandi valori off-diagonali. Ecco la figura rilevante di quel thread:
L'unica cosa che cambia tra le sottotrame, è un parametro che controlla quanto la distribuzione delle correlazioni parziali sia concentrata attorno a . Dato che OP stava chiedendo una distribuzione approssimativamente normale fuori diagonale, ecco la trama con istogrammi degli elementi fuori diagonale (per le stesse matrici di cui sopra):±1
Penso che queste distribuzioni siano ragionevolmente "normali", e si può vedere come aumenta gradualmente la deviazione standard. Dovrei aggiungere che l'algoritmo è molto veloce. Vedi thread collegato per i dettagli.
La mia risposta originale
Una modifica diretta del tuo metodo potrebbe fare il trucco (a seconda di quanto vuoi che la distribuzione sia normale). Questa risposta è stata ispirata dai commenti di @ cardinal sopra e dalla risposta di @ psarka alla mia domanda Come generare una matrice di correlazione casuale a pieno titolo con alcune forti correlazioni presenti?
Il trucco è rendere i campioni del tuo correlati (non caratteristiche, ma campioni). Ecco un esempio: ho generato una matrice casuale di dimensioni (tutti gli elementi dalla norma normale), quindi aggiungo un numero casuale da a ciascuna riga, per . Per la matrice di correlazione (dopo aver standardizzato le caratteristiche) avrà elementi off-diagonali approssimativamente distribuiti normalmente con deviazione standard . PerX 1000 × 100 [ - a / 2 , a / 2 ] a = 0 , 1 , 2 , 5 a = 0 X ⊤ X 1 / √XX1000×100[−a/2,a/2]a=0,1,2,5a=0X⊤X a>0aa=0,1,2,51/1000−−−−√a>0, Computo la matrice di correlazione senza centrare le variabili (ciò preserva le correlazioni inserite) e la deviazione standard degli elementi off-diagonali cresce con come mostrato in questa figura (le righe corrispondono a ):aa=0,1,2,5
Tutte queste matrici sono ovviamente definite positive. Ecco il codice matlab:
offsets = [0 1 2 5];
n = 1000;
p = 100;
rng(42) %// random seed
figure
for offset = 1:length(offsets)
X = randn(n,p);
for i=1:p
X(:,i) = X(:,i) + (rand-0.5) * offsets(offset);
end
C = 1/(n-1)*transpose(X)*X; %// covariance matrix (non-centred!)
%// convert to correlation
d = diag(C);
C = diag(1./sqrt(d))*C*diag(1./sqrt(d));
%// displaying C
subplot(length(offsets),3,(offset-1)*3+1)
imagesc(C, [-1 1])
%// histogram of the off-diagonal elements
subplot(length(offsets),3,(offset-1)*3+2)
offd = C(logical(ones(size(C))-eye(size(C))));
hist(offd)
xlim([-1 1])
%// QQ-plot to check the normality
subplot(length(offsets),3,(offset-1)*3+3)
qqplot(offd)
%// eigenvalues
eigv = eig(C);
display([num2str(min(eigv),2) ' ... ' num2str(max(eigv),2)])
end
L'output di questo codice (autovalori minimo e massimo) è:
0.51 ... 1.7
0.44 ... 8.6
0.32 ... 22
0.1 ... 48