Алгоритм K-Nearest Neighbors: принципы работы и применение в ML

Пройдите тест, узнайте какой профессии подходите
Сколько вам лет
0%
До 18
От 18 до 24
От 25 до 34
От 35 до 44
От 45 до 49
От 50 до 54
Больше 55

Для кого эта статья:

  • Студенты и начинающие специалисты в области Data Science и машинного обучения
  • Профессионалы, желающие углубить свои знания о методах классификации и регрессии
  • Аналитики данных, заинтересованные в практическом использовании алгоритмов машинного обучения на реальных задачах

    Алгоритм K-ближайших соседей (K-Nearest Neighbors, kNN) — один из тех редких методов машинного обучения, который сочетает поразительную простоту концепции с впечатляющей эффективностью на практике. Если вы когда-либо следовали совету "скажи мне, кто твой друг, и я скажу, кто ты", то вы уже интуитивно понимаете суть kNN. Этот алгоритм определяет класс объекта по большинству "голосов" его соседей, предлагая прозрачную и мощную модель для задач классификации и регрессии. Давайте погрузимся в практическое применение kNN с помощью библиотеки sklearn и разберем примеры кода, которые превратят вашу интуицию в работающие прогнозные модели 🔍

Хотите овладеть всем арсеналом методов машинного обучения, включая мастерское применение K-Nearest Neighbors? Профессия аналитик данных от Skypro — это именно то, что нужно. Курс фокусируется не просто на теории, а на практическом применении алгоритмов в реальных задачах. Вы научитесь не только настраивать параметры kNN, но и выбирать оптимальные модели для конкретных наборов данных, что сделает вас ценным специалистом на рынке труда.

Принципы работы K-Nearest Neighbors в sklearn

K-Nearest Neighbors (kNN) — это алгоритм машинного обучения без учителя, который находит применение как в задачах классификации, так и регрессии. Основной принцип его работы элегантно прост: для классификации нового объекта мы находим k ближайших к нему объектов из обучающего набора и определяем его класс путем "голосования" — объект относится к тому классу, который наиболее часто встречается среди его k соседей.

В sklearn этот алгоритм реализован в классах KNeighborsClassifier для задач классификации и KNeighborsRegressor для задач регрессии. Базовый принцип остается неизменным, но в случае регрессии вместо голосования происходит усреднение значений целевой переменной у k ближайших соседей.

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

  • Алгоритм является "ленивым" (lazy learner) — он не строит модель во время обучения, а просто запоминает обучающие данные
  • Предсказания делаются на этапе тестирования путем вычисления расстояний до всех точек обучающей выборки
  • Вычислительная сложность растет с увеличением размера обучающих данных
  • Для ускорения поиска ближайших соседей sklearn использует оптимизированные структуры данных (KD-деревья и Ball-деревья)

Процесс классификации с помощью kNN можно представить следующим образом:

  1. Загрузка и предобработка данных (масштабирование очень важно!)
  2. Разделение данных на обучающую и тестовую выборки
  3. Определение оптимального значения k (обычно нечетное число для избежания ничьих при голосовании)
  4. Обучение модели на тренировочных данных (фактически их сохранение)
  5. Предсказание классов для тестовых данных
  6. Оценка качества модели

Важно понимать, что эффективность kNN сильно зависит от выбора метрики расстояния. По умолчанию sklearn использует евклидово расстояние, но доступны и другие варианты:

Метрика Формула Применение
Евклидова √(Σ(xi-yi)²) Стандартный выбор для непрерывных признаков
Манхэттенская Σxi-yi Менее чувствительна к выбросам
Минковского xi-yi^p)^(1/p) Обобщение евклидовой (p=2) и манхэттенской (p=1)
Чебышева max(xi-yi) Учитывает только максимальное различие по одной из координат

Подбор правильной метрики может существенно улучшить производительность модели в зависимости от структуры ваших данных. 🧮

Александр Петров, ведущий специалист по машинному обучению

На одном из проектов по прогнозированию оттока клиентов банка я столкнулся с интересной проблемой. Использование евклидовой метрики давало точность около 76%, что было неприемлемо. После анализа данных я заметил, что признаки имели совершенно разные шкалы измерения. Перепробовав различные метрики, я обнаружил, что манхэттенская метрика в сочетании с правильным масштабированием данных подняла точность до 89%. Это подтвердило важный урок: никогда не следует полагаться на настройки по умолчанию без понимания природы ваших данных. Именно с того проекта я всегда провожу A/B тестирование различных метрик расстояния для kNN.

Пошаговый план для смены профессии

Реализация kNN-классификации с помощью sklearn

Давайте перейдем от теории к практике и рассмотрим, как реализовать kNN-классификатор с использованием библиотеки sklearn. Я покажу пример кода с комментариями для лучшего понимания каждого шага.

Начнем с импорта необходимых библиотек:

Python
Скопировать код
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

Теперь загрузим данные. Для примера возьмем классический датасет Iris:

Python
Скопировать код
from sklearn.datasets import load_iris

# Загружаем данные
iris = load_iris()
X = iris.data
y = iris.target

# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

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

Теперь создадим и обучим модель kNN:

Python
Скопировать код
# Создаем модель с k=5 соседями
knn_classifier = KNeighborsClassifier(n_neighbors=5)

# Обучаем модель на масштабированных данных
knn_classifier.fit(X_train_scaled, y_train)

# Делаем предсказание
y_pred = knn_classifier.predict(X_test_scaled)

# Оцениваем точность модели
accuracy = accuracy_score(y_test, y_pred)
print(f"Точность модели: {accuracy:.4f}")

# Выводим детальную оценку
print("\nОтчет о классификации:")
print(classification_report(y_test, y_pred, target_names=iris.target_names))

Важно помнить, что для kNN критически важно масштабирование признаков. Без него признаки с большими значениями будут доминировать при расчете расстояний, что может серьезно исказить результаты.

Давайте также рассмотрим, как выбрать оптимальное значение k при помощи кросс-валидации:

Python
Скопировать код
from sklearn.model_selection import GridSearchCV

# Определяем диапазон значений k для проверки
param_grid = {'n_neighbors': np.arange(1, 30)}

# Создаем модель kNN
knn = KNeighborsClassifier()

# Создаем объект GridSearchCV для поиска оптимального k
grid_search = GridSearchCV(knn, param_grid, cv=5)

# Обучаем на тренировочных данных
grid_search.fit(X_train_scaled, y_train)

# Выводим лучшее значение k
print(f"Оптимальное значение k: {grid_search.best_params_['n_neighbors']}")
print(f"Лучшая точность при кросс-валидации: {grid_search.best_score_:.4f}")

# Используем лучшую модель для предсказаний
best_knn = grid_search.best_estimator_
y_pred_best = best_knn.predict(X_test_scaled)

# Оцениваем точность лучшей модели
accuracy_best = accuracy_score(y_test, y_pred_best)
print(f"Точность лучшей модели на тестовой выборке: {accuracy_best:.4f}")

Интересной особенностью kNN является возможность получения вероятностных оценок для предсказаний:

Python
Скопировать код
# Получаем вероятности принадлежности к каждому классу
probabilities = best_knn.predict_proba(X_test_scaled)

# Выведем вероятности для первых 5 тестовых образцов
for i in range(5):
print(f"Образец {i+1}: {iris.target_names[y_test[i]]}")
for j, class_name in enumerate(iris.target_names):
print(f" Вероятность класса '{class_name}': {probabilities[i][j]:.4f}")
print()

Такие вероятностные оценки могут быть очень полезны, когда необходима не только классификация, но и уровень уверенности в предсказании. 📊

Итак, основные шаги для успешной реализации kNN-классификации с помощью sklearn:

  • Масштабирование данных (обязательно!)
  • Выбор оптимального значения k через кросс-валидацию
  • Подбор подходящей метрики расстояния
  • Оценка модели на независимой тестовой выборке
  • При необходимости — использование вероятностных оценок

Построение kNN-регрессии: код и особенности

K-Nearest Neighbors не ограничивается задачами классификации. Этот алгоритм также эффективен для задач регрессии, где необходимо предсказать непрерывное значение целевой переменной. В sklearn для этого предусмотрен класс KNeighborsRegressor, который работает по аналогичному принципу, но вместо "голосования" использует усреднение значений целевой переменной у k ближайших соседей.

Мария Соколова, исследователь в области анализа данных

Работая над проектом по предсказанию стоимости домов в мегаполисе, я экспериментировала с различными алгоритмами регрессии. Линейная регрессия давала неудовлетворительные результаты с RMSE около 120 000 долларов. Решила попробовать KNN-регрессию, предполагая, что стоимость дома часто коррелирует со стоимостью ближайших домов с аналогичными характеристиками. Настроив вес соседей обратно пропорционально расстоянию (weights='distance') и установив k=8 после тщательной перекрестной проверки, я добилась снижения RMSE до 62 000 долларов. Самое интересное — дополнительный анализ показал, что алгоритм фактически "обнаружил" микрорайоны с различной ценовой динамикой, которые не были явно указаны в исходных данных. Это подтвердило мое предположение о локальной природе ценообразования на недвижимость.

Давайте рассмотрим пример реализации kNN-регрессии на примере предсказания цен на недвижимость:

Python
Скопировать код
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error, r2_score

# Загрузим данные о ценах на недвижимость в Бостоне
from sklearn.datasets import load_boston
boston = load_boston()
X = boston.data
y = boston.target

# Разделим данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Масштабируем данные
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

# Создаем модель KNN-регрессии с k=5 и взвешиванием по расстоянию
knn_regressor = KNeighborsRegressor(n_neighbors=5, weights='distance')

# Обучаем модель
knn_regressor.fit(X_train_scaled, y_train)

# Делаем предсказания
y_pred = knn_regressor.predict(X_test_scaled)

# Оцениваем точность модели
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
r2 = r2_score(y_test, y_pred)

print(f"Среднеквадратичная ошибка (MSE): {mse:.4f}")
print(f"Корень из среднеквадратичной ошибки (RMSE): {rmse:.4f}")
print(f"Коэффициент детерминации (R²): {r2:.4f}")

Особенности kNN-регрессии, которые стоит учитывать:

  1. Взвешивание соседей: Параметр weights позволяет выбрать между равномерным взвешиванием всех соседей ('uniform') и взвешиванием обратно пропорционально их расстоянию от предсказываемой точки ('distance'). Второй вариант часто даёт лучшие результаты, так как учитывает, что ближайшие соседи обычно более релевантны.
  2. Проблема "краевых" точек: Для наблюдений вблизи края распределения предсказания могут быть смещены, так как все k соседей будут находиться с одной стороны.
  3. Проблема редких данных: В областях с малой плотностью данных kNN-регрессия может давать ненадежные результаты.

Давайте рассмотрим, как можно оптимизировать гиперпараметры kNN-регрессора с помощью перекрестной проверки:

Python
Скопировать код
from sklearn.model_selection import GridSearchCV

# Определяем параметры для поиска
param_grid = {
'n_neighbors': np.arange(1, 20),
'weights': ['uniform', 'distance'],
'p': [1, 2] # p=1 для манхэттенского расстояния, p=2 для евклидова
}

# Создаем модель
knn_reg = KNeighborsRegressor()

# Создаем объект GridSearchCV
grid_search = GridSearchCV(knn_reg, param_grid, cv=5, scoring='neg_mean_squared_error')

# Обучаем на тренировочных данных
grid_search.fit(X_train_scaled, y_train)

# Выводим лучшие параметры
print(f"Лучшие параметры: {grid_search.best_params_}")
print(f"Лучшая средняя ошибка MSE при кросс-валидации: {-grid_search.best_score_:.4f}")

# Используем лучшую модель для предсказаний
best_knn_reg = grid_search.best_estimator_
y_pred_best = best_knn_reg.predict(X_test_scaled)

# Оцениваем точность лучшей модели
mse_best = mean_squared_error(y_test, y_pred_best)
r2_best = r2_score(y_test, y_pred_best)
print(f"MSE лучшей модели на тестовой выборке: {mse_best:.4f}")
print(f"R² лучшей модели на тестовой выборке: {r2_best:.4f}")

Сравнение KNeighborsRegressor и других регрессионных алгоритмов:

Алгоритм Преимущества Недостатки Когда использовать
KNN-регрессия Не делает предположений о данных, моделирует сложные зависимости Медленно работает на больших данных, чувствителен к шуму Небольшие датасеты, нелинейные зависимости
Линейная регрессия Быстрая, интерпретируемая Моделирует только линейные зависимости Когда есть линейная связь между признаками и целевой переменной
Решающие деревья Моделирует нелинейные зависимости, устойчив к выбросам Склонен к переобучению Данные с категориальными признаками, нелинейные зависимости
Случайный лес Высокая точность, устойчивость к переобучению Медленное обучение, сложная интерпретация Когда важна точность предсказаний, а не интерпретация модели

Как и в случае с классификацией, для KNN-регрессии критически важно правильно масштабировать признаки. Также стоит помнить, что KNeighborsRegressor чувствителен к проклятию размерности — с увеличением числа признаков эффективность алгоритма может существенно снижаться. 📉

Настройка ключевых параметров KNeighborsClassifier

Эффективность алгоритма K-ближайших соседов сильно зависит от правильной настройки его параметров. В этом разделе мы подробно рассмотрим ключевые параметры класса KNeighborsClassifier из sklearn и их влияние на производительность модели.

Начнем с самого важного параметра — количества соседей:

n_neighbors — определяет количество соседей, которые будут использоваться для принятия решения о классификации:

  • Маленькие значения (1-5): модель становится более гибкой, может лучше захватывать сложные закономерности, но более подвержена переобучению и шуму в данных.
  • Большие значения (10+): модель становится более стабильной и устойчивой к шуму, но может упускать важные закономерности (недообучение).
  • Обычно рекомендуется использовать нечетные значения (3, 5, 7...) для бинарной классификации, чтобы избежать ситуаций с равенством голосов.

Код для визуализации влияния параметра n_neighbors на точность модели:

Python
Скопировать код
# Проверим, как изменяется точность модели в зависимости от значения k
k_range = range(1, 30)
scores = []

for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(X_train_scaled, y_train)
scores.append(knn.score(X_test_scaled, y_test))

# Визуализируем результаты
plt.figure(figsize=(10, 6))
plt.plot(k_range, scores, marker='o')
plt.xlabel('Значение K')
plt.ylabel('Точность модели')
plt.title('Зависимость точности модели от количества соседей')
plt.grid(True)
plt.show()

weights — определяет, как взвешивать вклад каждого соседа при голосовании:

  • uniform (по умолчанию): все соседи имеют одинаковый вес.
  • distance: вес соседей обратно пропорционален их расстоянию от тестовой точки. Ближайшие соседи имеют больший вес.
  • Можно также передать пользовательскую функцию взвешивания.

algorithm — определяет алгоритм, используемый для вычисления ближайших соседей:

  • auto: автоматический выбор наиболее подходящего алгоритма.
  • ball_tree: использование структуры данных Ball Tree.
  • kd_tree: использование KD-дерева.
  • brute: прямой расчет расстояний между всеми точками.

Для высокоразмерных данных 'brute' может быть эффективнее, чем древовидные структуры, особенно при малых наборах данных.

p — параметр для расстояния Минковского, определяет тип используемой метрики:

  • p=1: манхэттенское расстояние (сумма модулей разностей координат).
  • p=2: евклидово расстояние (корень из суммы квадратов разностей).
  • Другие значения p дают обобщенные метрики Минковского.

metric — задает метрику расстояния, используемую для поиска ближайших соседей:

  • euclidean, manhattan, chebyshev, minkowski и многие другие.
  • Можно также передать пользовательскую функцию для расчета расстояния.

leaf_size — параметр для алгоритмов BallTree и KDTree, влияет на скорость построения и запросов:

  • Большие значения приводят к более быстрому построению дерева, но могут замедлить запросы.
  • Рекомендуемый диапазон: 10-50.

Давайте рассмотрим, как эффективно подобрать оптимальные значения параметров с помощью сетки параметров и перекрестной проверки:

Python
Скопировать код
from sklearn.model_selection import GridSearchCV

# Определяем параметры для поиска
param_grid = {
'n_neighbors': [3, 5, 7, 9, 11, 13, 15],
'weights': ['uniform', 'distance'],
'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute'],
'p': [1, 2],
'leaf_size': [10, 20, 30, 40, 50]
}

# Создаем базовую модель
knn = KNeighborsClassifier()

# Создаем объект GridSearchCV с использованием 5-кратной перекрестной проверки
grid_search = GridSearchCV(knn, param_grid, cv=5, scoring='accuracy', n_jobs=-1)

# Обучаем на тренировочных данных
grid_search.fit(X_train_scaled, y_train)

# Выводим лучшие параметры и соответствующую точность
print(f"Лучшие параметры: {grid_search.best_params_}")
print(f"Лучшая точность при кросс-валидации: {grid_search.best_score_:.4f}")

# Создаем модель с лучшими параметрами
best_knn = KNeighborsClassifier(**grid_search.best_params_)
best_knn.fit(X_train_scaled, y_train)

# Оцениваем на тестовой выборке
accuracy = best_knn.score(X_test_scaled, y_test)
print(f"Точность на тестовой выборке: {accuracy:.4f}")

Важно помнить, что перебор такой большой сетки параметров может занять много времени, особенно на больших наборах данных. В таких случаях можно использовать RandomizedSearchCV вместо GridSearchCV для более эффективного поиска 🕒:

Python
Скопировать код
from sklearn.model_selection import RandomizedSearchCV

# Определяем расширенные параметры для случайного поиска
param_dist = {
'n_neighbors': np.arange(1, 30),
'weights': ['uniform', 'distance'],
'algorithm': ['auto', 'ball_tree', 'kd_tree', 'brute'],
'p': [1, 2, 3],
'leaf_size': np.arange(10, 100, 10)
}

# Создаем объект RandomizedSearchCV
random_search = RandomizedSearchCV(
knn, param_distributions=param_dist, n_iter=100, cv=5, 
scoring='accuracy', n_jobs=-1, random_state=42
)

# Обучаем на тренировочных данных
random_search.fit(X_train_scaled, y_train)

# Выводим лучшие параметры
print(f"Лучшие параметры: {random_search.best_params_}")
print(f"Лучшая точность при кросс-валидации: {random_search.best_score_:.4f}")

Оптимизация K-Nearest Neighbors для реальных задач

При использовании K-Nearest Neighbors в реальных проектах часто возникают вызовы, которые не решаются простой настройкой базовых параметров. В этом разделе мы рассмотрим продвинутые стратегии оптимизации kNN для работы с большими объемами данных, несбалансированными классами и высокоразмерными признаками. 🚀

1. Ускорение работы с большими наборами данных

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

Python
Скопировать код
# Использование приближенных методов поиска ближайших соседей
from sklearn.neighbors import NearestNeighbors

# Создаем модель для поиска ближайших соседей с использованием приближенного алгоритма
nbrs = NearestNeighbors(n_neighbors=5, algorithm='auto', leaf_size=30, n_jobs=-1)
nbrs.fit(X_train_scaled)

# Поиск соседей для первых 5 тестовых образцов
distances, indices = nbrs.kneighbors(X_test_scaled[:5])

# Индексы k ближайших соседей для каждого из 5 образцов
print("Индексы ближайших соседей:")
print(indices)

# Расстояния до этих соседей
print("\nРасстояния до соседей:")
print(distances)

Для очень больших наборов данных можно использовать методы аппроксимации ближайших соседей:

Python
Скопировать код
# Для очень больших наборов данных можно использовать ANNOY или FAISS
# pip install annoy
import numpy as np
from annoy import AnnoyIndex

# Создаем индекс Annoy для быстрого приближенного поиска соседей
f = X_train_scaled.shape[1] # Количество признаков
t = AnnoyIndex(f, 'euclidean') # Используем евклидово расстояние

# Добавляем все точки в индекс
for i in range(X_train_scaled.shape[0]):
t.add_item(i, X_train_scaled[i])

# Строим индекс с 100 деревьями (больше деревьев = выше точность)
t.build(100)

# Ищем ближайших соседей для первого тестового образца
nearest_neighbors = t.get_nns_by_vector(X_test_scaled[0], 5)
print(f"Индексы 5 ближайших соседей для первого тестового образца: {nearest_neighbors}")
print(f"Классы этих соседей: {y_train[nearest_neighbors]}")

2. Работа с несбалансированными классами

Несбалансированные классы — частая проблема в реальных задачах. kNN может быть особенно чувствителен к этой проблеме, так как мажоритарный класс будет преобладать среди k ближайших соседей.

Python
Скопировать код
# Использование стратегий ресэмплинга для решения проблемы несбалансированных классов
from imblearn.over_sampling import SMOTE
from imblearn.under_sampling import RandomUnderSampler
from imblearn.pipeline import Pipeline

# Создаем конвейер для ресэмплинга
# Сначала выполняем undersample мажоритарного класса, затем oversample миноритарного с помощью SMOTE
resample_pipeline = Pipeline([
('under', RandomUnderSampler(sampling_strategy=0.5, random_state=42)),
('over', SMOTE(sampling_strategy='auto', random_state=42))
])

# Применяем ресэмплинг
X_resampled, y_resampled = resample_pipeline.fit_resample(X_train_scaled, y_train)

# Проверяем распределение классов после ресэмплинга
print("Распределение классов после ресэмплинга:")
for class_label, count in zip(*np.unique(y_resampled, return_counts=True)):
print(f"Класс {class_label}: {count} образцов")

# Обучаем KNN на сбалансированных данных
knn_balanced = KNeighborsClassifier(n_neighbors=5)
knn_balanced.fit(X_resampled, y_resampled)

# Оцениваем результаты
from sklearn.metrics import balanced_accuracy_score, f1_score

y_pred_balanced = knn_balanced.predict(X_test_scaled)
balanced_acc = balanced_accuracy_score(y_test, y_pred_balanced)
f1 = f1_score(y_test, y_pred_balanced, average='weighted')

print(f"Сбалансированная точность: {balanced_acc:.4f}")
print(f"F1-мера (weighted): {f1:.4f}")

3. Снижение размерности и отбор признаков

KNN особенно чувствителен к "проклятию размерности". При увеличении числа признаков эффективность алгоритма может резко снижаться. Рассмотрим методы снижения размерности:

Python
Скопировать код
# Применение методов снижения размерности
from sklearn.decomposition import PCA
from sklearn.feature_selection import SelectKBest, f_classif
from sklearn.pipeline import Pipeline

# Создаем конвейер с PCA
pca_pipeline = Pipeline([
('scaler', StandardScaler()),
('pca', PCA(n_components=0.95)), # Сохраняем 95% дисперсии
('knn', KNeighborsClassifier(n_neighbors=5))
])

# Обучаем и оцениваем
pca_pipeline.fit(X_train, y_train)
pca_accuracy = pca_pipeline.score(X_test, y_test)

# Создаем конвейер с отбором признаков
select_pipeline = Pipeline([
('scaler', StandardScaler()),
('select', SelectKBest(f_classif, k=5)), # Выбираем 5 лучших признаков
('knn', KNeighborsClassifier(n_neighbors=5))
])

# Обучаем и оцениваем
select_pipeline.fit(X_train, y_train)
select_accuracy = select_pipeline.score(X_test, y_test)

print(f"Точность с PCA: {pca_accuracy:.4f}")
print(f"Точность с SelectKBest: {select_accuracy:.4f}")

# Выведем выбранные признаки
feature_mask = select_pipeline.named_steps['select'].get_support()
selected_features = [feature for feature, selected in zip(boston.feature_names, feature_mask) if selected]
print(f"Выбранные признаки: {selected_features}")

4. Ансамблевые методы на основе kNN

Комбинирование нескольких kNN-моделей может повысить точность и устойчивость предсказаний:

Python
Скопировать код
# Создаем ансамбль из нескольких kNN-моделей с разными метриками и значениями k
from sklearn.ensemble import VotingClassifier

# Создаем разные модели kNN
knn1 = KNeighborsClassifier(n_neighbors=3, weights='uniform', p=2)
knn2 = KNeighborsClassifier(n_neighbors=5, weights='distance', p=1)
knn3 = KNeighborsClassifier(n_neighbors=7, weights='distance', p=2)

# Объединяем их в ансамбль
ensemble = VotingClassifier(
estimators=[('knn1', knn1), ('knn2', knn2), ('knn3', knn3)],
voting='soft' # Используем вероятностное голосование
)

# Обучаем ансамбль
ensemble.fit(X_train_scaled, y_train)

# Оцениваем результаты
ensemble_accuracy = ensemble.score(X_test_scaled, y_test)
print(f"Точность ансамбля: {ensemble_accuracy:.4f}")

Сравнение различных стратегий оптимизации kNN:

Стратегия Преимущества Недостатки Когда применять
Приближенные методы поиска Значительное ускорение на больших данных Небольшая потеря точности Огромные наборы данных (миллионы образцов)
Ресэмплинг Улучшает работу с несбалансированными классами Может привести к переобучению Сильно несбалансированные наборы данных
Снижение размерности Уменьшает влияние проклятия размерности Потенциальная потеря важной информации Наборы данных с большим количеством признаков
Ансамблевые методы Повышает устойчивость и точность Увеличивает сложность и время обучения Когда требуется максимальная точность

В заключение, успешное применение kNN в реальных задачах требует комплексного подхода. Комбинирование различных стратегий оптимизации в зависимости от характеристик конкретной задачи позволяет получить максимальную производительность при использовании этого простого, но мощного алгоритма. 🧠

K-Nearest Neighbors — это не просто алгоритм из учебника, а мощный инструмент анализа данных, актуальный даже в эпоху глубокого обучения. Его простая интерпретируемость, отсутствие предположений о структуре данных и возможность быстрой адаптации делают его незаменимым в арсенале каждого специалиста по данным. Помните, что настоящее мастерство приходит не от механического применения метода, а от глубокого понимания его принципов и тонкой настройки под конкретную задачу. Не бойтесь экспериментировать с параметрами, метриками расстояния и стратегиями оптимизации — именно так рождаются эффективные решения для сложных проблем реального мира.

Читайте также

Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Что такое K-Nearest Neighbors (KNN)?
1 / 5

Загрузка...