I. Metrik Jarak
Pertama, jumlah fitur (kolom) dalam kumpulan data bukan merupakan faktor dalam memilih metrik jarak untuk digunakan di kNN. Ada beberapa studi yang diterbitkan yang ditujukan untuk pertanyaan ini, dan dasar yang biasa untuk perbandingan adalah:
distribusi statistik yang mendasari data Anda;
hubungan di antara fitur-fitur yang terdiri dari data Anda (apakah mereka independen - yaitu, seperti apa bentuk matriks kovarians); dan
ruang koordinat tempat data Anda diperoleh.
Jika Anda tidak memiliki pengetahuan sebelumnya tentang distribusi dari mana data Anda diambil sampelnya, setidaknya satu (didokumentasikan dengan baik dan menyeluruh) penelitian menyimpulkan bahwa jarak Euclidean adalah pilihan terbaik.
Metrik YEuclidean digunakan dalam Mesin Rekomendasi Web skala besar dan juga dalam penelitian akademik saat ini. Jarak yang dihitung oleh Euclidean memiliki makna intuitif dan skala perhitungan - yaitu, jarak Euclidean dihitung dengan cara yang sama, apakah dua titik berada dalam dua dimensi atau dalam ruang dua puluh dua dimensi.
Itu hanya gagal untuk saya beberapa kali, masing-masing kasus jarak Euclidean gagal karena sistem koordinat yang mendasari (cartesian) adalah pilihan yang buruk. Dan Anda biasanya akan mengenali ini karena misalnya panjang jalur (jarak) tidak lagi aditif - misalnya, ketika ruang metrik adalah papan catur, jarak Manhattan lebih baik daripada Euclidean, demikian juga ketika ruang metrik adalah Bumi dan jarak Anda trans penerbangan internasional, metrik jarak yang cocok untuk sistem koordinat kutub adalah ide yang baik (misalnya, London ke Wina adalah 2,5 jam, Wina ke St. Petersburg adalah 3 jam lagi, kurang lebih dalam arah yang sama, namun London ke St Petersburg bukan 5,5 jam, lebih dari 3 jam.)
Tetapi terlepas dari kasus-kasus di mana data Anda termasuk dalam sistem koordinat non-kartesius, pilihan metrik jarak biasanya tidak material. (Lihat posting blog ini dari seorang siswa CS, membandingkan beberapa metrik jarak dengan memeriksa efeknya pada pengklasifikasi kNN - chi square memberikan hasil terbaik, tetapi perbedaannya tidak besar; Studi yang lebih komprehensif ada di makalah akademis, Studi Banding Fungsi Jarak untuk Tetangga Terdekat - Mahalanobis (pada dasarnya Euclidean dinormalisasi dengan memperhitungkan kovarian dimensi) adalah yang terbaik dalam penelitian ini.
Satu syarat penting: agar perhitungan metrik jarak menjadi bermakna, Anda harus kembali skaladata Anda - jarang mungkin untuk membangun model kNN untuk menghasilkan prediksi yang akurat tanpa melakukan ini. Misalnya, jika Anda sedang membangun model kNN untuk memprediksi kinerja atletik, dan variabel harapan Anda adalah tinggi (cm), berat (kg), lemak tubuh (%), dan denyut nadi istirahat (denyut per menit), maka titik data tipikal mungkin Terlihat seperti ini: [180.4, 66.1, 11.3, 71]. Jelas perhitungan jarak akan didominasi oleh ketinggian, sedangkan kontribusi oleh bodyfat% akan hampir diabaikan. Dengan kata lain, jika sebaliknya, data dilaporkan secara berbeda, sehingga berat badan dalam gram daripada kilogram, maka nilai asli 86,1, akan menjadi 86.100, yang akan memiliki efek besar pada hasil Anda, yang persis seperti apa yang Anda lakukan. mau.
X_new = (X_old - mu) / sigma
II Struktur Data
Jika Anda khawatir tentang kinerja struktur kd-tree, A Voronoi Tessellation adalah wadah yang secara konsep sederhana namun secara drastis akan meningkatkan kinerja dan skala yang lebih baik daripada kd-Trees.
Ini bukan cara yang paling umum untuk mempertahankan data pelatihan kNN, meskipun penerapan VT untuk tujuan ini, serta keuntungan kinerja konsekuensinya, didokumentasikan dengan baik (lihat misalnya laporan Penelitian Microsoft ini ). Signifikansi praktis dari hal ini adalah bahwa, asalkan Anda menggunakan bahasa 'arus utama' (misalnya, dalam Indeks TIOBE ) maka Anda harus menemukan perpustakaan untuk melakukan VT. Saya tahu dengan Python dan R, ada beberapa opsi untuk setiap bahasa (misalnya, paket voronoi untuk R tersedia di CRAN )
Menggunakan VT untuk kNN bekerja seperti ini ::
Dari data Anda, pilih poin w secara acak - ini adalah pusat Voronoi Anda. Sel Voronoi merangkum semua titik tetangga yang terdekat dengan setiap pusat. Bayangkan jika Anda menetapkan warna yang berbeda untuk masing-masing pusat Voronoi, sehingga setiap titik yang ditugaskan ke pusat yang diberikan dicat warna itu. Selama Anda memiliki kepadatan yang cukup, melakukan ini akan dengan baik menunjukkan batas-batas masing-masing pusat Voronoi (sebagai batas yang memisahkan dua warna.
Bagaimana cara memilih Voronoi Center? Saya menggunakan dua pedoman ortogonal. Setelah memilih titik w secara acak, hitung VT untuk data pelatihan Anda. Selanjutnya periksa jumlah titik data yang ditetapkan untuk masing-masing pusat Voronoi - nilai-nilai ini harus hampir sama (diberikan kerapatan titik seragam di seluruh ruang data Anda). Dalam dua dimensi, ini akan menyebabkan VT dengan ubin dengan ukuran yang sama. Itulah aturan pertama, inilah yang kedua. Pilih w dengan iterasi - jalankan algoritma kNN Anda dengan w sebagai parameter variabel, dan ukur kinerja (waktu yang diperlukan untuk mengembalikan prediksi dengan menanyakan VT).
Jadi bayangkan Anda memiliki satu juta titik data ..... Jika titik-titik itu bertahan dalam struktur data 2D biasa, atau dalam kd-tree, Anda akan melakukan rata-rata beberapa juta perhitungan jarak untuk setiaptitik data baru yang variabel responsnya ingin Anda prediksi. Tentu saja, perhitungan tersebut dilakukan pada satu set data tunggal. Dengan V / T, pencarian tetangga terdekat dilakukan dalam dua langkah satu demi satu, terhadap dua populasi data yang berbeda - pertama melawan pusat Voronoi, kemudian setelah pusat terdekat ditemukan, titik-titik di dalam sel sesuai dengan pusat tersebut dicari untuk menemukan tetangga terdekat yang sebenarnya (dengan perhitungan jarak berurutan) Dikombinasikan, kedua pencarian ini jauh lebih cepat daripada pencarian dengan kekuatan kasar tunggal. Itu mudah dilihat: untuk 1M titik data, misalkan Anda memilih 250 pusat Voronoi untuk memeriksa ruang data Anda. Rata-rata, setiap sel Voronoi akan memiliki 4.000 poin data. Jadi alih-alih melakukan perhitungan rata-rata 500.000 jarak (brute force), Anda melakukan jauh lebih sedikit, rata-rata hanya 125 + 2.000.
AKU AKU AKU. Menghitung Hasil (variabel respons yang diprediksi)
Ada dua langkah untuk menghitung nilai prediksi dari serangkaian data pelatihan kNN. Yang pertama adalah mengidentifikasi n, atau jumlah tetangga terdekat yang digunakan untuk perhitungan ini. Yang kedua adalah bagaimana bobot kontribusi mereka terhadap nilai prediksi.
W / r / t komponen pertama, Anda dapat menentukan nilai terbaik dari n dengan menyelesaikan masalah optimasi (sangat mirip dengan optimasi kuadrat terkecil). Itulah teorinya; dalam praktiknya, kebanyakan orang hanya menggunakan n = 3. Bagaimanapun, sangat mudah untuk menjalankan algoritma kNN Anda di atas serangkaian contoh uji (untuk menghitung nilai prediksi) untuk n = 1, n = 2, n = 3, dll. Dan plot kesalahan sebagai fungsi dari n. Jika Anda hanya ingin nilai yang masuk akal untuk memulai, sekali lagi, gunakan saja n = 3.
Komponen kedua adalah bagaimana menghitung kontribusi masing-masing tetangga (dengan asumsi n> 1).
Teknik pembobotan yang paling sederhana adalah hanya mengalikan setiap tetangga dengan koefisien pembobotan, yang hanya 1 / (dist * K), atau kebalikan dari jarak dari tetangga itu ke contoh uji yang sering dikalikan dengan beberapa konstanta yang diturunkan secara empiris, K. I Saya bukan penggemar teknik ini karena sering kali lebih berat dari tetangga terdekat (dan secara bersamaan kurang berat yang lebih jauh); signifikansi ini adalah bahwa prediksi yang diberikan dapat hampir seluruhnya bergantung pada satu tetangga, yang pada gilirannya meningkatkan sensitivitas algoritma terhadap noise.
Fungsi pembobotan yang lebih baik, yang secara substansial menghindari batasan ini adalah fungsi gaussian , yang dalam python, terlihat seperti ini:
def weight_gauss(dist, sig=2.0) :
return math.e**(-dist**2/(2*sig**2))
Untuk menghitung nilai prediksi menggunakan kode kNN Anda, Anda akan mengidentifikasi n tetangga terdekat ke titik data yang variabel responsnya ingin Anda prediksi ('test instance'), lalu panggil fungsi weight_gauss, satu kali untuk masing-masing n tetangga, lewat dalam jarak antara masing-masing tetangga titik uji. Fungsi ini akan mengembalikan berat untuk masing-masing tetangga, yang kemudian digunakan sebagai koefisien tetangga dalam perhitungan rata-rata tertimbang.