J'ai d'abord fourni ce que je crois maintenant être une réponse sous-optimale; j'ai donc modifié ma réponse pour commencer par une meilleure suggestion.
Utilisation de la méthode de la vigne
Dans ce fil: Comment générer efficacement des matrices de corrélation aléatoire semi-définie positive? - J'ai décrit et fourni le code de deux algorithmes efficaces de génération de matrices de corrélation aléatoire. Les deux proviennent d'un article de Lewandowski, Kurowicka et Joe (2009).
S'il vous plaît voir ma réponse là pour beaucoup de chiffres et de code matlab. Ici, je voudrais seulement dire que la méthode de la vigne permet de générer des matrices de corrélation aléatoires avec n'importe quelle distribution de corrélations partielles (notez le mot "partiel") et peut être utilisée pour générer des matrices de corrélation avec de grandes valeurs hors diagonales. Voici la figure pertinente de ce fil:
La seule chose qui change entre les sous-parcelles est un paramètre qui contrôle la concentration de la distribution des corrélations partielles autour de . Comme OP demandait une distribution hors diagonale approximativement normale, voici le tracé avec des histogrammes des éléments hors diagonale (pour les mêmes matrices que ci-dessus):±1
Je pense que ces distributions sont raisonnablement "normales", et on peut voir comment l'écart-type augmente progressivement. Je dois ajouter que l'algorithme est très rapide. Voir le fil lié pour les détails.
Ma réponse originale
Une modification directe de votre méthode pourrait faire l'affaire (selon la proximité que vous souhaitez que la distribution soit normale). Cette réponse a été inspirée par les commentaires de @ cardinal ci-dessus et par la réponse de @ psarka à ma propre question Comment générer une grande matrice de corrélation aléatoire de rang complet avec de fortes corrélations présentes?
L'astuce consiste à faire des échantillons de votre corrélés (pas des fonctionnalités, mais des échantillons). Voici un exemple: je génère une matrice aléatoire de (tous les éléments de la normale standard), puis j'ajoute un nombre aléatoire de à chaque ligne, pour . Pour la matrice de corrélation (après standardisation des entités) aura des éléments hors diagonale répartis normalement normalement avec l'écart type . PourX 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, Je calcule la matrice de corrélation sans centrer les variables (cela préserve les corrélations insérées), et l'écart-type des éléments hors diagonale croît avec comme indiqué sur cette figure (les lignes correspondent à ):aa=0,1,2,5
Toutes ces matrices sont bien sûr définies positives. Voici le code 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
La sortie de ce code (valeurs propres minimum et maximum) est:
0.51 ... 1.7
0.44 ... 8.6
0.32 ... 22
0.1 ... 48