Saya memiliki vektor fitur (~ sejuta). Ada fitur biner (~ sejuta), tetapi dalam setiap vektor hanya (~ seribu) dari mereka akan menjadi , sisanya adalah . Saya mencari pasangan vektor yang memiliki setidaknya (~ seratus) fitur yang sama ( di keduanya). Jumlah pasangan demikian besarnya sama dengan (~ satu juta).M K 1 0 L 1 N
Saya pikir ini bisa didekati sebagai mencari pasangan titik dekat dalam ruang dimensi yang sangat tinggi. Fungsi jarak bisa sedemikian rupa sehingga didasarkan pada berapa banyak fitur yang dimiliki oleh kedua vektor tersebut. Tetapi mungkin akan berguna dengan metrik jarak yang lebih konvensional (seperti Euclidean) juga.
Algoritma terkenal mana yang akan berguna untuk mendekati masalah ini? Apa pun yang kuadratik dalam atau tidak akan praktis.M.
Contoh perumusan masalah dunia nyata adalah untuk mempertimbangkan orang bergerak di antara sejumlah lokasi. Jika dua orang berada di lokasi yang sama pada saat yang sama, kami katakan mereka bertemu satu sama lain. (Jumlah kombinasi waktu-lokasi dengan setidaknya 1 orang hadir adalah ) Kami mencari teman: orang yang bertemu setidaknya kali.M L
sumber
Jawaban:
Sepertinya pendekatan yang Anda cari adalah kombinasi tanda tangan minhash dan Locality Sensitive Hashing (LSH); pdf dari Kumpulan Data Penambangan Masif menjelaskan pendekatan ini (dan langkah-langkah kesamaan lainnya) dalam beberapa detail di Bab 3, tetapi secara singkat:
Sebuah tanda tangan minhash adalah representasi kental matriks asli Anda yang dibangun dengan menerapkan beberapa nomor n fungsi hash untuk fitur, sehingga mengurangi jumlah fitur per observasi. Ini mengurangi ukuran data Anda, namun Anda mungkin akan memperhatikan bahwa ini masih menyisakan masalah .O ( N2)
Untuk mengatasinya, MMDS menyarankan bahwa jika semua yang ingin Anda temukan adalah pasangan di atas ambang batas kemiripan tertentu (yang tampaknya berlaku dalam kasus Anda), maka Anda hanya dapat fokus pada pasangan yang paling mungkin serupa - pendekatan ini disebut Locality Sensitive Hashing , dan di bagian 3.4 mereka membahas contoh cara menggabungkan pendekatan tanda tangan minhash dengan LSH.
Selain teks, ada juga kuliah yang tersedia di kursus Coursera dengan nama yang sama.
sumber
Ini hanya produk dalam dari vektor fitur biner. Ketika produk dalam lebih besar dari , pasangan akan memiliki setidaknya elemen yang sama. Ini harus menjadi perhitungan yang relatif cepat - setidaknya, lebih cepat dari jarak euclidean, yang akan sia-sia dan lambat untuk data ini. Karena Anda menetapkan bahwa Anda sedang mencari pasangan, ini akan inheren berarti Anda harus melakukan perhitungan untuk membandingkan setiap vektor.LL - 1 L. ( N2)
Menemukan poin yang berdekatan memang merupakan masalah pengelompokan. Tetapi langkah pertama dari algoritma pengelompokan yang saya kenal adalah menghitung jarak berpasangan atau kesamaan. Saya yakin seseorang telah mengembangkan alternatif yang lebih efisien. Poin tentang terminologi: memiliki setidaknya tetangga yang sama diucapkan sebagai kesamaan , bukan jarak! Produk dalam, dalam hal ini, adalah persamaan cosinus yang tidak dinormalisasi.L.
Anda dapat membuat ini lebih mudah ditelusuri dengan hanya melakukan perhitungan produk dalam ketika jumlah vektor fitur (yang dalam hal ini sama dengan norma) untuk pengamatan lebih besar daripada , karena tidak mungkin untuk vektor fitur biner itu untuk memiliki produk batin dengan vektor fitur biner lain yang akan memenuhi kriteria saya ketika jumlah ini kurang dari . Jelas, menghitung jumlah ini hanya kompleksitas , jadi saya adalah cara yang murah untuk menurunkan besarnya langkah produk dalam.L O ( N )L - 1 L. O ( N)
Tetapi cara klasik untuk mengurangi ruang lingkup masalah ini adalah dengan melakukan pra-filtering tambahan. Apakah Anda terutama tertarik ketika satu, fitur yang agak tidak biasa mengambil nilai 1? Jika demikian, hanya lakukan penghitungan untuk vektor fitur tersebut.
Atau mungkin Anda bisa mendapat manfaat dari membingkai ulang masalah Anda. Sebagai contoh, pengambilan sampel diketahui memiliki sifat yang bagus; statistik inferensial berkembang pada gagasan ini hingga cukup mendalam. Jadi mungkin tidak mungkin untuk menganalisis seluruh kumpulan data, tetapi sangat layak untuk memeriksa sampel kecil. Saya tidak tahu pertanyaan apa yang Anda coba jawab, tetapi jika Anda dengan hati-hati merancang eksperimen Anda, Anda dapat pergi hanya dengan melihat beberapa ribu pengamatan, dengan lebih dari cukup data yang tersisa untuk keperluan validasi.
Setelah beberapa pemikiran tambahan, saya punya firasat kuat bahwa data Anda bekerja dengan beberapa jenis graf . Sangat masuk akal bahwa terdiri dari beberapa komponen yang terhubung, dalam hal ini Anda dapat menguraikan menjadi satu set grafik, dengan efek samping yang menyenangkan dari mengurangi dimensi data. Bahkan jika grafik hanya dua komponen yang terhubung dengan ukuran yang hampir sama, itu berarti perbandingan berpasangan memiliki kira-kira total biaya!G G O ( N 2 ) 1G G G O ( N2) 14
Jika grafiknya simetris, pengamatan berikut mungkin bermanfaat:
Jika Anda memiliki grafik bipartit yang menghubungkan orang dengan perilaku, Anda dapat menganggap ini sebagai jaringan afiliasi , dengan orang-orang sebagai baris dan perilaku sebagai kolom. Jika Anda ingin menghubungkan orang ke orang lain melalui perilaku mereka memiliki kesamaan, Anda dapat menghitung . adalah jumlah perilaku yang dimiliki orang-orang. Jelas, himpunan simpul di mana menjawab pertanyaan Anda.B B T = A A i j A i j ≥ LB B BT= A SEBUAHsaya j SEBUAHsaya j≥ L
sumber
Saat mencari orang yang bertemu di blok ruang-waktu:Nspace Ntime
O(N2)
pisah ruang menjadi blok (blok kota, km persegi, apa pun), dan waktu menjadi blok . Ada peluang bagus bahwa jika orang bertemu, mereka akan bertemu dalam blok yang sama. Jadi jalankan NN dalam setiap blok. Runtime dan tingkat kesalahan tentu saja akan tergantung pada ukuran dan bentuk blok (juga pada apa yang dapat Anda paralelkan / MapReduce), tetapi Anda memiliki parameter untuk dimainkan - teknik, bukan terbuka lebar .N t i m e O ( N 2 )
Lihat juga:
tetangga-tetangga-cari-data-sangat-tinggi-dimensi pada datacience.stackexchange
pairwise.py :
sumber
Kamus terbalik! titik sebagai , kunci yang terkait dengan nilai-nilai yang tidak nol (yaitu fitur yang dianggap benar). Ukuran rata-rata penyimpanan elemen akan . Memang, saya hanya perlu string untuk menyimpan fitur dan mengapung untuk memegang nilai-nilai.f e a t 1 : v a l u e 1 , f e a t 101 : v a l u e 101 K K Kx feat1:value1,feat101:value101 K K K
Untuk setiap fitur, buat kamus yang berisi indeks yang membagikan fitur ini. Semoga angka ini tidak terlalu besar (jika Anda memiliki fitur yang dibagikan oleh semua indeks, pendekatan ini hancur, Anda dapat berhenti membaca di sini).
Kamus ini terlihat seperti: . Jika saya ingin mendapatkan kecepatan dan menghemat ruang, saya bahkan dapat menjatuhkan fitur yang hanya ditemukan dengan satu elemen (di sini: ) karena mereka tidak akan menghasilkan pasangan yang dekat. Kamus ini dibangun dalam operasi .feat1:{1,101,202},feat2:{7,202},feat3:{202}...featM:{3,45,6} feat3 O(NK)
Sekarang, ketika Anda ingin mengevaluasi jarak elemen ke yang lain, buat (dengan kamus) daftar indeks yang membagikan setidaknya satu fitur dengan . Anda tahu bahwa semua elemen lainnya jauh dari (mereka bahkan tidak berbagi satu fitur!). Jika jumlah rata-rata "elemen per fitur" rendah (sebut saja ), Anda tidak perlu lagi menggunakan .x x P O ( N 2 )x x x P O(N2)
Sekarang ada perbaikan besar lainnya jika dan juga diwakili sebagai kamus, karena atau dapat dievaluasi iterasi dengan kunci dan , dalam operasi .y d ( x , y ) < x , y > x y O ( K )x y d(x,y) <x,y> x y O(K)
Kompleksitas akhir Anda adalah bukan pendekatan awal naif .O ( M N 2 )O(NPK) O(MN2)
Saya menerapkan metode ini untuk menerapkan KNN pada set teks besar (kereta: 2.000 baris, menguji 35.000 baris, jumlah fitur: 10.000, jumlah rata-rata fitur per elemen: 20), yang berjalan sekitar satu jam .. .
sumber
Saya telah menemukan referensi yang mungkin Anda temukan bermanfaat, dan saya percaya itu asimptotik lebih efisien daripada setiap solusi lain yang disajikan sejauh ini. Jika saya mengerti dengan benar, Anda dapat membuat grafik -nearest neighbor (KNN) dalam waktu .O ( L N log ( N ) )k O(LNlog(N))
L. Erotz, M. Steinbach, dan V. Kumar. "Algoritma pengelompokan tetangga terdekat baru yang dibagikan dan aplikasinya." Prosiding Lokakarya Pertama tentang Pengelompokan Data Dimensi Tinggi dan Penerapannya, 2002.
sumber
Mengingat bahwa k Anda adalah 100 dan n Anda adalah 1e6, ini akan memberi Anda ~ 1e4x lebih cepat dibandingkan dengan FFT klasik.
Jika Anda membutuhkan kecepatan 20x lain, dan Anda adalah pengambil risiko, maka alih-alih membelit semua baris terhadap domain dan mencari puncaknya, Anda dapat mem-bootstrap subset baris.
Anda mungkin juga memfilter kolom dengan menghapus kolom yang jumlahnya di bawah 50, atau beberapa ambang batas lainnya yang ada di urutan setengah jumlah baris yang ingin Anda cocokkan. Paling tidak Anda harus menghapus kolom semua nol dan semua 1 sebagai non-informatif. Sama dengan baris yang sepenuhnya kosong atau cukup kosong, atau baris yang penuh sehingga tidak relevan.
Agenda: Saya harus memberi contoh di sini menggunakan data sintetis, dan membandingkan beberapa metode.
sumber
Saya baru saja menemukan kertas yang secara langsung relevan.
Ini sebenarnya diimplementasikan di https://github.com/soundcloud/cosine-lsh-join-spark yang merupakan tempat saya menemukannya.
Ini didasarkan pada hashing sensitif lokalitas (sudah disebutkan dalam jawaban lain). Setelah mengurangi fitur vektor ke ruang dimensi rendah, ia menggunakan gabungan Hamming distance cepat untuk menemukan tetangga terdekat.
sumber