Модель получила цену вне обучающего диапазона: как найти экстраполяцию

Модель прогнозирует продажи по цене и региону. В тесте она работала хорошо, пока цены менялись в привычных пределах. После изменения ассортимента сервис получает дорогие товары в регионе, где раньше продавались только дешёвые. Каждое число по отдельности допустимо, поэтому проверка схемы проходит. Но такого сочетания в обучении не было.

Здесь полезно различать правильность формата и поддержку данными. Число 80 может быть корректной ценой и одновременно лежать за пределами опыта модели для конкретного сегмента. Проверка диапазонов помогает найти такие случаи до того, как средняя ошибка станет заметна в отчёте с запаздывающими фактами.

Простой детектор: диапазон относительно обучения

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

Такая проверка не измеряет точность предсказания. Она выделяет объекты для отдельного анализа, ограничения автоматизации или сбора новых наблюдений. Решение зависит от цены ошибки. Для внутреннего планирования можно вернуть прогноз с диагностическим флагом, а для автоматического назначения условий — передать случай человеку или согласованному правилу.

Почему нужен контекст диапазона

Глобальный диапазон цены может быть от 10 до 100. Однако в северном регионе история покрывает только 10–20, а в южном — 80–100. Значение 80 на севере укладывается в глобальные границы и выходит за локальные. Если связь цены с результатом различается по регионам, этот разрыв имеет практическое значение.

Пример строит границы на прошлых данных, присоединяет их к входу и сохраняет причину флага. Новый регион получает отдельное состояние: для него нет локального диапазона. Соединение выполняется с validate='many_to_one', чтобы ошибка справочника не размножила заявки.

import pandas as pd
train = pd.DataFrame({'region':['north','north','south','south'],
                      'price':[10.,20.,80.,100.]})
incoming = pd.DataFrame({'id':['x1','x2','x3','x4'],
    'region':['north','north','west','south'],
    'price':[15.,80.,30.,120.]})
bounds = train.groupby('region', as_index=False).agg(
    low=('price','min'), high=('price','max'), n=('price','size'))
out = incoming.merge(bounds, on='region', how='left', validate='many_to_one')
out['unknown_group'] = out['n'].isna()
out['outside_global'] = ~out.price.between(train.price.min(), train.price.max())
out['outside_group'] = (~out.unknown_group) & (
    (out.price < out.low) | (out.price > out.high))
out['review'] = out.unknown_group | out.outside_group
print(out[['id','unknown_group','outside_global','outside_group','review']].to_string(index=False))
assert out.loc[out.id=='x2','outside_global'].item() == False
assert out.loc[out.id=='x2','outside_group'].item() == True
assert out.loc[out.review,'id'].tolist() == ['x2','x3','x4']

Строка x2 проходит глобальную проверку, но выходит за северный диапазон. У x3 неизвестен сам регион, у x4 цена выше даже общего максимума. Это три разные причины вмешательства. В журнале их стоит разделить: новая группа требует проверки покрытия, локальный выход — сочетания признаков, глобальный — ещё и возможной ошибки единиц.

До обсуждения поведения модели проверьте источники. Цена могла перейти из рублей в копейки, регион — получить новый код, а колонка скидки — поменять доли на проценты. Откройте исходную строку, сравните с контрактом и статистикой предыдущей загрузки. Переобучение на ошибочных единицах только закрепит проблему.

Чего не видит проверка прямоугольников

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

Очень мелкие группы создадут собственную проблему: их диапазон по двум наблюдениям почти всегда узок. Храните число обучающих объектов и задайте правило достаточного покрытия. Для малых групп можно использовать более широкий родительский сегмент, сохраняя флаг слабой поддержки. Иначе мониторинг завалит команду одинаковыми сигналами.

Разные модели по-разному ведут себя вне знакомой области. Линейная модель продолжает выбранную зависимость; дерево со значениями в листьях часто возвращает знакомый уровень. Ни один из этих ответов сам по себе не подтверждает правильность продолжения. Нужны новые факты именно в появившемся диапазоне и отдельная оценка по ним.

Как проверить полезность сигналов

После прихода фактов сравните ошибку среди обычных объектов и помеченных случаев. Добавьте объём потока и причины флагов. Если сигналы не связаны с ухудшением и не приводят к действию, уточните группы или границы. Мониторинг полезен тогда, когда помогает выбрать конкретный шаг, а не просто доказывает, что данные меняются.

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

Платный курс «ML Engineer / Data Scientist: табличные модели в продакшн» связывает подготовку признаков, валидацию, разбор ошибок и мониторинг качества с batch-инференсом и API. Откройте программу курса, чтобы научиться проверять область применения модели и сохранять диагностические правила рядом с воспроизводимым pipeline.

Продолжить на практике

  • ML Engineer / Data Scientist: табличные модели в продакшн ↗

    Практический курс для тех, кто хочет получить навыки ML Engineer / Data Scientist на реальных табличных задачах. В курсе Вы не просто обучите CatBoost/LightGBM, а соберёте полноценный production-style пайплайн: подготовка данных, feature engineering (генерация признаков), корректная валидация, защита от leakage (утечек), тюнинг через Optuna, интерпретация через SHAP, batch-инференс и REST API для предсказаний.