Управление дисбалансом классов с помощью imbalanced-learn: Практические примеры и рекомендации

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

Управление дисбалансом классов с помощью 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))))
  • Принцип работы: Выявляет пары объектов разных классов, между которыми минимальное расстояние, и удаляет объекты мажоритарного класса. Это помогает "очистить" границы классов.
  • Когда использовать: При наличии шумовых данных или пересечений классов.

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 помогает повысить качество моделей в условиях дисбаланса классов, делая их более надежными и устойчивыми к шуму. Экспериментируйте с различными подходами, комбинируйте методы и адаптируйте стратегию под особенности ваших данных для достижения наилучших результатов.

Успешной работы и глубокого понимания методов балансировки данных в ваших проектах!

Nerd IT 🌀 ML, DS, ANN, GPT
Привет! Меня зовут Семён, я работаю в сфере ML и аналитики данных и пишу в блог nerdit.ru статьи о своем опыте и том, что может пригодиться начинающим в начале их пути изучения больших данных.

Подписаться на новости Nerd IT

Не пропустите последние выпуски. Зарегистрируйтесь сейчас, чтобы получить полный доступ к статьям.
jamie@example.com
Подписаться