Saya perlu menghitung jarak sampel Mahalanobis dalam R antara setiap pasangan pengamatan dalam matriks kovariat . Saya memerlukan solusi yang efisien, yaitu hanya jarak yang dihitung, dan lebih baik diimplementasikan dalam C / RCpp / Fortran dll. Saya berasumsi bahwa , matriks kovarian populasi, tidak diketahui dan menggunakan sampel matriks kovarians sebagai gantinya.n ( n - 1 ) / 2 Σ
Saya sangat tertarik pada pertanyaan ini karena tampaknya tidak ada metode "konsensus" untuk menghitung jarak Mahalanobis berpasangan dalam R, yaitu tidak diterapkan dalam dist
fungsi maupun dalam cluster::daisy
fungsi. The mahalanobis
fungsi tidak menghitung jarak berpasangan tanpa pekerjaan tambahan dari programmer.
Ini sudah diminta di sini jarak Pairwise Mahalanobis di R , tetapi solusi di sana tampaknya salah.
Berikut adalah metode yang benar tetapi sangat tidak efisien (karena jarak dihitung):
set.seed(0)
x0 <- MASS::mvrnorm(33,1:10,diag(c(seq(1,1/2,l=10)),10))
dM = as.dist(apply(x0, 1, function(i) mahalanobis(x0, i, cov = cov(x0))))
Ini cukup mudah untuk kode diri saya di C, tapi saya merasa seperti sesuatu yang dasar ini harus memiliki solusi yang sudah ada sebelumnya. Apakah ada satu?
Ada solusi lain yang gagal: HDMD::pairwise.mahalanobis()
menghitung jarak, ketika hanya jarak unik yang diperlukan. tampaknya menjanjikan, tetapi saya tidak ingin fungsi saya berasal dari paket yang tergantung , yang sangat membatasi kemampuan orang lain untuk menjalankan kode saya. Kecuali jika implementasi ini sempurna, saya lebih suka menulis sendiri. Adakah yang punya pengalaman dengan fungsi ini?n ( n - 1 ) / 2compositions::MahalanobisDist()
rgl
sumber
Jawaban:
Mulai dari solusi "succint" ahfoss, saya telah menggunakan dekomposisi Cholesky sebagai pengganti SVD.
Itu harus lebih cepat, karena penyelesaian-maju sistem segitiga lebih cepat daripada perkalian matriks padat dengan kovarians terbalik ( lihat di sini ). Berikut adalah tolok ukur dengan solusi ahfoss dan whuber di beberapa pengaturan:
Jadi Cholesky tampaknya lebih cepat seragam.
sumber
Rumus standar untuk jarak Mahalanobis kuadrat antara dua titik data adalah
di mana adalah vektor p × 1 yang sesuai dengan observasi i . Biasanya, matriks kovarians diperkirakan dari data yang diamati. Tidak menghitung inversi matriks, operasi ini membutuhkan p 2 + p perkalian dan p 2 + 2 p penambahan, masing-masing diulang n ( n - 1 ) / 2 kali.xi p×1 i p2+p p2+2p n(n−1)/2
Pertimbangkan derivasi berikut:
di mana . Perhatikan bahwaxTiΣ-1qsaya= Σ- 12xsaya . Ini bergantung pada fakta bahwaΣ-1xTsayaΣ- 12= ( Σ- 12xsaya)T= qTsaya adalah simetris, yang berlaku karena fakta bahwa untuk setiap matriks yang dapat didiagonalisasi simetrisA=PEPT,Σ- 12 A = PEPT
Jika kita membiarkan , dan perhatikan bahwa Σ - 1 simetris, kita melihat bahwa Σ - 1A = Σ- 1 Σ- 1 juga harus simetris. JikaXadalahmatriks pengamatann×pdanQadalahmatriksn×psedemikian rupa sehingga barisithdariQadalahqi, makaQdapat secara ringkas dinyatakan sebagaiXΣ-1Σ−12 X n×p Q n×p ith Q qi Q . Ini dan hasil sebelumnya menyiratkan ituXΣ−12
satu-satunya operasi yang dihitung n ( n - 1 ) / 2 kali adalah p perkalian danpenambahan 2 p (sebagai lawan dari p 2 + p perkalian dan p 2 + 2 p
sumber
pair.diff()
dilakukan dan juga memberikan contoh numerik dengan cetakan dari setiap langkah dari fungsi Anda? Terima kasih.Mari kita coba yang sudah jelas. Dari
berikut ini kita dapat menghitung vektor
dalam waktu dan matriksO(p2)
dalam waktu , kemungkinan besar menggunakan operasi larik cepat (paralel) yang built-in, dan kemudian membentuk solusiO(pn2+p2n)
di mana adalah produk luar sehubungan dengan + : ( a ⊕ b ) i j = a i + b j .⊕ + (a⊕b)ij=ai+bj.
SebuahΣ=Var(X) h
R
implementasi ringkas sejajar dengan formulasi matematis (dan mengasumsikan, dengan itu, bahwa sebenarnya dibalik dengan inverse ditulis h di sini):Perhatikan, untuk kompatibilitas dengan solusi lain, bahwa hanya elemen off-diagonal unik yang dikembalikan, daripada seluruh matriks jarak kuadrat (simetris, nol-di-diagonal). Scatterplots menunjukkan hasilnya setuju dengan yang dari
fastPwMahal
.Dalam C atau C ++, RAM dapat digunakan kembali dan dihitung dengan cepat, menghindarkan kebutuhan untuk penyimpanan menengah u ⊕ u .u⊕u u⊕u
Studi pengaturan waktu dengan mulai dari 33 hingga 5000 dan p mulai dari 10 hingga 100 menunjukkan implementasi ini 1,5 hingga 5 kali lebih cepat daripada dalam kisaran itu. Peningkatan menjadi lebih baik karena p dan n meningkat. Sebagai konsekuensinya, kita dapat mengharapkan menjadi lebih baik untuk p yang lebih kecil . Titik impas terjadi di sekitar p = 7 untuk n ≥ 100n 33 5000 hal 10 100 1.5 5 hal n hal p = 7 n ≥ 100 . Apakah keunggulan komputasi yang sama dari solusi langsung ini berkaitan dengan implementasi lain mungkin merupakan masalah seberapa baik mereka mengambil keuntungan dari operasi array vektor.
fastPwMahal
fastPwMahal
sumber
apply
danouter
... kecuali untuk keluarRcpp
.R
sana sepertinya tidak ada untungnya dengan hal itu.Jika Anda ingin menghitung jarak sampel Mahalanobis, maka ada beberapa trik aljabar yang dapat Anda manfaatkan. Mereka semua mengarah pada penghitungan jarak Euclidean berpasangan, jadi mari kita asumsikan kita dapat menggunakannyaX n×p p HAI(np)
dist()
untuk itu. Biarkan menyatakan n × p matriks data, yang kita asumsikan akan terpusat sehingga bahwa kolom yang memiliki mean 0 dan memiliki peringkat p sehingga matriks kovarians sampel adalah nonsingular. (Pemusatan membutuhkan operasi O ( n p ) .) Kemudian matriks kovarian sampel adalah S = X T X / n .Sampel berpasangan jarak Mahalanobis dari adalah sama dengan jarak Euclidean berpasangan dari X L untuk setiap matriks L yang memenuhi L L T = S - 1 , misalnya akar kuadrat atau faktor Cholesky. Ini mengikuti dari beberapa aljabar linier dan itu mengarah ke suatu algoritma yang membutuhkan perhitungan S , S - 1 , dan dekomposisi Cholesky. Kompleksitas kasus terburuk adalah O ( n p 2 + p 3 ) .X
Lebih dalam, jarak ini berhubungan dengan jarak antara komponen utama sampel . Mari X = U D V T menyatakan SVD dari X . Kemudian S = V D 2 V T / n dan S - 1 / 2 = V D - 1 V T n 1 / 2 . Jadi X S - 1 / 2 = U V T n 1X X= UD VT X
Berikut ini adalah implementasi R dari metode kedua yang tidak dapat saya uji pada iPad yang saya gunakan untuk menulis jawaban ini.
sumber
Ini adalah solusi yang jauh lebih ringkas. Itu masih didasarkan pada derivasi yang melibatkan matriks kovarians akar kuadrat terbalik (lihat jawaban saya yang lain untuk pertanyaan ini), tetapi hanya menggunakan basis R dan paket statistik. Tampaknya sedikit lebih cepat (sekitar 10% lebih cepat di beberapa tolok ukur yang saya jalankan). Perhatikan bahwa ia mengembalikan jarak Mahalanobis, yang bertentangan dengan jarak Maha kuadrat.
Fungsi ini memerlukan matriks kovarians terbalik, dan tidak mengembalikan objek jarak - tetapi saya menduga bahwa versi fungsi ini akan lebih berguna untuk menumpuk pengguna pertukaran.
sumber
SQRT
dengan dekomposisi Choleskychol(invCovMat)
.Jika Anda hanya menggunakan fitur-fitur Fortran77 di antarmuka, subrutin Anda masih cukup portabel untuk orang lain.
sumber
Ada cara yang sangat mudah untuk melakukannya menggunakan Paket R "biotools". Dalam hal ini Anda akan mendapatkan Matriks Mahalanobis Distance Squared.
sumber
Ini adalah kode yang diperluas dengan jawaban lama saya pindah ke sini dari utas lainnya .
Saya telah melakukan perhitungan waktu yang lama dari matriks simetris kuadrat dari jarak Mahalanobis berpasangan di SPSS melalui pendekatan matriks topi menggunakan penyelesaian sistem persamaan linear (untuk itu lebih cepat daripada membalikkan matriks kovarians).
Saya bukan pengguna R jadi saya baru saja mencoba mereproduksi @ahfoss ' resep ini di sini di SPSS bersama dengan resep "saya", pada data 1000 kasus dengan 400 variabel, dan saya menemukan cara saya jauh lebih cepat.
Jadi, kolom tengah dari matriks data, hitung matriks topi, kalikan dengan (n-1), dan lakukan operasi yang berlawanan dengan pemusatan ganda. Anda mendapatkan matriks jarak Mahalanobis kuadrat.
Dalam pengaturan kami, matriks "double-centrate" secara khusus adalah matriks topi (dikalikan dengan n-1), bukan produk skalar euclidean, dan dengan demikian matriks jarak kuadrat yang dihasilkan adalah matriks jarak Mahalanobis kuadrat, bukan matriks jarak euclidean kuadrat.
H= {H,H,...}
Kode dalam SPSS dan probe kecepatan di bawah ini.
Kode pertama ini sesuai dengan fungsi @ahfoss
fastPwMahal
dari jawaban yang dikutip . Ini setara dengan itu secara matematis. Tapi saya menghitung matriks simetris lengkap jarak (melalui operasi matriks) sementara @ahfoss menghitung segitiga matriks simetris (elemen demi elemen).Berikut ini adalah modifikasi saya untuk membuatnya lebih cepat:
solve(X'X,X')
sumber
Rumus yang Anda poskan bukan menghitung apa yang Anda pikir Anda hitung (statistik-U).
Dalam kode yang saya posting, saya menggunakan
cov(x1)
scaling matrix (ini adalah varian dari perbedaan data berpasangan). Anda menggunakancov(x0)
(ini adalah matriks kovarians dari data asli Anda). Saya pikir ini adalah kesalahan Anda. Inti dari menggunakan perbedaan berpasangan adalah bahwa hal itu membebaskan Anda dari asumsi bahwa distribusi multivariat data Anda simetris di sekitar pusat simetri (atau harus memperkirakan pusat simetri dalam hal ini, karenacrossprod(x1)
sebanding dengancov(x1)
). Jelas, dengan menggunakancov(x0)
Anda kehilangan itu.Ini dijelaskan dengan baik dalam makalah yang saya tautkan dalam jawaban asli saya.
sumber
Matteo Fasiolo
dan (saya asumsikan)whuber
di utas ini. Milikmu berbeda. Saya akan tertarik untuk memahami apa yang Anda hitung, tetapi jelas berbeda dari jarak Mahalanobis seperti yang biasanya didefinisikan.cov(x0)