KNN (k-Nearest Neighbors, «k ближайших соседей») — это один из самых простых и интуитивных алгоритмов машинного обучения. Он используется как для классификации, так и для регрессии. Иногда его называют «ленивым» алгоритмом (lazy learner), потому что он не строит явную модель во время обучения, а просто запоминает обучающие данные и делает вывод при появлении нового объекта.
Основная идея
Для нового объекта алгоритм:
- Находит наиболее похожих на него объектов из обучающей выборки (соседей).
- Смотрит на их ответы.
- Выдаёт итоговый прогноз:
- Классификация: выбирается класс, который чаще всего встречается среди соседей (голосование большинством).
- Регрессия: берётся среднее (или взвешенное среднее) значений целевой переменной у соседей.
Как измеряется «похожесть»
Чаще всего используется расстояние между объектами:
- Евклидово расстояние:
- Манхэттенское расстояние:
- Косинусное расстояние, расстояние Говера и другие — в зависимости от типов признаков.
Важно: перед применением KNN признаки нужно масштабировать (стандартизация или нормализация), иначе признаки с большими единицами измерения будут доминировать в расстоянии.
Параметр
- Маленькое (например, 1): модель чувствительна к шуму и выбросам, может переобучаться.
- Большое : модель становится более гладкой, но может недообучаться и размывать границы классов.
- Часто выбирают нечётное для классификации, чтобы избежать ничьих.
- Оптимальное подбирают по кросс-валидации.
Веса соседей
Можно учитывать расстояние: чем ближе сосед, тем больше его вклад.
weights='uniform'— все соседи равны.weights='distance'— вес обратно пропорционален расстоянию.
Преимущества
- Очень прост в понимании и реализации.
- Не требует обучения (нет этапа подгонки параметров).
- Естественно работает с многоклассовой классификацией.
- Может улавливать нелинейные зависимости.
- Непараметрический: не делает предположений о распределении данных.
Недостатки
- Медленное предсказание: нужно сравнивать новый объект со всеми обучающими.
- Большая память: хранит всю обучающую выборку.
- Проклятие размерности: в пространствах высокой размерности расстояния теряют смысл, качество падает.
- Чувствительность к масштабу, выбросам и несбалансированным классам.
- Плохо работает с категориальными признаками без специального кодирования.
- Нет интерпретируемой модели (нельзя сказать, какие признаки важны).
Пример на Python (scikit-learn)
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import make_pipeline
model = make_pipeline(
StandardScaler(),
KNeighborsClassifier(n_neighbors=5, weights='distance')
)
model.fit(X_train, y_train)
pred = model.predict(X_test)