Menghasilkan angka acak yang terdistribusi normal dengan matriks kovarians non-positif-pasti

15

Saya memperkirakan sampel matriks kovarian C sampel dan mendapatkan matriks simetris. Dengan C , saya ingin membuat n -variate rn didistribusikan normal, tetapi karena itu saya membutuhkan Cholesky dekomposisi . Apa yang harus saya lakukan jika tidak pasti positif?CC

Klaus
sumber
1
Apa perbedaan dengan pertanyaan ini stackoverflow.com/questions/17295627/… ?
dickoa
1
Matriks positive-semidefinite memiliki banyak akar kuadrat (lihat penjelasan di akhir stats.stackexchange.com/a/71303/919 , misalnya). Anda tidak perlu yang diproduksi oleh dekomposisi Cholesky. Di sinilah inti masalahnya: temukan metode untuk menghitung akar kuadrat yang bekerja bahkan ketika matriksnya tunggal. @amoeba Judulnya menunjukkan interpretasi Anda benar.
Whuber

Jawaban:

8

Kekhawatiran pertanyaan bagaimana untuk menghasilkan variates acak dari distribusi normal multivariat dengan (mungkin) singular kovarians matriks C . Jawaban ini menjelaskan satu cara yang akan bekerja untuk matriks kovarian apa pun . Ini menyediakan Rimplementasi yang menguji akurasinya.


Analisis aljabar dari matriks kovarians

Karena C adalah matriks kovarians, ia harus simetris dan positif-semidefinit. Untuk melengkapi informasi latar belakang, biarkan μ menjadi vektor dari cara yang diinginkan.

Karena simetris, Dekomposisi Nilai Singular (SVD) dan dekomposisi eigendnya akan secara otomatis berbentukC

C=VD2V

untuk beberapa ortogonal matriks dan matriks diagonal D 2 . Secara umum elemen diagonal D 2 adalah nonnegatif (menyiratkan mereka semua memiliki akar kuadrat nyata: pilih yang positif untuk membentuk matriks diagonal D ). Informasi yang kami miliki tentang C mengatakan bahwa satu atau lebih elemen diagonal tersebut adalah nol - tetapi itu tidak akan memengaruhi operasi selanjutnya, juga tidak akan mencegah SVD untuk dikomputasi.VD2D2DC

Menghasilkan nilai acak multivarian

Misalkan memiliki standar distribusi normal multivariat: masing-masing komponen memiliki mean nol, Unit varians, dan semua covariances adalah nol: matriks kovarians adalah identitas saya . Kemudian variabel acak Y = V D XXIY=VDX memiliki matriks kovarians

Cov(Y)=E(YY)=E(VDXXDV)=VDE(XX)DV=VDIDV=VD2V=C.

Akibatnya variabel acak memiliki distribusi normal multivariat dengan mean μ dan matriks kovarian Cμ+YμC .

Kode Komputasi dan Contoh

RKode berikut menghasilkan matriks kovarians dari dimensi dan peringkat yang diberikan, menganalisisnya dengan SVD (atau, dalam kode komentar, dengan komposisi eigend), menggunakan analisis tersebut untuk menghasilkan sejumlah realisasi ditentukan (dengan vektor rata-rata 0 ) , dan kemudian membandingkan matriks kovarians dari data tersebut dengan matriks kovarians yang dituju baik secara numerik dan grafik. Seperti ditunjukkan, itu menghasilkan 10 , 000 realisasi mana dimensi Y adalah 100 dan pangkat C adalah 50Y010,000Y100C50 . Outputnya adalah

        rank           L2 
5.000000e+01 8.846689e-05 

Artinya, peringkat data juga dan matriks kovarians seperti yang diperkirakan dari data berada dalam jarak 8 × 10 - 5 dari C - yang dekat. Sebagai pemeriksaan yang lebih terperinci, koefisien C diplot terhadap perkiraannya. Mereka semua berada dekat dengan garis kesetaraan:508×105CC

Figure

Kode tersebut persis paralel dengan analisis sebelumnya dan karenanya harus jelas (bahkan untuk non- Rpengguna, yang mungkin meniru di lingkungan aplikasi favorit mereka). Satu hal yang diungkapkan adalah perlunya kehati-hatian ketika menggunakan algoritma floating-point: entri dapat dengan mudah menjadi negatif (tapi kecil) karena ketidaktepatan. Entri seperti itu perlu di-nolkan sebelum menghitung akar kuadrat untuk menemukan D itu sendiri.D2D

n <- 100         # Dimension
rank <- 50
n.values <- 1e4  # Number of random vectors to generate
set.seed(17)
#
# Create an indefinite covariance matrix.
#
r <- min(rank, n)+1
X <- matrix(rnorm(r*n), r)
C <- cov(X)
#
# Analyze C preparatory to generating random values.
# `zapsmall` removes zeros that, due to floating point imprecision, might
# have been rendered as tiny negative values.
#
s <- svd(C)
V <- s$v
D <- sqrt(zapsmall(diag(s$d)))
# s <- eigen(C)
# V <- s$vectors
# D <- sqrt(zapsmall(diag(s$values)))
#
# Generate random values.
#
X <- (V %*% D) %*% matrix(rnorm(n*n.values), n)
#
# Verify their covariance has the desired rank and is close to `C`.
#
s <- svd(Sigma <- cov(t(X)))
(c(rank=sum(zapsmall(s$d) > 0), L2=sqrt(mean(Sigma - C)^2)))

plot(as.vector(C), as.vector(Sigma), col="#00000040",
     xlab="Intended Covariances",
     ylab="Estimated Covariances")
abline(c(0,1), col="Gray")
whuber
sumber
2
+1 tetapi ketika Anda mengatakan "tidak terbatas" dalam kalimat pertama Anda, apa sebenarnya yang Anda maksud? Saya memeriksa di Wikipedia dan mengatakan bahwa semidefinite positif bukan tidak pasti, artinya tidak terbatas berarti C memiliki nilai eigen positif dan negatif. Apakah itu yang Anda maksud di sana?
Amuba kata Reinstate Monica
2
@amoeba Ya, itu tergelincir. Terima kasih telah memperhatikan. "Tidak terbatas" berarti tanda tangan dari matriks memiliki tanda-tanda positif dan negatif, sedangkan "semidefinite" berarti tanda tangan hanya memiliki satu tanda.
whuber
6

Metode Solusi A :

  1. 0.5(C+CT)
  2. D+(mmin(eigenvalue(D)))I , di mana saya adalah matriks identitas. D berisi matriks kovarians positif pasti yang diinginkan.

Dalam MATLAB, kodenya adalah

D = 0.5 * (C + C');
D =  D + (m - min(eig(CD)) * eye(size(D));

Metode Solusi B : Merumuskan dan menyelesaikan Convex SDP (Program Semidefinite) untuk menemukan matriks D ke C terdekat sesuai dengan norma frobenius perbedaan mereka, sehingga D adalah pasti positif, memiliki nilai eigen minimum yang ditentukan m.

Menggunakan CVX di bawah MATLAB, kodenya adalah:

n = size(C,1);
cvx_begin
variable D(n,n)
minimize(norm(D-C,'fro'))
D -m *eye(n) == semidefinite(n)
cvx_end

Perbandingan Metode Solusi : Selain melakukan simetriisasi matriks awal, metode solusi A hanya menyesuaikan (meningkatkan) elemen diagonal dengan jumlah yang sama, dan membiarkan elemen off-diagonal tidak berubah. Metode solusi B menemukan matriks definit positif terdekat (ke matriks asli) yang memiliki nilai eigen minimum yang ditentukan, dalam arti norma frobenius minimum dari perbedaan matriks pasti positif D dan matriks C asli, yang didasarkan pada jumlah dari perbedaan kuadrat semua elemen D - C, untuk memasukkan elemen off-diagonal. Jadi dengan menyesuaikan elemen off-diagonal, itu dapat mengurangi jumlah dimana elemen diagonal perlu ditingkatkan, dan elemen diagoanl tidak harus semuanya meningkat dengan jumlah yang sama.

Mark L. Stone
sumber
2

Saya akan mulai dengan memikirkan model yang Anda perkirakan.

Jika matriks kovarians tidak semi-pasti positif, itu mungkin menunjukkan bahwa Anda memiliki masalah colinearity dalam variabel Anda yang akan menunjukkan masalah dengan model dan tidak harus diselesaikan dengan metode numerik.

Jika matriks semidefinite tidak positif karena alasan numerik, maka ada beberapa solusi yang dapat dibaca di sini

johnerik
sumber
1
Asumsinya adalah bahwa model tersebut adalah model campuran linier. Dan untuk kasus ini tidak relevan untuk menemukan model yang tepat untuk data, melainkan data diberikan sebagai contoh untuk beberapa perhitungan. Sekarang ada kemungkinan bahwa Anda mendapatkan matriks semidefinite non-positif sebagai estimasi untuk kovaraince. Jadi apa yang harus dilakukan dari sana, jika saya ingin mengetahui kovarians dari populasi terdistribusi normal dari mana data berasal. Bahwa sampel terdistribusi normal adalah asumsi.
Klaus
1

Salah satu caranya adalah dengan menghitung matriks dari dekomposisi nilai eigen. Sekarang saya akui bahwa saya tidak tahu banyak tentang Matematika di balik proses-proses ini, tetapi dari penelitian saya tampaknya bermanfaat untuk melihat file bantuan ini:

http://stat.ethz.ch/R-manual/R-patched/library/Matrix/html/chol.html

dan beberapa perintah terkait lainnya di R.

Juga, periksa 'nearPD' dalam paket Matrix.

Maaf saya tidak bisa membantu tetapi saya berharap pencarian saya di sekitar dapat membantu mendorong Anda ke arah yang benar.

Frank P.
sumber
Hai, terima kasih untuk tautannya. Berkaitan dengan dekomposisi nilai eigen, dekomposisi ini tidak membantu, karena dari sana Anda mendapatkan nilai eigen kompleks untuk matriks akar kuadrat, tapi saya perlu matriks bernilai kembali.
Klaus
1

Anda bisa mendapatkan hasil dari fungsi nearPD dalam paket Matrix di R. Ini akan memberi Anda matriks bernilai kembali nyata.

library(Matrix)
A <- matrix(1, 3,3); A[1,3] <- A[3,1] <- 0
n.A <- nearPD(A, corr=T, do2eigen=FALSE)
n.A$mat

# 3 x 3 Matrix of class "dpoMatrix"
#           [,1]      [,2]      [,3]
# [1,] 1.0000000 0.7606899 0.1572981
# [2,] 0.7606899 1.0000000 0.7606899
# [3,] 0.1572981 0.7606899 1.0000000
Mike
sumber
Untuk pengguna R .. ini mungkin bukan versi "orang miskin" yang buruk (dengan sedikit kontrol) dari Metode Metode B dalam jawaban saya.
Mark L. Stone
Saya setuju ini tidak optimal tetapi terkadang berhasil.
Dr. Mike