Как проверить модель: от точности на тесте до цены ошибок
Представим, что модель распределяет обращения клиентов между командами. Она читает текст заявки и определяет тему: оплата, доставка или доступ к аккаунту. После обучения мы получили результат: 90,4% правильных ответов.
Можно ли теперь автоматически отправлять заявки специалистам?
Одной цифры недостаточно. Возможно, модель хорошо распознаёт частые вопросы о доставке, но пропускает каждое третье обращение об оплате. Возможно, тестовые заявки почти повторяют обучающие. А может быть, качество измеряли с помощью данных, которые в реальной работе ещё не доступны.
Проверка модели отвечает на более конкретный вопрос: как она поведёт себя на будущих обращениях, какие ошибки совершит и подходят ли эти ошибки для выбранного способа применения?
В предыдущей главе учебного цикла мы готовили данные для той же задачи: определяли целевую метку, очищали обращения, следили за временем появления признаков и не допускали утечки информации. Теперь предположим, что обученная модель уже есть. Нужно проверить её до запуска и понять, что контролировать после него.
Сначала определяем решение, ради которого проверяем модель
Допустим, система должна автоматически направлять обращения об оплате профильному специалисту. Для остальных тем сохраняется обычный маршрут.
Ошибки здесь различаются по последствиям:
- Пропуск обращения об оплате: заявка уходит в общую очередь, её позже перенаправляют, клиент ждёт дольше.
- Ложное определение оплаты: специалист по оплате получает чужую заявку и тратит время на передачу её другой команде.
Если модель нужна для предварительной сортировки, некоторые ошибки допустимы: сотрудник проверит назначение. Если результат запускает действие без проверки человеком, требования к ошибкам будут строже.
Поэтому до выбора метрики полезно записать проверяемое решение:
Модель выделяет обращения об оплате среди новых заявок. Мы измеряем, сколько таких обращений она находит, сколько лишних отправляет специалисту и как меняется нагрузка на команду.
Это описание связывает техническую проверку с работой системы. Оно также подсказывает, какие данные понадобятся: фактическая тема заявки, прогноз модели и маршрут, выбранный на основании прогноза.
Вывод раздела
- Проверяют не абстрактную «хорошесть» модели, а её пригодность для определённого решения.
- Цена разных видов ошибки может различаться. Её нужно учитывать до выбора итогового порога.
Как получить честную оценку на новых данных
Модель легко проверить на обращениях, которые она уже видела. Результат такой проверки почти ничего не говорит о будущем: алгоритм мог запомнить характерные слова, шаблоны или отдельные заявки.
Обычно данные разделяют по назначению:
| Часть данных | Для чего используется |
|---|---|
| Обучающая | Настроить параметры модели и преобразования признаков |
| Валидационная | Сравнить варианты модели и выбрать правило принятия решения |
| Тестовая | Оценить уже выбранное решение на ранее не использованных данных |
Ключевое различие между валидацией и тестом состоит в том, влияет ли результат на наши решения. Если мы посмотрели качество на тесте, поменяли модель или порог и снова посмотрели качество на том же тесте, тест уже стал частью подбора. Итоговая цифра может оказаться чрезмерно оптимистичной. Такой порядок разделения описан в документации scikit-learn по проверке моделей.
Для обращений клиентов случайного разделения часто недостаточно. Пусть в обучающую часть попала заявка «Не прошёл платёж по заказу 4821», а в тестовую - её повторное отправление с почти тем же текстом. Модель может узнать знакомую формулировку, хотя нам важно понять, справится ли она с новым случаем.
Нужны два дополнительных ограничения:
- Учитывать время. Обучать модель на более ранних обращениях, а проверять на более поздних. Иначе мы рискуем оценивать «прошлое», пользуясь будущими примерами.
- Держать связанные обращения вместе. Повторные заявки, сообщения одной переписки или копии одного инцидента не должны оказываться одновременно в обучении и проверке.
Например, можно обучить модель на заявках января-июня, подобрать порог на июльских и провести финальную оценку на августовских. Если один инцидент продолжается на границе периодов, его обращения нужно обработать по заранее выбранному правилу, чтобы почти одинаковые случаи не оказались по обе стороны границы.
Есть ещё менее заметная проблема: задержка появления правильной метки. При поступлении заявки мы знаем её текст, но окончательная тема иногда становится ясна после работы специалиста. Для теста метку можно взять позже, когда разбор завершился. Для признаков модели - нельзя. Признаки должны соответствовать тому, что было известно в момент принятия решения.
Например, поле «команда, которая закрыла заявку» хорошо подскажет тему на исторических данных. Но при поступлении заявки этого поля ещё нет. Если включить его в модель, тест покажет качество системы, которую невозможно воспроизвести в работе. Это типичная утечка данных.
Справка. Перекрёстная проверка, или cross-validation, несколько раз меняет обучающую и проверочную части данных. Она полезна при выборе модели, когда одной валидационной выборки мало. Но схема разбиения должна соответствовать задаче: для связанных обращений учитывают группы, для последовательных периодов - время. Случайное перемешивание не исправляет зависимость между заявками.
Вывод раздела
- Тест должен напоминать будущие обращения, на которых модель действительно будет работать.
- Правильное разделение определяется не только долями данных, но и временем, связями между заявками и доступностью признаков.
- После выбора модели и порога тест используют для финальной оценки, а не для дальнейшей настройки.
Матрица ошибок: четыре числа вместо одной оценки
Чтобы подробно разобрать качество, временно сведём задачу к одному решению: «оплата» или «не оплата». Даже если исходная модель различает три темы, её работу по важной категории можно проверить отдельно.
Предположим, в тестовой выборке 1000 новых обращений. Из них 60 действительно связаны с оплатой, остальные 940 - с другими темами.
Получили такую матрицу:
| Фактическая тема | Модель: «оплата» | Модель: «не оплата» | Всего |
|---|---|---|---|
| Оплата | 42 | 18 | 60 |
| Другая тема | 78 | 862 | 940 |
| Всего | 120 | 880 | 1000 |
У четырёх внутренних ячеек есть общепринятые обозначения:
- TP, true positive = 42: модель нашла обращение об оплате.
- FN, false negative = 18: обращение об оплате пропущено.
- FP, false positive = 78: чужое обращение ошибочно отправлено специалисту по оплате.
- TN, true negative = 862: другая тема правильно оставлена вне этого маршрута.
В документации scikit-learn строки матрицы соответствуют истинному классу, столбцы - предсказанному. При чтении отчётов всегда проверяйте порядок осей: в других инструментах он может отличаться.
Теперь можно осмысленно вычислять показатели качества.
Вывод раздела
- Матрица ошибок показывает не только число неверных ответов, но и то, какие именно ошибки совершает модель.
- Если разные ошибки имеют разные последствия, итоговый отчёт должен сохранять их раздельно.
Почему accuracy может обмануть
Доля правильных ответов, или accuracy, равна числу правильных решений, делённому на число всех проверенных обращений:
Accuracy = (TP + TN) / (TP + TN + FP + FN).
В нашем примере правильных ответов 42 + 862, а всего обращений 1000:
Accuracy = (42 + 862) / 1000 = 90,4%.
Звучит убедительно. Но посмотрим на простейшее правило: никогда не определять обращение как оплату. Оно правильно назовёт все 940 заявок других тем и ошибётся на 60 заявках об оплате:
Accuracy простого правила = 940 / 1000 = 94%.
По accuracy это правило лучше модели. По назначению системы оно бесполезно: не найдёт ни одного нужного обращения.
Причина - соотношение классов. Обращения об оплате составляют лишь 6% выборки. Большое количество правильно отклонённых заявок других тем может скрыть проблему с поиском редкой, но важной категории.
Это не означает, что accuracy всегда плоха. Если классы встречаются примерно одинаково, а цена ошибок близка, показатель может быть удобным. Но его нельзя интерпретировать без частот классов и матрицы ошибок.
Вывод раздела
- Сравнивайте модель с простым правилом, которое можно применить без ML.
- При редком важном классе высокая доля правильных ответов не гарантирует, что модель выполняет свою задачу.
Precision и recall отвечают на разные вопросы
Для маршрутизации обращений об оплате особенно важны два показателя.
Precision, или точность положительных прогнозов: среди заявок, которые модель назвала оплатой, сколько действительно относятся к оплате?
Precision = TP / (TP + FP) = 42 / (42 + 78) = 35%.
Модель отправила профильной команде 120 заявок. Только 42 из них были по теме. Значит, 78 потребуют другой маршрутизации.
Recall, или полнота: среди всех настоящих обращений об оплате сколько модель нашла?
Recall = TP / (TP + FN) = 42 / (42 + 18) = 70%.
Из 60 нужных обращений система нашла 42 и пропустила 18.
Разница между показателями принципиальна:
- Precision отвечает на вопрос о чистоте очереди специалиста.
- Recall отвечает на вопрос о доле найденных нужных обращений.
Эти определения и другие показатели классификации собраны в руководстве scikit-learn по метрикам.
Можно также посчитать F1 - показатель, который соединяет precision и recall:
F1 = 2 × Precision × Recall / (Precision + Recall).
Ту же формулу можно записать через ячейки матрицы ошибок:
F1 = 2 × TP / (2 × TP + FP + FN).
Для нашего примера:
F1 = 84 / (84 + 78 + 18) ≈ 46,7%.
F1 удобна, когда нужен один показатель, чувствительный и к лишним назначениям, и к пропускам. Но она не знает, что в конкретной компании пропуск заявки об оплате может стоить гораздо дороже лишней передачи специалисту. Одна метрика не заменяет решения о допустимых последствиях ошибок.
Справка. Показатели для класса «оплата» нельзя автоматически переносить на весь многоклассовый классификатор. Для доставки и доступа нужно построить собственные матрицы ошибок и посмотреть, какие темы модель путает между собой.
Вывод раздела
- Precision измеряет, насколько можно доверять положительному маршруту.
- Recall измеряет, какую часть нужных обращений система не теряет.
- F1 соединяет их математически, но не отражает цену ошибок в конкретном процессе.
Как выбрать порог и учесть цену ошибок
Многие классификаторы возвращают не готовое действие, а оценку для каждого класса. Например, для заявки модель выдаёт 0,72 для оплаты. Затем правило решает, направить ли её специалисту:
Направить к специалисту по оплате, если p ≥ t.
Здесь p - оценка модели для класса «оплата», t - выбранный порог.
Если сделать порог строже, специалист получит меньше чужих обращений, но возрастёт риск пропуска нужных. Если сделать его мягче, модель найдёт больше обращений об оплате, но увеличит нагрузку на профильную очередь. Изменение порога меняет правило действия, даже если саму модель не переобучали. Это различие описано в руководстве scikit-learn по настройке порога.
Предположим, мы проверили три варианта на одной и той же валидационной выборке из 1000 заявок. Во всех вариантах 60 обращений действительно относятся к оплате.
| Порог | TP | FN | FP | TN | Precision | Recall |
|---|---|---|---|---|---|---|
| Строгий | 30 | 30 | 20 | 920 | 60% | 50% |
| Средний | 42 | 18 | 78 | 862 | 35% | 70% |
| Мягкий | 54 | 6 | 180 | 760 | 23,1% | 90% |
Какой вариант выбрать? Без сведений о последствиях ответить нельзя.
Для учебного расчёта назначим условную стоимость ошибки:
- Пропущенное обращение об оплате: 100 единиц.
- Лишнее обращение у специалиста по оплате: 15 единиц.
Тогда:
Стоимость ошибок = C(FN) × FN + C(FP) × FP.
Здесь C(FN) - стоимость одного пропуска, C(FP) - стоимость одного ложного назначения.
| Порог | Расчёт | Стоимость |
|---|---|---|
| Строгий | 30 × 100 + 20 × 15 | 3300 |
| Средний | 18 × 100 + 78 × 15 | 2970 |
| Мягкий | 6 × 100 + 180 × 15 | 3300 |
Среди этих трёх вариантов средний порог лучше по выбранному критерию. Простое правило «никогда не определять оплату» стоило бы 60 × 100 = 6000 единиц.
Но здесь есть важное условие: стоимость ошибок должна отражать реальный процесс, а не выбираться для красивого результата. Её можно оценить через дополнительное время обработки, стоимость работы специалиста, задержки ответа или другие измеримые последствия. Если команда по оплате способна принять не более 80 новых заявок за период, средний вариант со 120 назначениями может оказаться неприемлемым даже при меньшей рассчитанной стоимости. Тогда ограничение по вместимости очереди надо добавить в критерий выбора.
Откуда берётся теоретический порог
Если p является хорошо откалиброванной вероятностью оплаты, можно сравнить ожидаемые затраты для одной заявки.
При отправке к специалисту ошибка возникает, когда заявка не об оплате. Вероятность этого события равна 1 − p:
Ожидаемая стоимость отправки = (1 − p) × C(FP).
Если не отправлять заявку, ошибка возникает, когда она действительно об оплате:
Ожидаемая стоимость пропуска = p × C(FN).
Отправлять выгоднее, когда стоимость отправки меньше стоимости пропуска:
(1 − p) × C(FP) < p × C(FN).
Перенесём слагаемые и получим условие для вероятности:
C(FP) < p × (C(FP) + C(FN)).
p > C(FP) / (C(FP) + C(FN)).
Для наших условных затрат:
p > 15 / (15 + 100) ≈ 0,13.
Это не универсальный порог 0,13. Вывод предполагает, что оценка модели действительно соответствует вероятности, стоимость каждой ошибки постоянна, а у команды нет ограничений по нагрузке. В реальной системе эти предпосылки проверяют отдельно, а рабочий порог подбирают на валидационных данных и затем оценивают на тесте.
Вывод раздела
- Порог выбирают на данных, которые разрешено использовать для настройки, а не на финальном тесте.
- Сравнивать пороги полезно через последствия ошибок и ограничения процесса.
- Теоретическая формула помогает понять направление выбора, но опирается на предпосылки о вероятностях и стоимости.
Можно ли понимать оценку модели как вероятность
Модель выдала для заявки число 0,8. Это ещё не доказывает, что обращение связано с оплатой с вероятностью 80%.
Калибровка означает следующее: среди большого числа случаев, которым модель присвоила оценку около 0,8, примерно 80% действительно должны относиться к оплате. Модель может хорошо расставлять заявки по порядку, но при этом систематически завышать оценки. Например, часто выдавать 0,8 там, где доля оплаты составляет лишь 0,5.
Для проверки заявки группируют по диапазонам оценок: от 0 до 0,1; от 0,1 до 0,2 и так далее. Для каждой группы сравнивают:
- Среднюю оценку модели.
- Фактическую долю обращений об оплате.
Если в группе со средней оценкой 0,8 фактическая доля составляет 0,5, прогнозы в этом диапазоне завышены. Такое сравнение называют калибровочной кривой. Подход и смысл вероятностных прогнозов описаны в документации scikit-learn по калибровке.
Есть и числовая оценка - показатель Брайера. Для каждой заявки берут разницу между прогнозируемой вероятностью и фактической меткой, возводят её в квадрат, затем усредняют по всем заявкам:
B = сумма значений (pᵢ − yᵢ)² по всем заявкам / N.
Здесь pᵢ - выданная вероятность для заявки с номером i, yᵢ - фактическая метка: 1 для оплаты и 0 для других тем, N - число заявок.
Если модель выдала 0,8 для действительно платёжной заявки, вклад в показатель равен (0,8 − 1)² = 0,04. Если она выдала 0,8 для заявки о доставке, вклад равен (0,8 − 0)² = 0,64. Чем меньше итоговое значение, тем лучше вероятностные прогнозы по этому критерию.
Однако показатель Брайера не стоит считать отдельной мерой только калибровки: на него влияет и способность модели различать классы. Для диагностики полезно смотреть его вместе с калибровочной кривой и метриками выбранного маршрута. Если нужна корректировка вероятностей, её обучают на данных, отделённых от финального теста.
Вывод раздела
- Оценка для класса и надёжная вероятность - разные вещи.
- Калибровка особенно важна, если порог выводят из стоимости ошибок или показывают сотруднику процент уверенности.
- Проверять нужно и порядок, в котором модель расставляет заявки, и смысл чисел, которые она выдаёт.
Что меняется, когда меняется поток обращений
Вернёмся к нашему тесту. Модель нашла 70% обращений об оплате. Среди остальных тем она ошибочно назвала оплатой 78 из 940 заявок:
Доля ложных срабатываний среди других тем = 78 / 940 ≈ 8,3%.
Теперь представим, что в новом потоке обращений об оплате стало меньше: не 6%, а 3%. Даже если способность модели находить оплату и доля ложных срабатываний остались прежними, precision изменится.
Обозначим:
π- доля обращений об оплате во всём потоке;TPR- доля найденных обращений об оплате, в нашем примере 70%;FPR- доля ложных срабатываний среди остальных тем, примерно 8,3%.
Тогда:
Precision = (TPR × π) / (TPR × π + FPR × (1 − π)).
В числителе находится ожидаемая доля правильно найденных обращений об оплате во всём потоке. В знаменателе - все заявки, которые попадут к специалисту: правильно найденные плюс ошибочно направленные.
Подставим TPR = 0,70, FPR ≈ 0,083, π = 0,03:
Precision ≈ (0,70 × 0,03) / (0,70 × 0,03 + 0,083 × 0,97) ≈ 20,7%.
На исходном тесте precision составляла 35%. При меньшей доле платёжных обращений она опустилась бы примерно до 21%, даже если условные характеристики модели не ухудшились.
Это объясняет, почему после запуска нельзя смотреть только на один сохранённый показатель. Нужно знать состав текущего потока и отслеживать, сколько заявок фактически получает каждая команда.
Есть и статистическая неопределённость. Наш recall 70% рассчитан всего по 60 обращениям об оплате. При грубой оценке стандартная ошибка доли равна:
SE ≈ √(r × (1 − r) / n).
Здесь r - измеренная полнота, n - число настоящих обращений об оплате. Подставим значения:
SE ≈ √(0,7 × 0,3 / 60) ≈ 0,059.
Приблизительный диапазон 0,70 ± 1,96 × 0,059 даёт значения около 58–82%. Это иллюстрация масштаба неопределённости, а не гарантия будущего качества. Для рабочего отчёта лучше рассчитывать подходящий доверительный интервал и отдельно учитывать повторные обращения одного инцидента.
Вывод раздела
- Precision зависит не только от модели, но и от доли нужного класса в потоке.
- Качество, измеренное по нескольким десяткам важных случаев, нельзя считать точным до десятых долей процента.
- Отчёт должен показывать количество примеров рядом с каждой метрикой.
Как проверить все темы, а не только оплату
До сих пор мы рассматривали решение «оплата или не оплата». Исходная модель распределяет обращения как минимум между оплатой, доставкой и доступом к аккаунту. Значит, нужна полная матрица ошибок по всем категориям.
В ней становится видно, какие именно темы путаются. Например, заявка «После оплаты не открывается подписка» может попадать то в оплату, то в доступ. Общая доля правильных ответов не покажет, что такая пара тем требует уточнения правил разметки или отдельного маршрута.
Для каждой категории можно повторить расчёт «эта тема против всех остальных». Затем показатели иногда усредняют:
- Macro average: сначала рассчитывают метрику для каждой темы, затем берут обычное среднее. Редкая тема влияет на результат так же, как частая.
- Weighted average: усредняют с учётом количества заявок каждой темы. Частые темы влияют сильнее.
- Micro average: складывают ошибки и правильные ответы всех категорий до расчёта метрики. В обычной многоклассовой классификации с одной меткой на заявку такой общий результат для precision и recall совпадает с accuracy.
Ни одно усреднение не заменяет отдельного отчёта по важной категории. Если ошибочная маршрутизация обращений об оплате особенно болезненна, её precision, recall, число пропусков и нагрузку на специалиста показывают отдельно.
Проверку стоит дополнить срезами: новые и постоянные клиенты, разные каналы поступления, короткие и длинные сообщения, периоды до и после изменения продукта. Цель не в том, чтобы получить множество красивых таблиц. Нужно обнаружить случаи, где общий показатель скрывает систематический сбой. При этом маленькие срезы дают нестабильные оценки: рядом с процентом обязательно указывают число заявок.
Практическая проверка обученной модели
Ниже - компактный пример для уже обученной модели из предыдущей главы. Предполагается, что:
modelобучена только на обучающей части;validиtestсодержат признаки изfeature_columnsи проверенную меткуreviewed_topic;- модель поддерживает
predict_proba; - значение метки для платёжных обращений -
"payment".
Код подбирает порог на валидации по условной стоимости ошибок и затем применяет его к тесту:
import numpy as np
from sklearn.metrics import confusion_matrix, precision_score, recall_score
payment_column = list(model.classes_).index("payment")
y_valid = valid["reviewed_topic"].eq("payment").to_numpy()
p_valid = model.predict_proba(valid[feature_columns])[:, payment_column]
cost_false_negative = 100
cost_false_positive = 15
def routing_cost(y_true, probabilities, threshold):
predicted_payment = probabilities >= threshold
false_negative = np.sum(y_true & ~predicted_payment)
false_positive = np.sum(~y_true & predicted_payment)
return (
cost_false_negative * false_negative
+ cost_false_positive * false_positive
)
thresholds = np.linspace(0, 1, 101)
costs = [
routing_cost(y_valid, p_valid, threshold)
for threshold in thresholds
]
chosen_threshold = thresholds[np.argmin(costs)]
y_test = test["reviewed_topic"].eq("payment").to_numpy()
p_test = model.predict_proba(test[feature_columns])[:, payment_column]
predicted_payment = p_test >= chosen_threshold
tn, fp, fn, tp = confusion_matrix(
y_test, predicted_payment, labels=[False, True]
).ravel()
print("Порог:", chosen_threshold)
print("TP, FN, FP, TN:", tp, fn, fp, tn)
print(
"Precision:",
precision_score(y_test, predicted_payment, zero_division=0)
)
print("Recall:", recall_score(y_test, predicted_payment))
print(
"Стоимость ошибок:",
routing_cost(y_test, p_test, chosen_threshold)
)
Здесь сетка из 101 порога выбрана для простоты примера. Для рабочего решения можно проверять пороги точнее, добавлять ограничение на число автоматически назначенных заявок и сравнивать несколько периодов. Если модель вообще не выделила положительных заявок, zero_division=0 позволит получить число в отчёте, но такой случай нужно отметить отдельно: precision здесь нельзя понимать как обычную долю правильно направленных заявок.
Важно также не подменять техническую проверку одной строкой вывода программы. После расчёта стоит вручную просмотреть выборку ошибок:
- Какие слова или шаблоны привели к ложному назначению оплаты?
- Какие настоящие обращения об оплате были пропущены?
- Совпадают ли ошибки с пограничными случаями разметки?
- Есть ли среди них новые типы заявок, которых не было в обучении?
Такой разбор часто указывает, что исправлять дальше: данные, правила разметки, признаки, модель или сам маршрут обработки.
Вывод раздела
- Преобразования, модель и порог должны выбираться без участия финального теста.
- Матрица ошибок и примеры отдельных заявок объясняют результат лучше, чем одна итоговая метрика.
- Проверочный код должен воспроизводить то же решение, которое будет принято при поступлении новой заявки.
Что проверять после запуска
Даже честный тест не обещает постоянного качества. Меняется продукт, появляются новые способы оплаты, обновляются тексты уведомлений, клиенты начинают по-другому описывать проблемы. Модель остаётся прежней, а поток заявок - нет.
После запуска полезно собирать два вида сигналов.
Быстрые сигналы, доступные почти сразу:
- доля заявок, которые модель направляет в каждую команду;
- распределение её оценок;
- число автоматических назначений и ручных перенаправлений;
- состав входящих обращений по каналам и периодам.
Сигналы качества, которые появляются после проверки человеком:
- фактическая тема заявки;
- TP, FN, FP и TN за период;
- precision, recall и стоимость ошибок;
- качество по важным категориям и срезам.
Здесь возникает новая ловушка. Если сотрудники внимательно проверяют только заявки, уже направленные моделью к специалисту по оплате, мы хорошо узнаем о ложных срабатываниях, но можем не увидеть пропущенные обращения в общей очереди. Оценка recall окажется неполной. Нужна проверка части обращений из обоих маршрутов по заранее определённому правилу.
При изменении качества сначала выясняют причину. Падение precision может объясняться меньшей долей платёжных заявок, изменением их формулировок, ошибками разметки или реальным ухудшением модели. Эти причины требуют разных действий. Менять порог после каждого колебания одной метрики опасно: можно улучшить один показатель и незаметно ухудшить другой.
Типичные сбои и способы их обнаружить
| Что наблюдаем | Возможная причина | Что проверить |
|---|---|---|
| Почти идеальный тест, заметно хуже после запуска | Повторы заявок между частями данных или признак из будущего | Разделение по времени и связанным обращениям, доступность каждого признака при поступлении |
| Высокая accuracy, нужные заявки часто пропускаются | Редкий важный класс | Матрицу ошибок, recall и сравнение с простым правилом |
| После снижения порога найдено больше нужных заявок, но очередь перегружена | Рост ложных назначений | FP, precision и число заявок на специалиста за период |
| Оценки 0,8 часто оказываются ошибочными | Плохая калибровка | Фактические доли по диапазонам оценок |
| Общая метрика стабильна, жалоб стало больше | Сбой в отдельной теме или срезе | Ошибки по категориям, каналам, новым типам обращений |
| Отчёт после запуска показывает только высокую точность | Проверяются преимущественно заявки выбранного маршрута | Как получают метки для пропущенных обращений |
| Качество на тесте «улучшалось» после каждого изменения | Тест использовали для подбора | Историю экспериментов и независимую финальную выборку |
Итог: что значит «модель проверена»
Для нашего примера проверка считается содержательной, если мы можем объяснить весь путь:
Новые обращения -> доступные при поступлении признаки -> оценка модели -> выбранный на валидации порог -> маршрут заявки -> позднее подтверждённая тема -> анализ ошибок.
На этом пути нужны ответы на несколько вопросов:
- Похожа ли тестовая выборка на будущие обращения и нет ли между частями данных связанных случаев?
- Сколько платёжных заявок модель находит, сколько пропускает и сколько чужих отправляет специалисту?
- Как выбран порог и какую нагрузку он создаёт?
- Насколько надёжны оценки модели, если мы используем их как вероятности?
- Достаточно ли примеров важной категории для уверенного вывода?
- Как мы узнаем о пропущенных заявках после запуска?
Модель проверена не тогда, когда у неё появилась высокая цифра в отчёте. Она проверена тогда, когда команда понимает условия получения этой цифры, виды ошибок и последствия конкретного решения, а также может заметить, когда эти условия изменились.