Trước tiên tôi đã cung cấp những gì tôi tin là một câu trả lời tối ưu; do đó tôi chỉnh sửa câu trả lời của mình để bắt đầu với một gợi ý tốt hơn.
Sử dụng phương pháp cây nho
Trong chủ đề này: Làm thế nào để tạo hiệu quả các ma trận tương quan dương-semidefinite ngẫu nhiên? - Tôi đã mô tả và cung cấp mã cho hai thuật toán hiệu quả để tạo ma trận tương quan ngẫu nhiên. Cả hai đều đến từ một bài báo của Lewandowski, Kurowicka và Joe (2009).
Xin vui lòng xem câu trả lời của tôi ở đó cho rất nhiều số liệu và mã MATLAB. Ở đây tôi chỉ muốn nói rằng phương pháp cây nho cho phép tạo ra ma trận tương quan ngẫu nhiên với bất kỳ phân phối tương quan một phần nào (lưu ý từ "một phần") và có thể được sử dụng để tạo ma trận tương quan với các giá trị đường chéo lớn. Đây là con số liên quan từ chủ đề đó:
±1
Tôi nghĩ rằng sự phân phối này là "bình thường" một cách hợp lý, và người ta có thể thấy độ lệch chuẩn tăng dần. Tôi nên thêm rằng thuật toán rất nhanh. Xem chủ đề liên kết để biết chi tiết.
Câu trả lời ban đầu của tôi
Một sửa đổi thẳng về phương pháp của bạn có thể thực hiện thủ thuật (tùy thuộc vào mức độ bạn muốn phân phối trở nên bình thường). Câu trả lời này được lấy cảm hứng từ những bình luận của @ cardinal ở trên và bởi câu trả lời của @ psarka cho câu hỏi của riêng tôi Làm thế nào để tạo ra một ma trận tương quan ngẫu nhiên đầy đủ thứ hạng lớn với một số tương quan mạnh hiện diện?
XX1000×100[−a/2,a/2]a=0,1,2,5a=0X⊤X1/1000−−−−√a>0aa=0,1,2,5
Tất cả các ma trận này tất nhiên là tích cực xác định. Đây là mã 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
Đầu ra của mã này (giá trị riêng tối thiểu và tối đa) là:
0.51 ... 1.7
0.44 ... 8.6
0.32 ... 22
0.1 ... 48