Главная
#Практика и карьера #Classification #Data Science

Что такое Class weights и rebalancing в Data Science и как работать с дисбалансом классов кроме метрик в 2026 году?

Class weights и rebalancing становятся важными ровно в тот момент, когда мы понимаем неприятную вещь: проблема дисбаланса классов не решается одной заменой accuracy на recall, PR-AUC или F1. Метрики помогают честнее оценивать модель, но они сами по себе не заставляют алгоритм внимательнее относиться к редкому классу. Если обучение по-прежнему идет так, будто все ошибки стоят одинаково, модель часто продолжает учиться в логике большинства.

Содержание
  1. Почему одних метрик недостаточно
  2. Интуиция class weights: мы делаем ошибку на редком классе дороже
  3. Откуда обычно берут веса классов
  4. Геометрический смысл весов
  5. Что такое rebalancing кроме class weights
  6. Почему oversampling не равен магическому улучшению данных
  7. Когда class weights лучше, а когда лучше sampling
  8. Почему sampling нельзя делать до разбиения на train и validation
  9. Python: как сравнить обычную модель и модель с class weights
  10. Почему rebalancing не отменяет threshold selection
  11. Что важно вынести из темы
  12. Kaggle notebook по теме:

Именно поэтому в Data Science разговор о дисбалансе делится на два уровня. Первый уровень — как мы измеряем качество. Второй — как мы меняем саму задачу обучения, чтобы редкий класс перестал быть почти невидимым для алгоритма. Class weights, oversampling, undersampling и более сложные схемы rebalancing как раз живут на этом втором уровне.

Эту тему стоит рассматривать как часть подготовки данных целиком. Отдельный технический приём почти никогда не работает в отрыве от того, насколько аккуратно собраны признаки, как устроена выборка и нет ли в ней скрытых перекосов.

Для студента это один из тех моментов, где становится видно различие между “оценкой модели” и “управлением поведением модели”. Можно честно сказать, что классификатор плохо ловит редкий класс. Но следующий вопрос важнее: что именно мы будем менять в процессе обучения, чтобы это исправить?

Почему одних метрик недостаточно

Допустим, мы уже знаем, что accuracy обманывает нас на несбалансированных данных. Мы переключились на recall, precision, F1 или PR-AUC. Отлично. Теперь система начала честно показывать, что с редким классом все плохо. Но сама модель от этого еще не изменилась. Она просто получила более строгого судью.

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

Именно поэтому рядом полезно смотреть не только на сами значения recall или F1, но и на то, как ведёт себя precision-recall curve на редких классах. Тогда становится видно, что проблема лежит глубже одной красивой метрики в итоговой таблице.

Интуиция class weights: мы делаем ошибку на редком классе дороже

Самая простая идея звучит так: если объекты меньшинства встречаются редко, но для нас важны, мы должны увеличить цену ошибки на них. Тогда алгоритм перестанет воспринимать пропуск редкого класса как несущественную мелочь. Это не магия и не “улучшение данных”. Это явное изменение objective function.

(L=\sum_{i=1}^{n} w_{y_i}\,\ell(y_i,\hat{y}_i))

Раздел математики: оптимизация и теория машинного обучения.

Что означает каждый символ:

(L) — суммарная функция потерь.

(n) — число объектов.

(y_i) — истинный класс объекта (i).

(\hat{y}_i) — предсказание модели.

(\ell(y_i,\hat{y}_i)) — локальная ошибка на объекте.

(w_{y_i}) — вес класса, к которому относится объект.

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

Численный пример: пусть у нас два объекта. На обычном объекте ошибка равна 0.4, на редком — 0.4 тоже. Если веса одинаковы, суммарная потеря равна (0.4+0.4=0.8). Но если для редкого класса вес равен (5), то суммарная потеря станет (0.4+5\cdot0.4=2.4). Алгоритм начнет чувствовать эту ошибку гораздо сильнее.

Это и есть главный смысл class weights: не нарисовать более красивую метрику, а изменить поверхность потерь так, чтобы ошибка на minority class влияла на шаг оптимизации заметнее.

Откуда обычно берут веса классов

Самая базовая идея — делать вес класса обратно пропорциональным его частоте. Чем реже класс встречается, тем выше его вес. Это логично: если класс почти не представлен в данных, каждая ошибка на нем должна компенсироваться повышенным влиянием на loss.

(w_c=\frac{n}{K\,n_c})

Раздел математики: математическая статистика.

Что означает каждый символ:

(w_c) — вес класса (c).

(n) — общее число объектов.

(K) — число классов.

(n_c) — число объектов класса (c).

Формула появляется как нормированная обратная частота: редкий класс получает больший вес, частый — меньший.

Численный пример: пусть в выборке (n=10000) объектов, два класса, у большинства (n_0=9800), у меньшинства (n_1=200). Тогда вес majority класса равен (w_0=10000/(2\cdot9800)\approx0.51), а вес редкого класса — (w_1=10000/(2\cdot200)=25). Ошибка на minority class начинает весить во много раз сильнее.

Важно понимать: это не универсальная истина, а разумный старт. Иногда веса подбирают вручную под бизнес-цену ошибки, а не только под частоты классов. На практике это почти всегда идёт рядом с вопросом о том, какой рабочий threshold вообще переводит score модели в действие, потому что сама функция потерь и финальный порог влияют на систему по-разному.

Геометрический смысл весов

Геометрически class weights меняют поверхность функции потерь. Если без весов алгоритм видит огромное ровное плато большинства и едва заметные сигналы minority class, то после взвешивания рельеф становится другим: редкий класс буквально поднимается выше в пространстве ошибки. Поэтому граница решения может смещаться в его сторону.

Это особенно легко понять на логистической регрессии. Без весов модель может поставить гиперплоскость так, чтобы минимизировать среднюю ошибку на массе majority class. С весами та же гиперплоскость начинает сдвигаться, потому что несколько ошибок на minority class теперь “давят” на loss так же сильно, как десятки ошибок на majority class.

Что такое rebalancing кроме class weights

Если class weights меняют важность объектов в функции потерь, то rebalancing меняет сам обучающий набор или способ подачи данных. Это второй большой путь работы с дисбалансом.

Основных стратегий три:

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

Oversampling увеличивает minority class. Самый простой вариант — дублировать редкие объекты. Это помогает алгоритму чаще видеть важные примеры, но может усиливать переобучение, если просто копировать один и тот же сигнал.

Синтетическое увеличение вроде SMOTE пытается создавать новые объекты minority class между соседними примерами. Это уже не тупое копирование, а попытка сделать minority manifold плотнее.

Почему oversampling не равен магическому улучшению данных

Здесь важно не впасть в иллюзию. Oversampling не добывает новую информацию из воздуха. Если minority class беден и шумен, его тиражирование или синтетическое размножение не сделает задачу автоматически легкой. Oversampling просто помогает алгоритму внимательнее отнестись к редкому классу и чуть лучше увидеть его локальную геометрию.

Поэтому oversampling особенно полезен тогда, когда minority class действительно несет устойчивый сигнал, но представлен слишком редко для стабильного обучения. Если же minority class разнороден, грязен или смешан с шумом, oversampling может начать тиражировать и сам шум. В этом месте уже важно вернуться к базе и отдельно проверить, насколько вообще данным можно доверять, иначе rebalancing начнёт усиливать не сигнал, а мусор.

Когда class weights лучше, а когда лучше sampling

Class weights особенно удобны в линейных моделях, логистической регрессии, градиентном бустинге и многих алгоритмах, где вес объекта естественно входит в loss. Это аккуратный способ не ломать сами данные, а изменить их вклад в обучение. Он часто оказывается хорошим первым шагом.

Sampling полезен тогда, когда модель сильно чувствительна к частотам наблюдений как к “видимости” паттернов. Например, деревья и некоторые ансамбли могут заметно изменить поведение, если minority class чаще встречается при построении разбиений. В таких случаях oversampling или balanced-batch логика могут дать больше, чем просто веса.

На практике рабочая последовательность обычно такая: сначала честные метрики, затем class weights как baseline-вмешательство, потом аккуратная проверка oversampling или undersampling внутри валидации, и только затем более сложные схемы вроде SMOTE.

Почему sampling нельзя делать до разбиения на train и validation

Это одна из самых опасных ошибок. Если вы сначала размножили minority class, а потом делите данные на train и validation, дубликаты или близкие синтетические объекты могут попасть в обе части сразу. Тогда модель увидит валидацию почти заранее, и метрики станут нереалистично красивыми. Это уже leakage.

Правильный путь такой: сначала честно делим данные, потом применяем rebalancing только внутри train-части каждого фолда. Тогда validation остается нетронутой и реально проверяет обобщающую способность модели.

Python: как сравнить обычную модель и модель с class weights

from sklearn.datasets import make_classification  # Генерируем синтетическую задачу с дисбалансом классов.
from sklearn.model_selection import train_test_split  # Подключаем разбиение на train и test.
from sklearn.linear_model import LogisticRegression  # Берем логистическую регрессию.
from sklearn.metrics import classification_report  # Импортируем отчет по precision, recall и F1.

X, y = make_classification(  # Создаем данные с редким положительным классом.
    n_samples=6000,  # Генерируем шесть тысяч объектов.
    n_features=20,  # Используем двадцать признаков.
    n_informative=6,  # Шесть признаков действительно полезны.
    n_redundant=2,  # Два признака коррелируют с полезными.
    weights=[0.97, 0.03],  # Положительный класс занимает только 3 процента.
    random_state=42,  # Фиксируем случайность.
)  # Получаем матрицу признаков и target.

X_train, X_test, y_train, y_test = train_test_split(  # Делим данные на train и test.
    X, y, test_size=0.2, stratify=y, random_state=42
)  # Сохраняем долю классов в обеих частях.

plain_model = LogisticRegression(max_iter=1000)  # Создаем обычную логистическую регрессию без весов.
plain_model.fit(X_train, y_train)  # Обучаем baseline-модель.
plain_pred = plain_model.predict(X_test)  # Получаем предсказания baseline-модели.

weighted_model = LogisticRegression(max_iter=1000, class_weight='balanced')  # Создаем модель со встроенными весами классов.
weighted_model.fit(X_train, y_train)  # Обучаем взвешенную модель.
weighted_pred = weighted_model.predict(X_test)  # Получаем ее предсказания.

print('Baseline model')  # Печатаем заголовок для baseline.
print(classification_report(y_test, plain_pred, digits=4))  # Смотрим precision, recall и F1 без весов.

print('Weighted model')  # Печатаем заголовок для weighted-модели.
print(classification_report(y_test, weighted_pred, digits=4))  # Смотрим, как веса изменили работу на minority class.

Этот пример полезен тем, что сразу показывает смысл class weights на практике. Обычно recall редкого класса растет, но вместе с этим может просесть precision. Это нормально. Мы сознательно меняем приоритеты модели, а не пытаемся бесплатно получить “все и сразу”.

Почему rebalancing не отменяет threshold selection

Даже если мы удачно настроили class weights или sampling, у модели остается score, а не готовая бизнес-политика. Значит, вопрос выбора рабочего порога все равно остается. Rebalancing меняет то, как модель учится видеть редкий класс. Threshold selection меняет то, как мы переводим этот score в действие. Это разные уровни системы, и их нельзя путать.

Если сформулировать совсем жестко: class weights не заменяют PR-AUC, а oversampling не заменяет рабочий threshold. Все это части одной и той же production-логики.

И ещё одна важная оговорка: любые схемы перевзвешивания и ресемплинга нужно проверять только на чистой валидации. Иначе очень легко получить скрытую утечку и переоценить качество модели, особенно если сначала размножить minority class, а уже потом делить выборку. Поэтому рядом полезно держать в голове и материал о том, как leakage искажает оценку модели ещё до продакшена.

Что важно вынести из темы

Работа с дисбалансом классов не заканчивается на выборе правильной метрики. Метрика честно показывает проблему, но class weights и rebalancing позволяют реально вмешаться в процесс обучения. Веса делают ошибки на редком классе дороже. Sampling меняет видимость minority class для алгоритма. Оба подхода можно использовать аккуратно, если помнить про утечки данных и не ждать бесплатного чуда.

Если сказать совсем коротко, class weights и rebalancing — это способы заставить модель всерьез воспринимать редкий класс. А сильный Data Scientist должен уметь не только измерять дисбаланс, но и менять саму механику обучения так, чтобы редкий, но важный сигнал не растворялся в массе большинства.

Kaggle notebook по теме:

https://www.kaggle.com/code/andreyukio/imbalanced-smote-vs-ctgan-vs-class-weight/notebook

Что читать дальше

Связанные статьи по этой теме

Инструменты Python в 2026 году: современный стек для профессиональной разработки Что должен знать Junior Data Scientist в 2026 году? Как собрать GitHub-портфолио для Data Science
Вернуться в блог