Я спершу представив те, що зараз вважаю, як неоптимальну відповідь; тому я відредагував свою відповідь, щоб почати з кращої пропозиції.
Використовуючи метод виноградної лози
У цій темі: Як ефективно генерувати випадкові матриці кореляції з позитивом-напівдефін? - Я описав і надав код для двох ефективних алгоритмів генерації випадкових кореляційних матриць. І те й інше походять з документа Левандовського, Куровіки та Джо (2009).
Будь ласка, дивіться мою відповідь там, щоб отримати багато цифр та код matlab. Тут я хотів би лише сказати, що метод виноградної лози дозволяє генерувати випадкові матриці кореляції з будь-яким розподілом часткових кореляцій (зверніть увагу на слово "частковий") і може бути використаний для генерації кореляційних матриць з великими позадіагональними значеннями. Ось відповідна цифра з цієї теми:
Єдине, що змінюється між субплотами, - це один параметр, який контролює, наскільки сконцентрований розподіл часткових кореляцій навколо . Оскільки ОП просив приблизно нормального розподілу поза діагоналі, ось графік з гістограмами позадіагональних елементів (для тих же матриць, що і вище):±1
Я думаю, що такі розподіли є досить «нормальними», і видно, як поступово збільшується стандартне відхилення. Додам, що алгоритм дуже швидкий. Детальні відомості див. У пов'язаній нитці.
Моя оригінальна відповідь
Пряма модифікація вашого методу може зробити трюк (залежно від того, наскільки близько ви хочете, щоб розподіл було нормальним). Ця відповідь надихнула коментарів @ кардинала вище та відповіді @ psarka на моє власне запитання Як створити велику повномасштабну матрицю випадкової кореляції з наявними сильними кореляціями?
Хитрість полягає в тому, щоб зробити зразки вашого співвіднесеними (не функції, а зразки). Ось приклад: я генерую випадкову матрицю розміром (всі елементи зі стандартного нормального), а потім додаю випадкове число з до кожного рядка для . Для кореляційна матриця (після стандартизації функцій) матиме недіагональні елементи, приблизно нормально розподілені зі стандартним відхиленням . ДляX 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, Я обчислюю матрицю кореляції без центрування змінних (це зберігає вставлені кореляції), а стандартне відхилення недіагональних елементів зростає з як показано на цій фігурі (рядки відповідають ):aa=0,1,2,5
Усі ці матриці, звичайно, є позитивними. Ось код 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
Вихід цього коду (мінімальні та максимальні власні значення):
0.51 ... 1.7
0.44 ... 8.6
0.32 ... 22
0.1 ... 48