Сначала я предоставил то, что теперь считаю неоптимальным ответом; поэтому я отредактировал свой ответ, чтобы начать с лучшего предложения.
Используя метод лозы
В этой теме: Как эффективно генерировать случайные матрицы положительной-полуопределенной корреляции? - Я описал и предоставил код для двух эффективных алгоритмов генерации матриц случайной корреляции. Оба взяты из статьи Левандовски, Куровицки и Джо (2009).
Пожалуйста, смотрите мой ответ там для большого количества цифр и кода Matlab. Здесь я хотел бы только сказать, что метод виноградной лозы позволяет генерировать матрицы случайной корреляции с любым распределением частичных корреляций (обратите внимание на слово «частичный») и может использоваться для генерации матриц корреляции с большими недиагональными значениями. Вот соответствующая цифра из этой темы:
Единственное, что меняется между участками, - это один параметр, который контролирует, насколько сильно распределение частичных корреляций сосредоточено вокруг . Поскольку OP запрашивал приблизительно нормальное распределение вне диагонали, вот график с гистограммами недиагональных элементов (для тех же матриц, что и выше):± 1
Я думаю, что это распределение достаточно «нормальное», и можно увидеть, как стандартное отклонение постепенно увеличивается. Я должен добавить, что алгоритм очень быстрый. Смотрите связанные темы для деталей.
Мой оригинальный ответ
Прямая модификация вашего метода может помочь (в зависимости от того, насколько близко вы хотите, чтобы распределение было нормальным). Этот ответ был вдохновлен комментариями @ cardinal выше и ответом @ psarka на мой собственный вопрос Как создать большую матрицу случайных корреляций полного ранга с некоторыми сильными корреляциями?
Хитрость заключается в том, чтобы сделать сэмплы вашего коррелированными (не функциями, а сэмплами). Вот пример: я генерирую случайную матрицу размером (все элементы из стандартного нормали), а затем добавляю случайное число из в каждую строку для . Для корреляционная матрица (после стандартизации элементов) будет иметь недиагональные элементы, приблизительно нормально распределенные со стандартным отклонением . ДляX 1000 × 100 [ - a / 2 , a / 2 ] a = 0 , 1 , 2 , 5 a = 0 X ⊤ X 1 / √ИксИкс1000 × 100[ - a / 2 , a / 2 ]а = 0 , 1 , 2 , 5а = 0Икс⊤Икс a>0aa=0,1,2,51 / 1000----√а > 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