Как сравнить две ML-модели, если средняя метрика скрывает провал сегмента
Одна модель точнее в среднем, другая реже ошибается на новых клиентах. Соберём отчёт, который помогает выбрать модель для внедрения и объяснить решение владельцу продукта.
Сначала зафиксируем, где модель должна работать
В прогнозе суммы заказа новая модель снизила среднюю абсолютную ошибку. Команда собирается заменить старую версию, но менеджер по новым клиентам возражает: у него качество стало хуже. Оба наблюдения могут быть верными. Средняя метрика складывается из ошибок отдельных объектов, а доля больших групп определяет её сильнее, чем качество маленького сегмента.
До сравнения выгрузите предсказания обеих версий на один и тот же набор объектов. Для каждой строки нужны идентификатор, факт, два прогноза и признаки сегмента, известные на момент решения. Если версии считались на разных датах, разница может отражать состав данных. Сегмент «плохие прогнозы новой модели» пригодится для расследования, но не заменит заранее выбранные группы при приёмке.
Определите основную метрику и ограничения. Например, выбираем минимальную общую MAE при условии, что MAE новых клиентов не превышает старую более чем на пять денежных единиц. Число пять должно прийти из допустимого ущерба для процесса. Если команда впервые видит его после сравнения, это уже подгонка правила под понравившуюся версию.
Маленький отчёт, который сохраняет структуру ошибки
В учебной таблице четыре постоянных и два новых клиента. Старая модель ошибается на десять единиц на каждом заказе. Новая лучше на постоянных клиентах, но хуже на новых. Считаем MAE как среднее модулей разности прогноза и факта, затем показываем численность каждой группы. Код использует стандартный Python; вместо списков можно подать строки из сохранённого тестового отчёта.
rows = [
("repeat", 100, 110, 102), ("repeat", 100, 90, 98),
("repeat", 100, 110, 102), ("repeat", 100, 90, 98),
("new", 100, 110, 120), ("new", 100, 90, 80),
]
def report(group):
selected = rows if group == "all" else [r for r in rows if r[0] == group]
old = sum(abs(r[2] - r[1]) for r in selected) / len(selected)
new = sum(abs(r[3] - r[1]) for r in selected) / len(selected)
return len(selected), old, new
for group in ["all", "repeat", "new"]:
print(group, report(group))
assert report("all")[2] < report("all")[1]
assert report("new")[2] > report("new")[1] + 5
Получится общая MAE 10 против 8. Для постоянных клиентов — 10 против 2, для новых — 10 против 20. По нашему заранее заданному ограничению полный переход не проходит. Это конкретное основание вернуть модель на доработку. Можно отдельно исследовать маршрут новых клиентов, но гибридная схема потребует собственной проверки, обслуживания двух версий и корректного определения сегмента в API.
Численность здесь важна не для красоты. Два клиента позволяют проверить арифметику, но ничего не говорят об устойчивости эффекта на будущей неделе. В рабочем отчёте добавьте интервалы разницы и повторите сравнение на нескольких периодах. При зависимых заказах одного клиента единицей повторной выборки должен стать клиент. Тысяча строк от одного покупателя не превращается в тысячу независимых свидетельств.
Дальше откройте несколько крупнейших ошибок внутри проблемного сегмента. Посмотрите, какие сведения модель получает о первом заказе: история покупок может отсутствовать, а признаки, полезные постоянным клиентам, превращаются в пустые значения. Такой разбор даёт проверяемую гипотезу для следующего обучения: например, отделить отсутствие истории от нулевой активности.
В релизный отчёт достаточно перенести правило выбора, общий результат, проблемные срезы с численностью и решение. Сохраните версию данных и код расчёта. При следующем запуске вы сможете проверить ту же договорённость, а обсуждение не начнётся заново с поиска удобной метрики.
Для следующего шага пригодится как разделять данные по клиентам.
В платном курсе «ML Engineer / Data Scientist: табличные модели в продакшн» вы сравните табличные модели по подходящим метрикам и научитесь находить причины их ошибок. По итогам работы останется отчёт, который помогает объяснить выбор модели и ограничения для внедрения. Откройте программу курса.
Продолжить на практике
- ML Engineer / Data Scientist: табличные модели в продакшн ↗
Практический курс для тех, кто хочет получить навыки ML Engineer / Data Scientist на реальных табличных задачах. В курсе Вы не просто обучите CatBoost/LightGBM, а соберёте полноценный production-style пайплайн: подготовка данных, feature engineering (генерация признаков), корректная валидация, защита от leakage (утечек), тюнинг через Optuna, интерпретация через SHAP, batch-инференс и REST API для предсказаний.
