I. Mesafe Metriği
İlk olarak, bir veri kümesindeki özelliklerin (sütunlar) sayısı, kNN'de kullanılacak bir mesafe metriği seçiminde bir faktör değildir. Tam olarak bu soruya yönelik yayınlanmış az sayıda çalışma vardır ve karşılaştırma için olağan temeller şunlardır:
verilerinizin altında yatan istatistiksel dağılım;
verilerinizi oluşturan özellikler arasındaki ilişki (bağımsız mı - yani kovaryans matrisi neye benziyor); ve
verilerinizin alındığı koordinat alanı.
Verilerinizin örneklendiği dağıtım (lar) hakkında önceden bilginiz yoksa, en az bir (iyi belgelenmiş ve kapsamlı) çalışma Öklid mesafesinin en iyi seçim olduğu sonucuna varır.
Mega ölçekli Web Öneri Motorlarında ve güncel akademik araştırmalarda kullanılan YEuclidric metriği. Öklid tarafından hesaplanan mesafeler sezgisel bir anlama sahiptir ve hesaplama ölçekleri - yani Öklid mesafesi, iki nokta iki boyutta ya da yirmi iki boyut uzayında olsun aynı şekilde hesaplanır.
Benim için sadece birkaç kez başarısız oldu, bu vakaların her biri Öklid mesafesi başarısız oldu, çünkü alttaki (kartezyen) koordinat sistemi kötü bir seçimdi. Ve genellikle bunu fark edersiniz, çünkü örneğin yol uzunlukları (mesafeler) artık ilave değildir - örneğin, metrik alan bir satranç tahtası olduğunda, Manhattan mesafesi Öklidenden daha iyidir, aynı şekilde metrik alan Dünya ve mesafeleriniz trans olduğunda - kıta uçuşları, kutupsal koordinat sistemine uygun bir mesafe ölçüsü iyi bir fikirdir (örneğin, Londra'dan Viyana'ya 2.5 saat, Viyana'dan St.Petersburg'a 3 saat, aşağı yukarı aynı yönde, Londra'dan St. Petersburg 5.5 saat değil, 3 saatin biraz üzerindedir.)
Ancak, verilerinizin kartezyen olmayan bir koordinat sistemine ait olduğu durumlar dışında, mesafe metriği seçimi genellikle önemli değildir. ( Bir CS öğrencisinden bu blog yayınına bakın , kNN sınıflandırıcı - chi square üzerindeki etkilerini inceleyerek birkaç mesafe metriğini karşılaştırarak en iyi sonuçları verin, ancak farklılıklar büyük değildir; Daha kapsamlı bir çalışma akademik makalede, Karşılaştırmalı Çalışma En Yakın Komşuların Uzaklık İşlevleri Mahalanobis (esas olarak, boyut kovaryansını hesaba katarak normalleştirilmiş Öklid) bu çalışmada en iyisiydi.
Önemli bir şart: mesafe metrik hesaplamalarının anlamlı olması için, yeniden ölçeklendirmenizverileriniz - bunu yapmadan doğru tahminler oluşturmak için nadiren bir kNN modeli oluşturmak mümkündür. Örneğin, atletik performansı tahmin etmek için bir kNN modeli oluşturuyorsanız ve beklenti değişkenleriniz yükseklik (cm), ağırlık (kg), vücut yağ (%) ve dinlenme nabzı (dakikadaki atım) ise, tipik bir veri noktası olabilir şuna benzer: [180.4, 66.1, 11.3, 71]. Açıkça, mesafe hesaplamasına yükseklik hakim olacak,% vücut yağının katkısı neredeyse önemsiz olacaktır. Başka bir deyişle, bunun yerine, veriler farklı raporlandıysa, böylece vücut ağırlığı kilogram yerine gram cinsindeydi, o zaman 86.1, orijinal değeri 86.100 olur ve sonuçlarınız üzerinde büyük bir etkisi olur, istemiyorum.
X_new = (X_old - mu) / sigma
II. Veri Yapısı
Kd ağacı yapısının performansı hakkında endişeleriniz varsa, bir Voronoi Mozaikleme kavramsal olarak basit bir kaptır, ancak bu performansı ve ölçekleri kd-Ağaçlarından daha iyi bir şekilde artıracaktır.
Bu, kNN eğitim verilerini sürdürmenin en yaygın yolu değildir, ancak VT'nin bu amaç için uygulanması ve bunun sonucu olarak ortaya çıkan performans avantajları iyi belgelenmiştir (bkz. Örneğin bu Microsoft Araştırma raporu ). Bunun pratik önemi, 'ana akım' bir dil kullanmanız koşuluyla (örneğin, TIOBE Endeksinde ) VT yapmak için bir kütüphane bulmanız gerektiğidir. Python ve R biliyorum örneğin her dil için birden fazla seçenek (vardır voronoi üzerinde R paketi mevcut CRAN )
KNN için VT kullanmak şu şekilde çalışır ::
Verilerinizden rastgele w noktaları seçin - bunlar Voronoi merkezlerinizdir. Bir Voronoi hücresi, her merkeze en yakın olan tüm komşu noktaları kapsar. Voronoi merkezlerinin her birine farklı bir renk atarsanız, belirli bir merkeze atanan her noktanın o renge boyanmasını hayal edin. Yeterli bir yoğunluğa sahip olduğunuz sürece, bunu yapmak her Voronoi merkezinin sınırlarını güzel bir şekilde gösterecektir (iki rengi ayıran sınır olarak).
Voronoi Merkezleri nasıl seçilir? İki dik yönerge kullanıyorum. W noktalarını rastgele seçtikten sonra egzersiz verileriniz için VT'yi hesaplayın. Daha sonra her bir Voronoi merkezine atanan veri noktalarının sayısını kontrol edin - bu değerler yaklaşık aynı olmalıdır (veri alanınız boyunca tekdüze nokta yoğunluğu verilmiştir). İki boyutta, bu aynı boyutta karolara sahip bir VT'ye neden olacaktır.İlk kural bu, ikincisi. Yinelemeye göre w'yi seçin - değişken parametre olarak kNN algoritmanızı w ile çalıştırın ve performansı ölçün (VT'yi sorgulayarak bir tahmin döndürmek için gereken süre).
Öyleyse bir milyon veri noktanız olduğunu hayal edin ..... Noktalar sıradan bir 2D veri yapısında veya bir kd ağacında kalsaydı, her biri için ortalama birkaç milyon mesafe hesaplaması yaparsınızYanıt değişkenini tahmin etmek istediğiniz yeni veri noktaları. Tabii ki, bu hesaplamalar tek bir veri kümesinde gerçekleştirilir. Bir V / T ile, en yakın komşu arama birbiri ardına iki adımda, iki farklı veri popülasyonuna karşı yapılır - önce Voronoi merkezlerine karşı, daha sonra en yakın merkez bulunduğunda, hücrenin içindeki noktalar o merkez en yakın komşuyu bulmak için aranır (birbirini izleyen mesafe hesaplamaları ile) Bu iki arama, tek bir kaba kuvvet bakışından çok daha hızlıdır. Bunu görmek kolaydır: 1M veri noktaları için, veri alanınızı incelemek üzere 250 Voronoi merkezi seçtiğinizi varsayalım. Ortalama olarak, her bir Voronoi hücresinde 4.000 veri noktası olacaktır. Yani ortalama 500.000 mesafe hesaplaması (kaba kuvvet) yapmak yerine, ortalamada sadece 125 + 2.000 gibi çok daha az performans gösterirsiniz.
III. Sonucu Hesaplama (tahmini yanıt değişkeni)
Bir grup kNN egzersiz verisinden tahmini değeri hesaplamak için iki adım vardır. Birincisi, n'yi veya bu hesaplama için kullanılacak en yakın komşu sayısını tanımlamaktır . İkincisi, öngörülen değere katkılarının nasıl ağırlıklandırılacağıdır .
İlk bileşen W / r / t, bir optimizasyon problemini (en küçük kareler optimizasyonuna çok benzer) çözerek n'nin en iyi değerini belirleyebilirsiniz. Teori bu; pratikte çoğu insan sadece n = 3 kullanır. Her halükarda, kNN algoritmanızı n = 1, n = 2, n = 3, vb. İçin bir dizi test örneği üzerinde çalıştırmak ve hatayı n'nin bir fonksiyonu olarak çizmek kolaydır. N'nin başlaması için makul bir değer istiyorsanız, yine n = 3 kullanın.
İkinci bileşen, her bir komşunun katkısının nasıl ağırlıklandırılacağıdır (n> 1 olduğu varsayılarak).
En basit ağırlıklandırma tekniği, her bir komşuyu sadece 1 / (dist * K) olan bir ağırlıklandırma katsayısı veya o komşudan test örneğine olan mesafenin tersi olarak çoğu zaman ampirik olarak türetilmiş bir sabit, K ile çarpmaktır. bu tekniğin bir hayranı değilim, çünkü genellikle en yakın komşuları aşırı ağırlaştırır (ve daha uzak olanları eşzamanlı olarak daha düşük ağırlıklar); bunun önemi, verilen bir tahminin neredeyse tamamen tek bir komşuya bağlı olabilmesidir, bu da algoritmanın gürültüye duyarlılığını arttırır.
Bu sınırlamayı büyük ölçüde önleyen daha iyi bir ağırlık fonksiyonu, python'da şöyle görünen gauss fonksiyonudur :
def weight_gauss(dist, sig=2.0) :
return math.e**(-dist**2/(2*sig**2))
KNN kodunuzu kullanarak tahmin edilen bir değeri hesaplamak için, yanıt değişkenini tahmin etmek istediğiniz veri noktasına en yakın n komşuları tanımlayacaksınız ('test örneği'), ardından n_ komşularının her biri için bir kez weight_gauss işlevini çağıracaksınız. Bu fonksiyon, her komşu için ağırlığı döndürür, bu daha sonra ağırlıklı ortalama hesaplamasında komşunun katsayısı olarak kullanılır.