Алгоритм K-Nearest Neighbors: принципы работы и применение в ML
Для кого эта статья:
- Студенты и начинающие специалисты в области 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 можно представить следующим образом:
- Загрузка и предобработка данных (масштабирование очень важно!)
- Разделение данных на обучающую и тестовую выборки
- Определение оптимального значения k (обычно нечетное число для избежания ничьих при голосовании)
- Обучение модели на тренировочных данных (фактически их сохранение)
- Предсказание классов для тестовых данных
- Оценка качества модели
Важно понимать, что эффективность 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. Я покажу пример кода с комментариями для лучшего понимания каждого шага.
Начнем с импорта необходимых библиотек:
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:
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:
# Создаем модель с 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 при помощи кросс-валидации:
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 является возможность получения вероятностных оценок для предсказаний:
# Получаем вероятности принадлежности к каждому классу
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-регрессии на примере предсказания цен на недвижимость:
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-регрессии, которые стоит учитывать:
- Взвешивание соседей: Параметр
weightsпозволяет выбрать между равномерным взвешиванием всех соседей ('uniform') и взвешиванием обратно пропорционально их расстоянию от предсказываемой точки ('distance'). Второй вариант часто даёт лучшие результаты, так как учитывает, что ближайшие соседи обычно более релевантны. - Проблема "краевых" точек: Для наблюдений вблизи края распределения предсказания могут быть смещены, так как все k соседей будут находиться с одной стороны.
- Проблема редких данных: В областях с малой плотностью данных kNN-регрессия может давать ненадежные результаты.
Давайте рассмотрим, как можно оптимизировать гиперпараметры kNN-регрессора с помощью перекрестной проверки:
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 на точность модели:
# Проверим, как изменяется точность модели в зависимости от значения 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.
Давайте рассмотрим, как эффективно подобрать оптимальные значения параметров с помощью сетки параметров и перекрестной проверки:
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 для более эффективного поиска 🕒:
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 может быть вычислительно затратным на больших наборах данных, так как для каждого нового образца нужно рассчитывать расстояние до всех точек обучающего набора. Рассмотрим несколько подходов к оптимизации:
# Использование приближенных методов поиска ближайших соседей
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)
Для очень больших наборов данных можно использовать методы аппроксимации ближайших соседей:
# Для очень больших наборов данных можно использовать 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 ближайших соседей.
# Использование стратегий ресэмплинга для решения проблемы несбалансированных классов
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 особенно чувствителен к "проклятию размерности". При увеличении числа признаков эффективность алгоритма может резко снижаться. Рассмотрим методы снижения размерности:
# Применение методов снижения размерности
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-моделей может повысить точность и устойчивость предсказаний:
# Создаем ансамбль из нескольких 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 — это не просто алгоритм из учебника, а мощный инструмент анализа данных, актуальный даже в эпоху глубокого обучения. Его простая интерпретируемость, отсутствие предположений о структуре данных и возможность быстрой адаптации делают его незаменимым в арсенале каждого специалиста по данным. Помните, что настоящее мастерство приходит не от механического применения метода, а от глубокого понимания его принципов и тонкой настройки под конкретную задачу. Не бойтесь экспериментировать с параметрами, метриками расстояния и стратегиями оптимизации — именно так рождаются эффективные решения для сложных проблем реального мира.
Читайте также
- TF-IDF в Python: превращаем текст в векторы для машинного обучения
- Техники обучения ML-моделей на малых данных: основные подходы
- Оптимизация классификаторов Grid Search: настраиваем Random Forest и CatBoost
- Речевые технологии Python: как создать умный голосовой интерфейс
- 15 образовательных ресурсов для изучения нейросетей: от основ до мастерства
- Наивный байесовский классификатор: применение в ML и реализация
- Обучение с подкреплением на Python: как создавать самообучающиеся системы
- Машинное обучение на Python: от базовых навыков к экспертизе


