Условие
Fraud-классификатор: 99.7% legit, 0.3% fraud. Когда применять SMOTE, когда undersampling?
Решение
Подход
| Метод | Что делает | Плюсы | Минусы |
|---|---|---|---|
| Undersampling | Случайно убираем majority | Быстро, ресурсы | Теряем информацию |
| Random oversampling | Дублируем minority | Не теряем | Overfit (точные дубли) |
| SMOTE | Синтетический minority через k-NN интерполяцию | Гладко, нет дублей | Шум, если границы классов сложные |
| ADASYN | Как SMOTE, но больше на трудных примерах | Фокус на boundary | Шум усиливается |
| Borderline-SMOTE | SMOTE только у boundary | Чище | Сложнее, нужен класс |
| Class weights | Веса в loss, без перевыборки | Просто, нет artifact | Иногда недостаточно |
SMOTE алгоритм
Для каждой minority point x:
- Найти k=5 ближайших соседей-minority.
- Случайно выбрать одного,
x'. - Создать синт. точку:
x_new = x + λ·(x' − x),λ ∈ [0,1].
Реализация
from imblearn.over_sampling import SMOTE, ADASYN, BorderlineSMOTE
from imblearn.under_sampling import RandomUnderSampler
from imblearn.combine import SMOTEENN, SMOTETomek
from imblearn.pipeline import Pipeline
# Никогда не применять SMOTE до CV!
pipe = Pipeline([
('smote', SMOTE(sampling_strategy=0.1, random_state=42)),
('clf', LogisticRegression())
])Когда что
- Очень большая выборка (10M+, minority 0.1%): undersampling — быстро.
- Малая minority (n_minority < 100): SMOTE — синтетика помогает.
- Tabular numeric: SMOTE хорошо.
- Tabular с categorical: SMOTE-NC.
- Text / image: SMOTE не работает (нет смысла в interpolation). Лучше data augmentation или class weights.
- Tree-based modeling: часто достаточно
class_weight='balanced'илиscale_pos_weight.
Какую долю minority после resample
sampling_strategy=0.5 — 1:2 ratio. Не обязательно 1:1. Над-resample → fake-confident модель.
Подводные камни
- SMOTE до split = leakage: train содержит точки, синтезированные с участием val/test. Всегда внутри pipeline / только на train fold.
- SMOTE в high-dim → синтетика становится бессмысленной (curse of dimensionality).
- SMOTE предполагает гладкую границу классов. Если minority — outliers (как fraud!), интерполяция между outlierами создаёт нереалистичные синт-точки.
- Калибровка: после oversampling модель predict_proba биased. Калибровать на отдельной не-resampled выборке.
- Метрики: accuracy на oversampled бессмысленна — модель отчитывается на 50/50. Считайте PR-AUC на original distribution.
Эталонный ответ
SMOTE: синтетика через k-NN интерполяцию, для numeric tabular с малой minority. Undersampling: для огромных выборок, теряет информацию. Tree-based: часто хватает class_weight. SMOTE всегда внутри CV pipeline на train fold, никогда до split. Калибровка после SMOTE обязательна.