Saya sebelumnya menanyakan ini pada StackOverflow, tetapi sepertinya itu mungkin lebih tepat di sini, mengingat bahwa itu tidak mendapatkan jawaban pada SO. Ini semacam persimpangan antara statistik dan pemrograman.
Saya perlu menulis beberapa kode untuk melakukan PCA (Principal Component Analysis). Saya telah melihat-lihat algoritma yang terkenal dan menerapkan yang ini , yang sejauh yang saya tahu sama dengan algoritma NIPALS. Ini bekerja dengan baik untuk menemukan 2-3 komponen utama pertama, tetapi kemudian tampaknya menjadi sangat lambat untuk bertemu (pada urutan ratusan hingga ribuan iterasi). Berikut ini rincian yang saya butuhkan:
Algoritma harus efisien ketika berhadapan dengan sejumlah besar fitur (pesanan 10.000 hingga 20.000) dan ukuran sampel pada urutan beberapa ratus.
Itu harus dapat dilaksanakan secara wajar tanpa perpustakaan aljabar / matriks linier yang layak, karena bahasa targetnya adalah D, yang belum memilikinya, dan bahkan jika itu terjadi, saya lebih suka tidak menambahkannya sebagai ketergantungan pada proyek yang dimaksud. .
Sebagai catatan, pada dataset yang sama R tampaknya menemukan semua komponen utama sangat cepat, tetapi menggunakan dekomposisi nilai singular, yang bukan sesuatu yang saya ingin kode sendiri.
Jawaban:
Saya telah mengimplementasikan SVD Acak seperti yang diberikan dalam "Halko, N., Martinsson, PG, Shkolnisky, Y., & Tygert, M. (2010). Algoritma untuk analisis komponen utama dari kumpulan data besar. Arxiv pracetak arXiv: 1007.5510, 0526. Diperoleh 1 April 2011, dari http://arxiv.org/abs/1007.5510 . " Jika Anda ingin mendapatkan SVD terpotong, itu benar-benar bekerja jauh lebih cepat daripada variasi svd di MATLAB. Anda bisa mendapatkannya di sini:
Untuk mengujinya, cukup buat gambar di folder yang sama (seperti halnya matriks besar, Anda bisa membuat matriks sendiri)
Ketika saya menjalankannya di desktop saya untuk gambar ukuran 635 * 483, saya dapatkan
Seperti yang Anda lihat, untuk nilai rendah
k
, itu lebih dari 10 kali lebih cepat daripada menggunakan Matlab SVD. Omong-omong, Anda mungkin memerlukan fungsi sederhana berikut untuk fungsi tes:Saya tidak menambahkan metode PCA karena mudah untuk menerapkan menggunakan SVD. Anda dapat memeriksa tautan ini untuk melihat hubungannya.
sumber
Anda dapat mencoba menggunakan beberapa opsi.
1- Penalized Matrix penguraian . Anda menerapkan beberapa batasan penalti pada u dan v untuk mendapatkan sparsity. Algoritma cepat yang telah digunakan pada data genomik
Lihat Whitten Tibshirani. Mereka juga memiliki R-pkg. "Dekomposisi matriks yang dihukum, dengan aplikasi untuk jarang komponen utama dan analisis korelasi kanonik."
2- SVD Acak . Karena SVD adalah algoritma utama, cari perkiraan yang sangat cepat mungkin diinginkan, terutama untuk analisis eksplorasi. Menggunakan SVD acak, Anda dapat melakukan PCA pada kumpulan data besar.
Lihat Martinsson, Rokhlin, dan Tygert "Algoritma acak untuk dekomposisi matriks". Tygert memiliki kode untuk implementasi PCA yang sangat cepat.
Di bawah ini adalah implementasi sederhana SVD acak di R.
sumber
Sepertinya Anda ingin menggunakan Algoritma Lanczos . Jika gagal, Anda mungkin ingin berkonsultasi dengan Golub & Van Loan. Saya pernah mengkodekan algoritma SVD (dalam SML, semua bahasa) dari teks mereka, dan itu bekerja dengan cukup baik.
sumber
Saya sarankan mencoba PCA kernel yang memiliki kompleksitas waktu / ruang tergantung pada jumlah contoh (N) daripada jumlah fitur (P), yang saya pikir akan lebih cocok di pengaturan Anda (P >> N)). Kernel PCA pada dasarnya bekerja dengan matriks kernel NxN (matriks kemiripan antara titik-titik data), dan bukan matriks kovarian PxP yang sulit diatasi untuk P. besar. Hal baik lainnya tentang kernel PCA adalah dapat mempelajari proyeksi non-linear. juga jika Anda menggunakannya dengan kernel yang sesuai. Lihat makalah ini pada kernel PCA .
sumber
Saya sepertinya ingat bahwa adalah mungkin untuk melakukan PCA dengan menghitung eigen-dekomposisi X ^ TX daripada XX ^ T dan kemudian berubah untuk mendapatkan PC. Namun saya tidak dapat mengingat detailnya secara langsung, tetapi itu ada di buku Jolliffe (luar biasa) dan saya akan mencarinya ketika saya berikutnya bekerja. Saya akan transliterasi rutin aljabar linier dari misalnya Metode Numerik dalam C, daripada menggunakan algoritma lain.
sumber
Ada juga metode bootstrap oleh Fisher et al , yang dirancang untuk beberapa ratus sampel berdimensi tinggi.
Gagasan utama dari metode ini dirumuskan sebagai "resampling adalah transformasi dimensi rendah". Jadi, jika Anda memiliki sejumlah kecil (beberapa ratus) sampel berdimensi tinggi, maka Anda tidak bisa mendapatkan lebih banyak komponen utama daripada jumlah sampel Anda. Dengan demikian masuk akal untuk mempertimbangkan sampel sebagai dasar pelit, memproyeksikan data pada subruang linier yang direntang oleh vektor-vektor ini, dan menghitung PCA dalam subruang yang lebih kecil ini. Mereka juga memberikan rincian lebih lanjut bagaimana menangani kasing ketika tidak semua sampel dapat disimpan dalam memori.
sumber
Lihat makalah Sam Roweis, Algoritma EM untuk PCA dan SPCA .
sumber