Управление дисбалансом классов с помощью imbalanced-learn: Практические примеры и рекомендации
В задачах машинного обучения часто возникает проблема дисбаланса классов, когда один класс представлен значительно больше, чем другой. Это может привести к смещению модели в сторону мажоритарного класса, снижая качество предсказаний для редких, но зачастую критически важных классов.

В этом подробном руководстве мы рассмотрим библиотеку imbalanced-learn, изучим ее методы, алгоритмы и лучшие практики, а также приведем расширенные примеры кода.
1. Проблематика дисбалансированных данных
Почему возникает дисбаланс?
- Реальные данные: Во многих прикладных задачах, таких как обнаружение мошенничества, диагностика заболеваний или обнаружение дефектов в производстве, наблюдается естественный дисбаланс: положительные случаи (например, мошеннические транзакции) встречаются редко.
- Сбор данных: Иногда из-за методов сбора информации или этических соображений может возникнуть неравномерное представление классов.
Проблемы при обучении
- Смещение модели: Стандартные алгоритмы могут "запоминать" мажоритарный класс, что приводит к высоким значениям accuracy, но низкому recall для миноритарного класса.
- Неверные метрики: Accuracy часто оказывается недостаточным показателем. Вместо него используют precision, recall, F1-score, ROC-AUC и confusion matrix для оценки качества модели.
2. Обзор библиотеки imbalanced-learn
imbalanced-learn – это специализированная библиотека для работы с дисбалансированными данными. Ее основные преимущества:
- Совместимость с scikit-learn: Методы можно легко интегрировать в пайплайны и использовать вместе с алгоритмами scikit-learn.
- Широкий спектр алгоритмов: Библиотека содержит как методы oversampling, так и undersampling, а также комбинированные подходы.
Основные категории алгоритмов
2.1. Методы Oversampling (увеличение выборки миноритарного класса)
- RandomOverSampler: Случайное повторение примеров миноритарного класса.
- SMOTE (Synthetic Minority Over-sampling Technique): Создает синтетические образцы, используя метод ближайших соседей для интерполяции между существующими точками.
- BorderlineSMOTE: Фокусируется на точках, находящихся у границы классов, что позволяет улучшить разделимость.
- ADASYN (Adaptive Synthetic Sampling): Похож на SMOTE, но генерирует больше синтетических образцов для трудноклассифицируемых примеров.
- SVMSMOTE: Использует алгоритмы опорных векторов для определения пограничных точек.
2.2. Методы Undersampling (уменьшение выборки мажоритарного класса)
- RandomUnderSampler: Случайное удаление примеров мажоритарного класса.
- Tomek Links: Удаляет пары объектов, которые являются "Tomek Link" (близкие по расстоянию, но принадлежат разным классам), что помогает убрать шум.
- NearMiss: Метод выбора наиболее сложных для классификации примеров мажоритарного класса.
- ClusterCentroids: Производит кластеризацию и заменяет группы объектов мажоритарного класса их центроидами.
2.3. Комбинированные методы
- SMOTETomek: Объединяет преимущества SMOTE (oversampling) и Tomek Links (очистка шумовых данных).
- SMOTEENN: Комбинирует SMOTE с Edited Nearest Neighbours для удаления неправильно классифицированных примеров.
3. Установка и интеграция
Установка
Для установки библиотеки выполните в терминале:
pip install imbalanced-learn
Интеграция с пайплайнами scikit-learn
Одним из больших преимуществ imbalanced-learn является его интеграция с конвейерами scikit-learn. Это позволяет комбинировать этапы балансировки данных с обучением модели, минимизируя риск утечки информации.
Пример интеграции:
from sklearn.pipeline import Pipeline
from imblearn.over_sampling import SMOTE
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.datasets import make_classification
# Генерация синтетического набора данных
X, y = make_classification(n_samples=1000, n_features=20, n_redundant=2,
n_clusters_per_class=1, weights=[0.95, 0.05],
random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
# Создание пайплайна с использованием SMOTE и классификатора
pipeline = Pipeline([
('smote', SMOTE(random_state=42)),
('classifier', RandomForestClassifier(random_state=42))
])
# Кросс-валидация для оценки модели
scores = cross_val_score(pipeline, X_train, y_train, cv=5, scoring='f1')
print("F1-score на кросс-валидации:", scores.mean())
В данном примере SMOTE применяется в рамках пайплайна, что позволяет избежать утечек данных между обучающей и тестовой выборками.
4. Глубокое погружение в алгоритмы
4.1. Oversampling: SMOTE и его варианты
SMOTE
- Принцип работы: Метод интерполирует между ближайшими соседями миноритарного класса для создания новых синтетических образцов.
- Основные параметры:
k_neighbors
: число ближайших соседей для интерполяции (по умолчанию 5).sampling_strategy
: стратегия увеличения выборки (например, до равновесия классов или до заданного соотношения).
Пример использования SMOTE уже был приведен выше. Его можно дополнить настройкой параметров:
from imblearn.over_sampling import SMOTE
# Пример настройки параметров SMOTE
smote = SMOTE(sampling_strategy=0.5, k_neighbors=3, random_state=42)
X_resampled, y_resampled = smote.fit_resample(X, y)
print("Новое распределение классов:", dict(zip(*np.unique(y_resampled, return_counts=True))))
BorderlineSMOTE
- Особенности: Генерирует новые образцы для объектов, находящихся у границы между классами. Это повышает качество разделения классов.
- Параметры: Похожи на SMOTE, но с дополнительной логикой выбора объектов у границы.
ADASYN
- Особенности: Адаптивно распределяет количество синтетических примеров в зависимости от сложности классификации конкретного объекта. Сложные для классификации примеры получают больше новых образцов.
- Параметры: Подобны SMOTE, но с дополнительным параметром
n_neighbors
и внутренними расчетами, определяющими сложность.
4.2. Undersampling: методы удаления примеров
RandomUnderSampler
- Принцип работы: Случайно удаляет объекты из мажоритарного класса до достижения заданного соотношения.
- Плюсы и минусы:
- Плюс: Простота реализации и быстродействие.
- Минус: Потенциальная потеря полезной информации.
Пример:
from imblearn.under_sampling import RandomUnderSampler
rus = RandomUnderSampler(sampling_strategy=0.5, random_state=42)
X_res_under, y_res_under = rus.fit_resample(X, y)
print("Распределение классов после undersampling:", dict(zip(*np.unique(y_res_under, return_counts=True))))
Tomek Links
- Принцип работы: Выявляет пары объектов разных классов, между которыми минимальное расстояние, и удаляет объекты мажоритарного класса. Это помогает "очистить" границы классов.
- Когда использовать: При наличии шумовых данных или пересечений классов.
NearMiss
- Особенности: Отбирает объекты мажоритарного класса, которые находятся ближе всего к объектам миноритарного класса. Существует несколько вариантов NearMiss (v1, v2, v3) с разной логикой выбора объектов.
- Применение: Полезно, когда важна именно граница между классами.
4.3. Комбинированные методы
SMOTETomek
- Суть метода: Сначала применяется SMOTE для увеличения числа примеров миноритарного класса, затем производится очистка с использованием Tomek Links.
- Преимущество: Сочетает преимущества oversampling и удаления шумовых данных.
Пример:
from imblearn.combine import SMOTETomek
smt = SMOTETomek(random_state=42)
X_res_comb, y_res_comb = smt.fit_resample(X, y)
print("Распределение классов после SMOTETomek:", dict(zip(*np.unique(y_res_comb, return_counts=True))))
SMOTEENN
- Принцип работы: После синтеза новых примеров с помощью SMOTE применяется алгоритм Edited Nearest Neighbours (ENN) для удаления примеров, которые не соответствуют своим соседям.
- Сценарии использования: Особенно эффективен, если в данных присутствует большое количество аномальных точек.
5. Расширенные примеры использования
5.1. Визуализация влияния методов oversampling
Для иллюстрации работы методов oversampling создадим двухмерный набор данных, где разница между классами визуально заметна, и сравним распределение до и после применения SMOTE.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
from imblearn.over_sampling import SMOTE
# Создаем набор данных с двумя признаками для наглядности
X, y = make_classification(n_samples=500, n_features=2, n_redundant=0,
n_clusters_per_class=1, weights=[0.85, 0.15],
random_state=42)
print("Исходное распределение классов:")
print(pd.Series(y).value_counts())
# Применяем SMOTE для увеличения выборки миноритарного класса
sm = SMOTE(random_state=42)
X_smote, y_smote = sm.fit_resample(X, y)
print("Распределение классов после SMOTE:")
print(pd.Series(y_smote).value_counts())
# Визуализация
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap='coolwarm', edgecolor='k', alpha=0.7)
plt.title("Изначальные данные")
plt.xlabel("Признак 1")
plt.ylabel("Признак 2")
plt.subplot(1, 2, 2)
plt.scatter(X_smote[:, 0], X_smote[:, 1], c=y_smote, cmap='coolwarm', edgecolor='k', alpha=0.7)
plt.title("Данные после SMOTE")
plt.xlabel("Признак 1")
plt.ylabel("Признак 2")
plt.tight_layout()
plt.show()
5.2. Использование комбинированного подхода с кросс-валидацией
Иногда важно оценить, как методы балансировки влияют на качество модели. Рассмотрим интеграцию SMOTETomek в пайплайн с классификатором и проведение кросс-валидации с использованием нескольких метрик.
from imblearn.combine import SMOTETomek
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import cross_validate
from sklearn.metrics import make_scorer, f1_score, roc_auc_score
# Создаем пайплайн с использованием SMOTETomek
pipeline = Pipeline([
('smt', SMOTETomek(random_state=42)),
('classifier', GradientBoostingClassifier(random_state=42))
])
# Определяем метрики для оценки: F1-score и ROC-AUC
scoring = {
'f1': make_scorer(f1_score),
'roc_auc': make_scorer(roc_auc_score)
}
results = cross_validate(pipeline, X, y, cv=5, scoring=scoring)
print("Средний F1-score:", results['test_f1'].mean())
print("Средний ROC-AUC:", results['test_roc_auc'].mean())
6. Лучшие практики и рекомендации
Анализ данных перед балансировкой
- Исследование распределения: Внимательно изучите распределение классов и признаков. Используйте визуализации и статистические методы для определения аномалий.
- Корректная выборка метрик: Выбирайте метрики (F1-score, ROC-AUC, precision, recall), которые позволяют адекватно оценить работу модели на дисбалансированных данных.
Настройка параметров алгоритмов
- Параметры SMOTE и ADASYN: Играйте с числом ближайших соседей (
k_neighbors
) и стратегиями синтеза. Иногда BorderlineSMOTE или ADASYN могут работать лучше стандартного SMOTE. - Параметры undersampling: Если используется undersampling, внимательно оцените, насколько удаление данных может повлиять на обобщающую способность модели. Попробуйте разные стратегии (NearMiss, ClusterCentroids).
Интеграция и избежание утечек данных
- Использование пайплайнов: Всегда применяйте методы балансировки внутри конвейера обработки данных. Это позволяет избежать утечек информации между этапами обучения и тестирования.
- Кросс-валидация: Проводите оценку модели с использованием кросс-валидации, чтобы убедиться, что балансировка данных не приводит к переобучению.
Мониторинг и валидация модели
- Анализ ошибок: Используйте confusion matrix для анализа ошибок модели. Это поможет выявить, какие классы модель предсказывает неправильно.
- Регулярное обновление: Данные могут изменяться со временем, поэтому периодически проверяйте, актуальна ли стратегия балансировки, и при необходимости перенастраивайте модель.
7. Дополнительные аспекты и направления развития
Интерпретируемость и объяснимость
При использовании синтетических методов (SMOTE, ADASYN) важно понимать, как были сгенерированы новые примеры. В некоторых случаях, особенно в критических приложениях (медицина, финансы), может потребоваться интерпретируемость модели.
Расширенные исследования
- Сравнительный анализ: Рекомендуется проводить сравнительный анализ различных методов балансировки на конкретном наборе данных.
- Гибридные подходы: Комбинирование oversampling и undersampling, а также использование ансамблевых методов (например, BalancedBaggingClassifier) могут дать лучшие результаты.
Возможные ограничения
- Переобучение: При чрезмерном oversampling-е модель может переобучаться на синтетических данных.
- Потеря информации: Undersampling может привести к удалению ценной информации из-за случайного исключения образцов мажоритарного класса.
Библиотека imbalanced-learn предоставляет мощный и гибкий набор инструментов для решения проблемы дисбалансированных данных. В этом руководстве мы рассмотрели:
- Проблематику дисбаланса классов и её влияние на модели машинного обучения.
- Различные методы oversampling и undersampling, их алгоритмическую суть и особенности.
- Практические примеры кода, демонстрирующие применение SMOTE, Tomek Links, SMOTETomek и других методов.
- Интеграцию методов балансировки в пайплайны scikit-learn, настройку параметров и применение кросс-валидации для объективной оценки модели.
- Лучшие практики, рекомендации по анализу данных и мониторингу моделей, а также обсуждение ограничений и направлений дальнейших исследований.
Использование imbalanced-learn помогает повысить качество моделей в условиях дисбаланса классов, делая их более надежными и устойчивыми к шуму. Экспериментируйте с различными подходами, комбинируйте методы и адаптируйте стратегию под особенности ваших данных для достижения наилучших результатов.
Успешной работы и глубокого понимания методов балансировки данных в ваших проектах!
