Najpierw udzieliłem odpowiedzi, która moim zdaniem nie jest optymalna; dlatego zredagowałem swoją odpowiedź, aby zacząć od lepszej sugestii.
Metoda winorośli
W tym wątku: Jak efektywnie generować losowe macierze korelacji dodatnich i półkolistych? - Opisałem i podałem kod dwóch wydajnych algorytmów generowania macierzy losowej korelacji. Oba pochodzą z pracy Lewandowskiego, Kurowickiej i Joe (2009).
Proszę zobaczyć moją odpowiedź tam dla wielu cyfr i kodu Matlab. Chciałbym tylko powiedzieć, że metoda winorośli pozwala na generowanie losowych macierzy korelacji z dowolnym rozkładem korelacji cząstkowych (zwróć uwagę na słowo „częściowe”) i może być stosowana do generowania macierzy korelacji o dużych wartościach nie przekątnych. Oto odpowiednia liczba z tego wątku:
Jedyną rzeczą, która zmienia się między podplotami, jest jeden parametr, który kontroluje, w jakim stopniu rozkład korelacji cząstkowych jest skoncentrowany wokół . Ponieważ OP poprosił o mniej więcej rozkład normalny poza przekątną, oto wykres z histogramami elementów poza przekątną (dla tych samych matryc jak powyżej):±1
Myślę, że te rozkłady są w miarę „normalne” i widać, jak stopniowo odchyla się standardowe. Powinienem dodać, że algorytm jest bardzo szybki. Zobacz link do wątku po szczegóły.
Moja oryginalna odpowiedź
Prosta modyfikacja metody może załatwić sprawę (w zależności od tego, jak blisko rozkładu ma być normalny). Ta odpowiedź została zainspirowana powyższymi komentarzami @ kardynała i odpowiedzią @ psarka na moje własne pytanie Jak wygenerować dużą macierz korelacji losowej pełnej rangi z obecnymi silnymi korelacjami?
Sztuczka polega na tym, aby próbki twojego skorelowane (nie funkcje, ale próbki). Oto przykład: generuję macierz losową wielkości (wszystkie elementy ze standardowej normy), a następnie dodam liczbę losową z do każdego wiersza, dla . Dla macierz korelacji (po standaryzacji funkcji) będzie miała elementy o przekątnej mniej więcej normalnie rozmieszczonej ze standardowym odchyleniem . DlaX 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, To obliczanie macierzy korelacji bez centrowania zmiennych (Zachowuje wstawione korelacje), a odchylenie standardowe elementów niediagonalnych rosnąć z jak to pokazano na tym rysunku (rzędy odpowiadają )aa=0,1,2,5
Wszystkie te macierze są oczywiście określone pozytywnie. Oto kod 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
Dane wyjściowe tego kodu (minimalne i maksymalne wartości własne) to:
0.51 ... 1.7
0.44 ... 8.6
0.32 ... 22
0.1 ... 48