Редкие категории в модели: когда объединение помогает, а когда стирает сигнал
В столбце «поставщик» тысячи значений, а у части поставщиков есть всего несколько заказов. После кодирования матрица разрастается, отдельные категории легко запоминаются, а на следующей неделе появляются новые имена. Возникает естественное желание заменить всё редкое одной меткой other. Это уменьшает сложность, но иногда объединяет совершенно разные процессы.
Например, небольшой поставщик специализированных деталей редко встречается в заказах, зато имеет особый срок доставки. Если отправить его в общую корзину вместе с случайными разовыми покупками, полезный сигнал исчезнет. Частота категории говорит о количестве наблюдений, а не о её ценности для задачи.
Группировку определяет обучающая выборка
Посчитайте число строк каждой категории только на обучении. Задайте порог: категории ниже него переходят в общую группу. Полученную таблицу соответствия сохраните как часть подготовки признаков. На валидации и в сервисе используйте именно её. Если заново выбирать редкие значения для каждого файла, одно имя получит разные признаки в зависимости от соседних строк.
Отдельно определите поведение пропусков и значений, которых на обучении не было совсем. Пустое поле может означать сбой интеграции, новый поставщик — нормальное развитие каталога, известная редкая категория — недостаток истории. Для диагностики эти ситуации полезно различать, даже если позже кодировщик обрабатывает их похожим способом.
Служебные метки не должны совпадать с настоящими значениями. В небольшом примере используются явные строки и проверка отсутствия коллизий. В общем конвейере можно хранить статус отдельным столбцом или применять зарезервированное кодирование. Важно, чтобы поставщик с реальным названием other не стал незаметно технической корзиной.
Подготовим категории и посмотрим внутрь корзины
Код ниже строит соответствие по шести историческим заказам. Затем применяет его к новой порции без пересчёта частот. В конце отдельно показывает фактические задержки известных редких поставщиков. Эти исходы используются для диагностики объединения, а не для вычисления правила группировки на будущем.
from collections import Counter
train = ['A','A','A','B','B','C']
late = [0,0,1,0,0,1]
reserved = {'__RARE__','__NEW__','__MISSING__'}
assert not set(train) & reserved
counts = Counter(train)
min_count = 3
frequent = {name for name, n in counts.items() if n >= min_count}
known = set(counts)
def transform(value):
if value is None:
return '__MISSING__'
if value not in known:
return '__NEW__'
return value if value in frequent else '__RARE__'
incoming = ['A','B','C','D',None]
mapped = [transform(x) for x in incoming]
print('counts', dict(counts), 'mapped', mapped)
rare = [i for i,x in enumerate(train) if x not in frequent]
print('pooled_rare_late_rate', sum(late[i] for i in rare)/len(rare))
for category in sorted(known-frequent):
ids = [i for i,x in enumerate(train) if x == category]
print(category, 'n', len(ids), 'late_rate', sum(late[i] for i in ids)/len(ids))
assert mapped == ['A','__RARE__','__RARE__','__NEW__','__MISSING__']Поставщики B и C объединяются, и общая доля задержек равна одной трети. При этом у B две доставки без задержки, а у C одна задержанная. Такого объёма недостаточно для уверенных выводов о поставщиках, но пример показывает, какую информацию скрывает общая группа. На реальных данных проверьте её состав и количество наблюдений до выбора преобразования.
Порог — часть эксперимента, а не универсальное число
Сравните несколько порогов на одной валидационной схеме. Для каждого сохраните качество модели, число оставшихся категорий и долю объектов, попавших в общую группу. При задаче доставки особенно полезен отдельный срез новых и редких поставщиков: общая ошибка может почти не измениться, потому что большинство заказов приходится на крупных партнёров.
Если редкая категория имеет осмысленную родительскую группу, используйте её: тип поставщика, регион производства, класс оборудования. Такое объединение сохраняет предметный смысл лучше одной общей корзины. Но справочник должен быть доступен на момент предсказания, а правило выбора родителя — одинаковым в обучении и сервисе.
Модель, умеющая работать с категориями напрямую, тоже требует проверки редких значений. У неё может быть иной механизм регуляризации, поэтому частотное объединение не обязательно улучшит результат. Сравните исходный признак с группировкой в одинаковых условиях, прежде чем добавлять постоянный слой преобразований.
Если используете OneHotEncoder, у него есть параметры min_frequency и max_categories. Их поведение для редких и неизвестных значений нужно согласовать с вашим контрактом. Самодельное правило в примере специально сохраняет три диагностических состояния и не является демонстрацией этого SDK.
Что наблюдать после запуска
Считайте долю новых категорий отдельно от известных редких. Рост новых значений может означать расширение ассортимента, переименование справочника или потерю нормализации. Рост пропусков обычно ведёт к другой проверке — состоянию источника. Общая доля other смешала бы эти причины и затруднила решение о переобучении.
Если в данных есть варианты написания одного имени, исправляйте их до подсчёта частоты. Пробел в конце и разный регистр могут искусственно сделать известного поставщика редким. При этом нормализация должна следовать правилам справочника: безусловное удаление символов способно склеить разные юридические лица. Сохраните исходное значение для разбора и отдельно нормализованный ключ для обучения. После изменения нормализации заново сравните распределение категорий и качество модели.
В платном курсе «ML Engineer / Data Scientist: табличные модели в продакшн» вы готовите признаки, сравниваете CatBoost и LightGBM, разбираете ошибки и сохраняете единый inference pipeline. Это помогает оценивать группировку по качеству на нужной аудитории и переносить её в batch и API. Посмотрите программу курса и выберите практику для следующего табличного проекта.
Продолжить на практике
- ML Engineer / Data Scientist: табличные модели в продакшн ↗
Практический курс для тех, кто хочет получить навыки ML Engineer / Data Scientist на реальных табличных задачах. В курсе Вы не просто обучите CatBoost/LightGBM, а соберёте полноценный production-style пайплайн: подготовка данных, feature engineering (генерация признаков), корректная валидация, защита от leakage (утечек), тюнинг через Optuna, интерпретация через SHAP, batch-инференс и REST API для предсказаний.
