Несколько меток у документа: почему accuracy скрывает пропущенные темы
Обращение клиента одновременно касается доставки и возврата. Классификатор нашёл доставку, и оператор получил часть нужного маршрута. Считать такой ответ полностью правильным нельзя: возврат останется без обработки. Но и приравнивать его к совершенно чужой теме иногда неудобно — тогда теряется информация о том, что уже работает.
Когда объекту разрешено иметь несколько меток, задача называется multilabel-классификацией. Её стоит отличать от выбора одного класса из нескольких. В ответе хранится набор тем или отдельное решение для каждой темы. Поэтому слово accuracy без уточнения способа расчёта легко вводит команду в заблуждение.
Согласуем, что является завершённой работой
Начните с действия после классификации. Если система должна создать все нужные задачи, важна полнота комплекта меток. Пропуск одной темы означает незавершённую обработку. Если модель лишь предлагает сотруднику несколько тегов, частичное совпадение тоже полезно. Один и тот же прогноз получает разную прикладную оценку в этих сценариях.
Для полной автоматизации удобно считать долю документов, где набор меток совпал целиком: subset accuracy. Для диагностики добавьте пропущенные и лишние метки. Пропуски означают потерянные действия, лишние метки создают ненужные очереди. Дальше эти два вида ошибок можно перевести в затраты отдела.
Распространённая ловушка — доля правильных ответов по всем парам «документ — возможная тема». Большинство тем обычно отсутствует. Модель может отвечать «нет» почти везде и получать высокий процент за огромное число верных отрицаний. В поиске обязательных действий такой результат мало помогает.
Проверим маленькую очередь вручную и кодом
В примере четыре обращения и пять возможных тем. Модель не обучается заново: сравниваются уже полученные наборы с эталоном. Дополнительно вычислим micro precision и recall по положительным меткам. Здесь micro означает, что все найденные, пропущенные и лишние темы суммируются перед делением.
truth = [
{'delivery', 'return'}, {'payment'},
{'warranty'}, {'delivery', 'payment'},
]
pred = [
{'delivery'}, {'payment'},
set(), {'delivery', 'payment', 'return'},
]
labels = {'delivery', 'return', 'payment', 'warranty', 'account'}
assert all(s <= labels for s in truth+pred)
tp = sum(len(t & p) for t, p in zip(truth, pred))
fp = sum(len(p-t) for t, p in zip(truth, pred))
fn = sum(len(t-p) for t, p in zip(truth, pred))
exact = sum(t == p for t, p in zip(truth, pred))/len(truth)
binary_accuracy = 1-(fp+fn)/(len(truth)*len(labels))
precision = tp/(tp+fp) if tp+fp else None
recall = tp/(tp+fn) if tp+fn else None
print('exact', exact, 'binary_accuracy', binary_accuracy)
print('micro_precision', precision, 'micro_recall', recall)
for i, (t, p) in enumerate(zip(truth, pred), 1):
print(i, 'missing', sorted(t-p), 'extra', sorted(p-t))
assert (tp, fp, fn) == (4, 1, 2)
assert exact == .25 and binary_accuracy == .85По бинарным решениям получаем 85% правильных ответов, а полностью завершено только одно обращение из четырёх. Есть четыре найденные истинные метки, одна лишняя и две пропущенные. Micro precision равна 0,8, micro recall — примерно 0,667. Эти числа объясняют разные стороны работы и не заменяют друг друга.
Для третьего обращения модель вернула пустой набор. Если пустой ответ разрешён продуктом, он должен вести в понятное состояние: например, на ручное определение тем. Нельзя молча считать его отсутствием проблем. Если обращение может действительно не относиться ни к одной теме, такие случаи необходимо включить и в разметку, и в проверку.
От общего результата к конкретной теме
Теперь посчитайте precision и recall отдельно для доставки, возврата и остальных тем. Частая доставка способна доминировать в micro-оценке, пока гарантийные обращения почти не распознаются. Для каждой темы выводите число истинных примеров. Высокий процент по двум документам требует другого решения, чем тот же процент по нескольким тысячам.
Если важна одинаковая роль всех тем, добавьте macro-оценку, усредняющую результаты тем. Заранее определите, что делать с темой, у которой нет положительных примеров в тесте. Не скрывайте её под нулём или единицей. Отсутствие примеров означает, что этот набор данных не даёт нужной проверки.
Порог выбора метки можно настроить отдельно для каждой темы на валидационных данных. У возврата может быть высокая цена пропуска, у рекламной категории — высокая цена лишнего тега. После настройки зафиксируйте пороги и проверьте полный набор действий на отдельном тесте. Выбор порогов непосредственно по тесту сделает итог оптимистичным.
В справке по accuracy_score для multilabel используется именно полное совпадение набора. Если переносите отчёт между библиотеками или собственным SQL, запишите формулу и знаменатель: одинаковое название ещё не обеспечивает одинаковый смысл.
Как собрать понятный отчёт приёмки
Покажите заказчику долю обращений с полным комплектом, количество пропущенных действий и лишних задач. Рядом дайте несколько документов с различными видами ошибок. Тогда понятна следующая работа: уточнить границы тем, добавить сложные сочетания в обучение или изменить пороги конкретных действий.
Проверьте и сочетания меток. По отдельности доставка и возврат могут распознаваться хорошо, а вместе — хуже из-за короткого текста или обрезания документа. Сравните качество однотемных и многотемных обращений. Это помогает обнаружить ограничение входа, которое не видно в таблице средних результатов по классам.
Для дальнейшей работы с данными и оценкой подходит платный курс «ML Engineer / Data Scientist: табличные модели в продакшн»: в программе есть корректная валидация, сравнение моделей и разбор ошибок, затем batch-инференс и REST API. Откройте программу курса, чтобы научиться связывать метрику с решением пользователя и сохранять это правило в общем pipeline.
Продолжить на практике
- ML Engineer / Data Scientist: табличные модели в продакшн ↗
Практический курс для тех, кто хочет получить навыки ML Engineer / Data Scientist на реальных табличных задачах. В курсе Вы не просто обучите CatBoost/LightGBM, а соберёте полноценный production-style пайплайн: подготовка данных, feature engineering (генерация признаков), корректная валидация, защита от leakage (утечек), тюнинг через Optuna, интерпретация через SHAP, batch-инференс и REST API для предсказаний.
