Saya menggunakan dekomposisi Cholesky untuk mensimulasikan variabel acak berkorelasi diberi matriks korelasi. Masalahnya, hasilnya tidak pernah mereproduksi struktur korelasi seperti yang diberikan. Berikut ini adalah contoh kecil dalam Python untuk menggambarkan situasi.
import numpy as np
n_obs = 10000
means = [1, 2, 3]
sds = [1, 2, 3] # standard deviations
# generating random independent variables
observations = np.vstack([np.random.normal(loc=mean, scale=sd, size=n_obs)
for mean, sd in zip(means, sds)]) # observations, a row per variable
cor_matrix = np.array([[1.0, 0.6, 0.9],
[0.6, 1.0, 0.5],
[0.9, 0.5, 1.0]])
L = np.linalg.cholesky(cor_matrix)
print(np.corrcoef(L.dot(observations)))
Ini mencetak:
[[ 1. 0.34450587 0.57515737]
[ 0.34450587 1. 0.1488504 ]
[ 0.57515737 0.1488504 1. ]]
Seperti yang Anda lihat, matriks korelasi taksiran post-hoc berbeda secara drastis dari yang sebelumnya. Apakah ada bug dalam kode saya, atau ada beberapa alternatif untuk menggunakan dekomposisi Cholesky?
Edit
Maafkan saya atas kekacauan ini. Saya tidak berpikir ada kesalahan dalam kode dan / atau cara dekomposisi Cholesky diterapkan karena beberapa kesalahpahaman tentang materi yang saya pelajari sebelumnya. Sebenarnya saya yakin bahwa metode itu sendiri tidak dimaksudkan untuk menjadi tepat dan saya baik-baik saja dengan itu sampai situasi yang membuat saya memposting pertanyaan ini. Terima kasih telah menunjukkan kesalahpahaman yang saya miliki. Saya telah mengedit judul untuk lebih mencerminkan situasi sebenarnya seperti yang diusulkan oleh @Silverfish.
sumber
Jawaban:
Pendekatan berdasarkan dekomposisi Cholesky harus bekerja, dijelaskan di sini dan ditunjukkan dalam jawaban oleh Mark L. Stone yang diposting hampir bersamaan dengan jawaban ini.
Contoh dalam
R
(maaf saya tidak menggunakan perangkat lunak yang sama dengan yang Anda gunakan dalam pertanyaan):Anda mungkin juga tertarik dengan posting ini dan posting ini .
sumber
Orang-orang kemungkinan akan menemukan kesalahan Anda lebih cepat jika Anda menjelaskan apa yang Anda lakukan dengan kata-kata dan aljabar daripada kode (atau setidaknya menulisnya menggunakan pseudocode).
Anda tampaknya melakukan hal yang setara dengan ini (meskipun mungkin diubah):
Yang harus Anda lakukan adalah ini:
Ada banyak penjelasan tentang algoritma ini di situs. misalnya
Bagaimana cara menghasilkan angka acak berkorelasi (diberikan berarti, varians dan tingkat korelasi)?
Bisakah saya menggunakan metode Cholesky untuk menghasilkan variabel acak berkorelasi dengan mean yang diberikan?
Yang ini membahasnya langsung dalam hal matriks kovarians yang diinginkan, dan juga memberikan algoritma untuk mendapatkan sampel kovarians yang diinginkan :
Menghasilkan data dengan matriks kovarians sampel yang diberikan
sumber
Tidak ada yang salah dengan faktorisasi Cholesky. Ada kesalahan dalam kode Anda. Lihat edit di bawah.
Berikut adalah kode dan hasil MATLAB, pertama untuk n_obs = 10.000 seperti yang Anda miliki, kemudian untuk n_obs = 1e8. Untuk kesederhanaan, karena itu tidak mempengaruhi hasil, saya tidak peduli dengan cara, yaitu, saya membuatnya nol. Perhatikan bahwa chol MATLAB menghasilkan faktor Cholesky segitiga atas R dari matriks M sehingga R '* R = M. numpy.linalg.cholesky menghasilkan faktor Cholesky segitiga yang lebih rendah, sehingga diperlukan penyesuaian vs kode saya; tapi saya percaya kode Anda baik-baik saja dalam hal itu.
Sunting: Saya menemukan kesalahan Anda. Anda salah menerapkan standar deviasi. Ini setara dengan apa yang Anda lakukan, yang salah.
sumber
CV bukan tentang kode, tetapi saya tertarik untuk melihat bagaimana ini akan terlihat setelah semua jawaban yang baik, dan khususnya kontribusi @Mark L. Stone. Jawaban aktual untuk pertanyaan diberikan pada posnya (mohon kredit posnya jika ragu). Saya sedang memindahkan info tambahan ini di sini untuk memudahkan pengambilan posting ini di masa mendatang. Tanpa mengecilkan salah satu jawaban luar biasa lainnya, setelah jawaban Markus, ini menyelesaikan masalah dengan memperbaiki pos di OP.
Sumber
DI PYTHON:
DALAM [R]:
sumber
Seperti yang telah ditunjukkan orang lain: karya cholesky. Di sini sepotong kode yang sangat pendek dan sangat dekat dengan pseudocode: sebuah codepiece di MatMate:
sumber