Как работает алгоритм KNN (k-nearest neighbors)?

Ответ

KNN (k-ближайших соседей) — это алгоритм для задач классификации и регрессии, основанный на метриках близости. Он не строит явную модель во время обучения, а «запоминает» всю обучающую выборку.

Алгоритм работы:

  1. Вычисление расстояний: Для нового объекта вычисляются расстояния до всех точек обучающей выборки. Чаще всего используется Евклидово расстояние, но могут применяться Манхэттенское, косинусное и другие метрики.
  2. Выбор соседей: Выбираются k объектов с наименьшими расстояниями.
  3. Принятие решения:
    • Для классификации: Присваивается класс, наиболее часто встречающийся среди k соседей (мажоритарное голосование).
    • Для регрессии: Вычисляется среднее (или медиана) значений целевой переменной соседей.

Пример классификации с использованием scikit-learn:

from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

# Масштабирование данных критически важно для KNN
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Создание и обучение модели
model = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
model.fit(X_train_scaled, y_train)

# Предсказание
predictions = model.predict(X_test_scaled)

Ключевые особенности и настройки:

  • Чувствительность к масштабу: Обязательна нормализация или стандартизация признаков.
  • Выбор k: Слишком малое k (например, 1) ведет к переобучению и высокой чувствительности к шуму. Слишком большое k сглаживает модель и может привести к недообучению. Оптимальное k подбирается через кросс-валидацию.
  • Вычислительная сложность: Предсказание медленное на больших данных, так как требует вычисления расстояний до всех обучающих примеров. Для ускорения используются структуры данных вроде KD-деревьев или шаровых деревьев.
  • Вес соседей: Часто используется взвешенное голосование, где голос ближайшего соседа имеет больший вес.

Ответ 18+ 🔞

А, KNN, классика жанра, ебать мои старые костыли! Алгоритм, который тупо запоминает всю твою обучающую выборку и потом прикидывается самым умным, сравнивая нового чувака со старыми знакомыми.

Как он работает, если по-простому:

  1. Считаем дистанцию. Появился новый объект — незнакомец. Алгоритм тут же начинает судорожно мерить, насколько он далеко от каждой точки, которую он уже видел. Чаще всего тычется евклидовым расстоянием — это как прямая линия на карте. Но можно и манхэттенским (только по перпендикулярам, как таксист), и другими штуками.
  2. Ищем своих. Из всей этой оравы запомненных данных он выбирает k самых близких по духу соседей. Тех, кто на него больше всего похож.
  3. Принимаем решение.
    • Классификация (кто ты?): Смотрит на этих k соседей. Если большинство из них — пидоры, то и новичка записывает в пидоры. Мажоритарное голосование, хуле.
    • Регрессия (сколько стоит?): Берет у этих соседей их целевую переменную (цену, рост, IQ) и выдает среднюю температуру по больнице.

Вот тебе код, как это впихнуть в scikit-learn:

from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

# Без масштабирования — нихуя не выйдет! KNN без него — как мартышлюшка с гранатой.
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Рожаем модель и учим её (то есть просто даём ей запомнить данные)
model = KNeighborsClassifier(n_neighbors=5, metric='euclidean')
model.fit(X_train_scaled, y_train)

# Ну и спрашиваем у неё: "А кто это у нас тут такой новенький?"
predictions = model.predict(X_test_scaled)

На что обратить внимание, а то обосрёшься:

  • Масштабирование — святое. Если один признак измеряется в миллионах, а другой в сантиметрах, то первый просто заткнёт второго за пояс, и все решения будут только по нему. Доверия ебать ноль к таким результатам. Стандартизируй обязательно!
  • Число k — головная боль. Поставишь k=1 — модель станет истеричной недотрогой, будет орать на каждый шум в данных (переобучение). Поставишь k на всё тренировочное множество — получишь овощ, который всем присваивает самый частый класс (недообучение). Золотую середину ищи кросс-валидацией.
  • Скорость предсказания — пиздец. Чтобы дать ответ, ему нужно пробежаться по ВСЕМ записям в обучении. На больших данных это терпения ноль ебать. Чтобы не ждать до второго пришествия, умные люди придумали KD-деревья — это как картотека, чтобы не листать всё подряд, а сразу прыгать в нужный раздел.
  • Вес голоса. Можно сделать так, чтобы голос соседа, который в двух шагах, весил больше, чем того, который на другом конце квартала. Часто так и делают — это логичнее.