KNN (K-Nearest Neighbors — метод k-ближайших соседей) — это простой, интуитивно понятный алгоритм машинного обучения, используемый для задач классификации и регрессии. Его основная идея: “скажи мне, кто твои соседи, и я скажу, кто ты”.

Основная концепция

Алгоритм основан на предположении, что похожие объекты (близкие в пространстве признаков) имеют схожие значения целевой переменной.

Для классификации:

Объект относится к тому классу, к которому принадлежит большинство из его k ближайших соседей.

Для регрессии:

Значение объекта — это среднее (или медиана) значений его k ближайших соседей.

Как работает алгоритм (шаги)

  1. Загрузить данные: Имеем размеченный набор данных (обучающую выборку)
  2. Выбрать метрику расстояния: Определить, как измерять “близость” объектов
  3. Выбрать k: Количество соседей для рассмотрения
  4. Для нового объекта:
    • Вычислить расстояние от этого объекта до всех объектов в обучающей выборке
    • Найти k объектов с наименьшими расстояниями (ближайших соседей)
    • Для классификации: подсчитать количество соседей каждого класса, назначить наиболее частый класс
    • Для регрессии: вычислить среднее значение соседей

Ключевые компоненты

1. Метрики расстояния (как измеряем близость):

МетрикаФормулаОсобенности
ЕвклидовоНаиболее распространённая, чувствительна к масштабу
МанхэттенскоеПодходит для данных с выбросами, быстрее вычисляется
МинковскогоОбобщение (p=1 — Манхэттен, p=2 — Евклид)
КосинусноеДля текстов, игнорирует длину векторов

2. Выбор параметра k:

  • Слишком маленькое k (k=1):

    • Высокая чувствительность к шуму и выбросам
    • Сложная граница решений, риск переобучения
    • Низкое смещение, высокая дисперсия
  • Слишком большое k:

    • Сглаживание границы решений
    • Учёт далёких (нерелевантных) объектов
    • Высокое смещение, низкая дисперсия
    • Риск недообучения
  • Оптимальное k:

    • Обычно выбирается через кросс-валидацию
    • Часто нечётное (чтобы избежать ничьей в классификации)
    • Практическое правило: k ≈ √n, где n — размер обучающей выборки

3. Взвешивание соседей:

  • Единичные веса: Все соседи равноправны
  • Взвешенные по расстоянию: Более близкие соседи имеют больший вес
    • Например: вес = 1 / расстояние или вес = exp(-расстояние)

Реализация в Python

from sklearn.neighbors import KNeighborsClassifier, KNeighborsRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score
 
# Для классификации
knn_classifier = KNeighborsClassifier(
    n_neighbors=5,        # k соседей
    weights='uniform',    # или 'distance' для взвешивания
    metric='euclidean',   # метрика расстояния
    algorithm='auto'      # алгоритм поиска соседей
)
 
# Для регрессии
knn_regressor = KNeighborsRegressor(
    n_neighbors=5,
    weights='uniform',
    metric='euclidean'
)
 
# Важный этап: масштабирование признаков!
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
 
# Обучение и предсказание
knn_classifier.fit(X_train, y_train)
predictions = knn_classifier.predict(X_test)

Преимущества KNN

  1. Простота реализации и понимания
  2. Не требует обучения (ленивый алгоритм): Модель “запоминает” данные, вычисления происходят только при предсказании
  3. Адаптивность: Легко добавлять новые данные
  4. Универсальность: Работает для классификации и регрессии
  5. Непараметрический: Не делает предположений о распределении данных
  6. Естественная обработка многоклассовых задач

Недостатки и ограничения

  1. Вычислительная сложность:

    • Хранит весь набор данных (проблема памяти)
    • Время предсказания O(n) для наивной реализации
    • Не подходит для больших данных (>50-100 тыс. объектов)
  2. Чувствительность к масштабу и шуму:

    • Требует масштабирования признаков
    • Чувствителен к выбросам и нерелевантным признакам
  3. Проклятие размерности:

    • Эффективность резко падает при большом количестве признаков (>20-30)
    • В высоких размерностях все объекты становятся “одинаково далекими”
  4. Выбор метрики и k: Требует тонкой настройки и кросс-валидации

  5. Неравномерные данные: Плохо работает, когда плотность классов сильно различается

Оптимизации и улучшения

  1. Структуры данных для быстрого поиска:

    • KD-деревья
    • Ball trees
    • LSH (Locality Sensitive Hashing)
  2. Методы уменьшения размерности:

    • PCA, t-SNE для борьбы с проклятием размерности
  3. Отбор признаков: Удаление нерелевантных признаков

  4. Дискретизация непрерывных признаков

Практические рекомендации

Когда использовать KNN:

Хорошо работает, когда:

  • Небольшой или средний набор данных (до 50 тыс. объектов)
  • Небольшое количество признаков (<20)
  • Данные очищены от шума и нормализованы
  • Нужен простой baseline для сравнения
  • Интерпретируемость важнее точности

Стоит избегать, когда:

  • Большие объемы данных
  • Высокая размерность признаков
  • Требуется быстрое предсказание
  • Данные зашумлены или содержат много выбросов

Важные шаги при использовании:

  1. Масштабирование признаков (StandardScaler, MinMaxScaler)
  2. Обработка пропусков и выбросов
  3. Отбор/преобразование признаков
  4. Кросс-валидация для выбора k и метрики
  5. Балансировка классов (если нужно)

Пример выбора k через кросс-валидацию

from sklearn.model_selection import GridSearchCV
 
param_grid = {
    'n_neighbors': list(range(1, 31)),
    'weights': ['uniform', 'distance'],
    'metric': ['euclidean', 'manhattan', 'minkowski']
}
 
grid_search = GridSearchCV(
    KNeighborsClassifier(),
    param_grid,
    cv=5,
    scoring='accuracy'
)
grid_search.fit(X_scaled, y)
print(f"Лучшие параметры: {grid_search.best_params_}")

Интересные модификации

  1. Radius Neighbors: Использует всех соседей в пределах заданного радиуса
  2. KNN с ядрами: Использует ядерные функции для взвешивания
  3. Взвешенный KNN: Разные веса для разных признаков
  4. Адаптивный KNN: k меняется в зависимости от плотности данных

KNN — отличный алгоритм для начала изучения машинного обучения, демонстрирующий фундаментальные концепции близости и сходства объектов. Несмотря на простоту, при правильной подготовке данных и настройке параметров может показывать конкурентоспособные результаты, особенно на небольших и средних наборах данных с явной пространственной структурой.