03 · Nadzorowane · 4 min czytania · Interaktywne · aktualizacja
Jak działa algorytm k najbliższych sąsiadów i jak dobrać k?
W skrócie
Metoda kNN klasyfikuje nowy punkt głosem k najbliższych przykładów treningowych. Jest prosta i elastyczna, ale wrażliwa na skalę cech i ich liczbę.
Co to jest
Metoda k najbliższych sąsiadów (k-nearest neighbors, kNN) to algorytm, który dla nowego przypadku znajduje k najbardziej podobnych przykładów w zbiorze treningowym i przypisuje mu klasę, która przeważa wśród tych sąsiadów. W regresji zamiast głosowania bierze średnią ich wartości. Podobieństwo mierzy się zwykle odległością euklidesową w przestrzeni cech.
To model „leniwy”: podczas treningu nie robi nic poza zapamiętaniem danych, cała praca dzieje się przy przewidywaniu. Nie ma wag do nauczenia ani wzoru do odczytania — model to po prostu zbiór treningowy plus reguła głosowania.
Intuicja jest codzienna: chcąc ocenić cenę mieszkania, patrzysz na kilka najbardziej podobnych ofert w okolicy. Analiza teoretyczna metody zaczęła się od pracy Fixa i Hodgesa (1951), a znany wynik Covera i Harta (1967) mówi, że przy nieskończenie wielu danych błąd reguły jednego sąsiada jest co najwyżej dwa razy większy od najmniejszego możliwego błędu.
Mechanizm — dlaczego tak działa
kNN opiera się na jednym założeniu: punkty bliskie w przestrzeni cech mają podobne odpowiedzi. Jeśli to prawda, lokalna większość jest dobrym przybliżeniem prawdopodobieństwa klasy w danym miejscu. Model nie zakłada żadnego kształtu granicy, więc może dopasować się do dowolnie skomplikowanego podziału — pod warunkiem, że ma dość danych.
Parametr k steruje kompromisem obciążenie–wariancja. Przy k = 1 model zapamiętuje każdy punkt, także błędnie oznaczony; granica jest postrzępiona, a trafność na treningu zawsze wynosi 100% (punkt jest swoim własnym sąsiadem). Większe k uśrednia więcej punktów: granica się wygładza, wpływ szumu maleje. Przy k równym liczbie danych model zawsze przewiduje klasę większościową. Dobre k leży gdzieś pomiędzy i dobiera się je walidacją krzyżową; przy dwóch klasach wybiera się k nieparzyste, żeby uniknąć remisów.
Najważniejsza praktyczna pułapka to skala cech. Odległość euklidesowa sumuje kwadraty różnic, więc cecha o dużych liczbach — masa w gramach, dochód w złotych — zdominuje cechy mierzone w małych jednostkach. Bez standaryzacji kNN de facto używa tylko jednej cechy.
Druga pułapka to wymiar. W wielu wymiarach odległości między punktami stają się do siebie podobne: „najbliższy” sąsiad jest niewiele bliżej niż przeciętny. To przejaw przekleństwa wymiarowości. Do tego każda nieistotna cecha dodaje do odległości szum, który rozmywa sygnał z cech ważnych. kNN nie umie sam zignorować bezużytecznych cech — trzeba je usunąć wcześniej.
Trzeci koszt: przewidywanie wymaga porównania z całym zbiorem treningowym. Struktury danych (drzewa KD, drzewa kul) przyspieszają to w niskich wymiarach; przy milionach wektorów stosuje się przybliżone wyszukiwanie sąsiadów, to samo, które napędza dziś wyszukiwanie wektorowe.
Na przykładzie
Palmer Penguins: 342 pingwiny, cztery pomiary (długość i głębokość dzioba w mm, długość płetwy w mm, masa w g), trzy gatunki; trening na 256, test na 86 (podział warstwowy, random_state=0). Bez skalowania kNN z k = 5 trafia w 86,0% przypadków. Dlaczego tak słabo? Weźmy pingwina Adelie (39,1; 18,7; 181; 3750) i Chinstrap (46,5; 17,9; 192; 3500). Ich odległość to 250,4, z czego niemal wszystko (99,7% sumy kwadratów) pochodzi z różnicy masy 250 g — a różnica 7,4 mm długości dzioba, która akurat najlepiej odróżnia te gatunki, prawie się nie liczy.
Po standaryzacji cech (średnia 0, odchylenie 1) ten sam model ma 98,8%. Wpływ k: dla k = 1, 3 i 5 — 98,8%, dla k = 11 i 25 — 97,7%, dla k = 51 — 96,5%, dla k = 101 — 87,2%, bo „sąsiedztwo” obejmuje już połowę mniej licznego gatunku. Przekleństwo wymiarowości też widać: gdy do czterech pomiarów dopiszemy losowe cechy-szum, trafność w 5-krotnej walidacji krzyżowej spada z 98,2% do 91,8% (10 cech szumu), 79,8% (50) i 63,7% (200).
Dane: Palmer Penguins (pingwiny z Antarktydy)
W praktyce
KNeighborsClassifier(n_neighbors=5)iKNeighborsRegressor; zawsze w potoku:make_pipeline(StandardScaler(), KNeighborsClassifier()).- k dobieraj przez
GridSearchCVpokneighborsclassifier__n_neighbors; typowo 3–30, przy małych zbiorach mniej. weights="distance"daje bliższym sąsiadom większy głos — pomaga, gdy gęstość danych jest nierówna.- Inne metryki przez
metric=:"manhattan"bywa odporniejsza,"cosine"sprawdza się dla tekstu i osadzeń. - Dla dużych zbiorów i wielu wymiarów użyj przybliżonych bibliotek sąsiedztwa (np. FAISS, Annoy) zamiast wyszukiwania dokładnego.
Najczęstsze pytania
- Jak wybrać k?
- Walidacją krzyżową: sprawdź kilka wartości i wybierz tę z najlepszym wynikiem walidacyjnym. Reguła kciuka k ≈ √n bywa punktem startowym, ale nie zastępuje walidacji. Przy remisie wyników wybierz większe k — da gładszą, stabilniejszą granicę.
- Czy kNN nadaje się do dużych zbiorów danych?
- Trening jest natychmiastowy, ale każde przewidywanie wymaga szukania sąsiadów, a cały zbiór musi być w pamięci. Przy milionach przykładów stosuje się przybliżone wyszukiwanie sąsiadów, które poświęca odrobinę dokładności dla ogromnego przyspieszenia.
- Dlaczego kNN źle działa przy wielu cechach?
- Bo w wysokich wymiarach wszystkie punkty są od siebie podobnie daleko, a nieistotne cechy dodają szum do każdej odległości. Model nie potrafi sam ich pominąć. Pomaga selekcja cech, redukcja wymiaru (np. PCA) albo nauczenie lepszej reprezentacji przed zastosowaniem kNN.
Źródła
- Cover T., Hart P. „Nearest Neighbor Pattern Classification”, IEEE Transactions on Information Theory 13(1), 1967.
- Hastie T., Tibshirani R., Friedman J. „The Elements of Statistical Learning”, 2nd ed., 2009, rozdz. 13.3.
- James G., Witten D., Hastie T., Tibshirani R. „An Introduction to Statistical Learning”, 2nd ed., 2021, rozdz. 2.2.3 i 4.
- Dokumentacja scikit-learn, „Nearest Neighbors”: https://scikit-learn.org/stable/modules/neighbors.html