Saya pertama kali memberikan apa yang sekarang saya yakini sebagai jawaban yang kurang optimal; karena itu saya mengedit jawaban saya untuk memulai dengan saran yang lebih baik.
Menggunakan metode pokok anggur
Di utas ini: Bagaimana cara efisien menghasilkan matriks korelasi positif-semidefinit acak? - Saya menjelaskan dan menyediakan kode untuk dua algoritma yang efisien untuk menghasilkan matriks korelasi acak. Keduanya berasal dari sebuah makalah oleh Lewandowski, Kurowicka, dan Joe (2009).
Silakan lihat jawaban saya di sana untuk banyak angka dan kode matlab. Di sini saya hanya ingin mengatakan bahwa metode anggur memungkinkan untuk menghasilkan matriks korelasi acak dengan distribusi korelasi parsial (perhatikan kata "parsial") dan dapat digunakan untuk menghasilkan matriks korelasi dengan nilai off-diagonal yang besar. Berikut adalah angka yang relevan dari utas itu:
±1
Saya pikir distribusi ini cukup "normal", dan orang dapat melihat bagaimana standar deviasi meningkat secara bertahap. Saya harus menambahkan bahwa algoritma ini sangat cepat. Lihat utas terkait untuk detailnya.
Jawaban asli saya
Modifikasi langsung metode Anda dapat melakukan trik (tergantung pada seberapa dekat Anda ingin distribusi menjadi normal). Jawaban ini terinspirasi oleh komentar @ cardinal di atas dan oleh jawaban @ psarka untuk pertanyaan saya sendiri. Bagaimana cara menghasilkan matriks korelasi acak peringkat penuh yang besar dengan beberapa korelasi kuat yang ada?
XX1000×100[−a/2,a/2]a=0,1,2,5a=0X⊤X1/1000−−−−√a>0aa=0,1,2,5
Semua matriks ini tentu saja pasti positif. Berikut ini adalah kode 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
Output dari kode ini (nilai eigen minimum dan maksimum) adalah:
0.51 ... 1.7
0.44 ... 8.6
0.32 ... 22
0.1 ... 48