Машинное обучение сегодня на пике популярности — многие ИТ-решения создаются именно на его основе, иногда лишь формируя оболочку вокруг ключевой модели машинного обучения, призванной приносить бизнес-пользу. Качество таких решений зависит от того, как хорошо отлажены «модули» машинного обучения, однако подход к тестированию таких «модулей» отличается от классического подхода к тестированию традиционных аппаратно-программных конфигураций, допускающему фиксацию сценария тестирования с ожидаемым, детерминированным результатом. Модель обучилась чему-то новому и при работе может выдавать непредсказуемые результаты. В итоге потребитель систем на основе машинного обучения опасается доверять результатам, задавая справедливый вопрос: если завтра поступят новые данные и решение опять выдаст «что-нибудь эдакое»?

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

«Модулем» машинного обучения будем называть программный модуль, в основе которого находится любой алгоритм машинного обучения:

  • k-ближайших соседей;
  • случайный лес;
  • глубинное обучение нейронных сетей;
  • большие языковые модели.

Все эти алгоритмы объединяет то, что сначала модель обучается, а потом используется для решения конкретной задачи, поэтому для системного, риск-ориентированного подхода к тестированию следует разделить его на три уровня (см. рис.): алгоритм обучения; подготовка обучающей выборки и использование модели.

Уровни тестирования решений с машинным обучением

Уровни тестирования определяют последовательность отладки «модуля» машинного обучения с целью уменьшения трудоемкости поиска дефектов. Такое разделение относится именно к задаче тестирования — проектирование и разработка таких «модулей» выполняются в другой последовательности. Классическое проектирование выполняется «сверху вниз» — от потребителя ИТ-решения до поиска источников данных. Разработку также удобно выполнять «снизу вверх», в этом случае можно отталкиваться от результатов предыдущего этапа.

Тестирование на уровне алгоритма обучения

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

  • вот мы поэкспериментировали со структурой нейронной сети;
  • вот мы поэкспериментировали с функцией потерь;
  • получили модель с метрикой, на тестовой выборке, среднее относительное отклонение равно 10%.

В чем мы можем быть здесь уверены? Цикл обучения выжал максимум «знаний» из обучающей выборки? Нет. Оптимизация весов модели (функция потерь) выбрана корректно? Нет. Архитектура нейронной сети (полносвязанная, разреженная, сверточная, рекурентная) выбрана корректно? Нет.

Это все специализированные вопросы, которые стоят перед инженером, но правильная организация работы должна также донести уверенный ответ «Да» и до понимания заказчика. Вот несколько приемов, которые позволят убедить его в том, что цикл обучения модели реализован корректно.

  • Добавление тестового выхода модели. Можно добавить +1 тестовый выход модели, рассчитав его по простой формуле от некоторого входа (например, <тестовый выход = вход1 × 2>). Если модель сможет качественно предсказывать такой тестовый выход, то это будет понятным для заказчика индикатором того, что «модель ловит мышей». После наглядного доказательства этот выход можно отключить, чтобы модель не отвлекалась на него в ходе обучения.
  • Ведение бенчмарка моделей. Следует организовать таблицу бенчмарка версий моделей, в которой накапливать результаты экспериментов. Подключить к экспериментам пару ML-инженеров с разным проектным опытом и собрать результаты их экспериментов. Простой анализ этой таблицы позволит понять, что для задачи заказчика среднее относительное отклонение в 10% может быть очень хорошим результатом.
  • Ведение бенчмарка при переобучении модели. При переобучении следует сравнивать достигнутые метрики с историческими. Причем команду разработчиков должна насторожить не только деградация метрик, но и их резкое, ничем не обоснованное улучшение.
  • Калибровка пороговых значений классификации. Когда заказчику важно не пропустить критичный сигнал, следует изменить пороги, даже если придется обработать несколько «ложных срабатываний».
  • Иллюстрация результатов работы модели на «микроуровне». Значения метрик обычно слишком абстрактны для заказчика — больше уверенности придают наглядные иллюстрации работы модели на тестовой выборке (которая ранее была не известна модели). Одна иллюстрация того, как модель угадывает цель на экземплярах тестовой выборки, снимет опасения заказчика лучше, чем обширная аналитическая записка про достигнутые метрики качества модели.
  • Метрика «доля малых отклонений». В ходе постановки бизнес-задачи надо выяснить, какое отклонение в прогнозе можно считать хорошим (например, пять единиц в каждую сторону). Это отклонение назовем малым и подсчитаем долю (процент) малых отклонений на тестовой выборке, например, 87%. Для заказчика эта метрика будет наглядной, если ее интерпретировать, например, «5 единиц» — это размер мишени, а метрика — это доля попаданий в нее. Попадание в 87% мишеней — понятный и, возможно, приемлемый для бизнеса результат.

Тестирование на уровне подготовки обучающей выборки

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

Вот типичные ошибки при определении состава обучающей выборки.

  • Ошибочные проектные решения о том, какие именно факты следует включать в обучающую выборку. Например, при решении задачи прогнозирования выбора клиентом розничной сети конкретного товара на вход подаются данные о его текущем статусе, которые лишь косвенно связаны с принятыми ранее решениями клиента. В этом случае лучше не полениться и развернуть из статуса достоверную историю фактов о принятых клиентом решениях.
  • Включение в обучающую выборку свойств, которые были определены (изменены) уже после обучающего события. Например, есть соблазн включить в обучающую выборку все доступные на сегодня свойства клиента (объем сделанных им за всю историю заказов). На языке геймеров это можно назвать «читерством», на языке отцов геймеров «звонком из будущего». Такой самообман будет вскрыт на более позднем этапе проекта, когда в реальных условиях эксплуатации «идеальная модель» будет давать плохой результат.

Качество данных — «старая мозоль» при получении любой бизнес-пользы из данных, и обучение моделей не исключение. Основная ошибка тут — игнорирование проблемы качества данных, которые поступают в обучающую выборку: на вход подадим данные «как есть», а модель сама разберется и обучится. Такая позиция критично снижает способность модели обучиться на полезных входных данных, поэтому лучше предварительно предпринять легкие и понятные действия для повышения качества данных, поступающих для обучения модели: устранение выбросов, заполнение пропусков и исключение дубликатов.

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

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

  • С самого начала проекта стремитесь работать с реальными данными, которые в будущем будут подаваться на вход модели. Лучше узнать всю правду о данных как можно раньше.
  • Выполните предварительное профилирование входных данных, посмотрите, что действительно они из себя представляют. Часто бывает, что заказчик сам находится в заблуждении относительно качества доступных данных и только профилирование может дать объективную оценку пригодности данных для обучения модели.
  • При подготовке данных выполните элементарную дедубликацию классификаторов. Если обучающая выборка содержит данные за много лет, то, вероятно, эти данные накапливались в различных ИТ-системах, вводились и обрабатывались разными людьми. Например, если модель будет одинаково воспринимать категорию VIP-клиентов, вне зависимости от написания («ВИП», «VIP», «VIP-клиент», …), то это поможет модели выявить зависимости и связи, критичные для качественного прогноза.
  • Прежде чем фиксировать состав данных, подаваемых на вход обучения, проведите обследование процессов обновления источников данных. Возможно, будет достаточно изучить документацию систем-источников и каталог данных хранилища. Но если изучать нечего, то следует провести интервью с ответственными за данные и с ИТ-специалистами, поддерживающими системы-источники. Убедитесь, что каждое свойство, которое планируется подать на вход модели, содержит именно ту версию, которая была актуальна на момент обучающего события.
  • После получения версии обученной модели проанализируйте, какие входы больше всего влияют на прогноз. Если результат работы модели во многом зависит от одного входа, то следует тщательно проверить подозрение — может, этот вход является «звонком из будущего». Некоторые методы и библиотеки (например, Random forest и CatBoost) имеют встроенные инструменты выявления «самых важных входов». Для остальных моделей, в том числе для нейронных сетей, можно использовать метод SHAP (Shapley Additive Explanations), который дает числовую оценку вклада каждого входа.
  • Если на вход модели подаются подготовленные векторы (результаты эмбендинга — преобразования абстракции в набор чисел и векторов), то необходимо убедиться — явно протестировать, что эмбендинг близко располагает объекты, которые похожи именно для решаемой задачи. Например, если для задачи важен класс клиента, но в результате эмбендинга VIP-клиент и клиент из розницы располагаются рядом, то надо улучшить преобразование, возможно, обучить его с ориентацией на критичные признаки.

Тестирование на уровне использования модели

Основной риск, который здесь отрабатывается, — убедиться, что модель используется правильно. Надо стремиться выявить большинство дефектов на предыдущих уровнях, что похоже на модульное тестирование (unit test), а данный уровень больше напоминает комплексное, затратное сквозное тестирование (end-to-end test). Здесь также можно выделить два класса дефектов: некорректный запуск модели и некорректная интерпретация результатов работы модели. Иначе говоря, при тестировании для первого класса мы гарантируем, что модель развернута корректно, с необходимыми параметрами работы и данные на вход модели подготовлены корректно, в том числе оцифровка входных данных выполнена по спецификации «как при обучении».

Второй класс тестирования ориентирован на бизнес-анализ и сценарий использования результатов работы модели. Здесь надо убедиться, что исходящие интеграции отрабатывают корректно и результаты работы модели правильно интерпретируются «принимающей стороной».

Практические рекомендации для данного уровня тестирования таковы.

Убедитесь, что изначальная бизнес-задача не искажена в ходе решения. Вспомните формулировки изначального ТЗ и, глядя на результат работы модели, ответьте на вопрос: именно ли это требуется заказчику?

Обсудите с заказчиком достигнутые метрики качества работы модели. Например, средняя ошибка выхода в 20 единиц означает, что результат работы модели будет «ну где-то от 0 до 40» (причем слово «средняя» не означает «максимальная»). Метрики могут быть неприемлемыми для решаемой бизнес-задачи, и при встраивании такой модели в бизнес-процесс от нее будет больше вреда, чем пользы.

Проведите сквозной тест использования модели по аналогии с «тестовой эксплуатацией» на реальных данных. Загляните к принимающей стороне — будь то пользователь или ИТ-система. Проведите интервью с принимающей стороной, убедитесь, что имеется одинаковое понимание результатов работы модели.

Единое понимание уровней тестирования «модулей» машинного обучения улучшит взаимопонимание между заказчиком и подрядчиком, и если «на берегу» удастся зафиксировать уровни тестирования и ответственность, то это станет прочным фундаментом успешного выполнения проекта.

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

***

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

Виталий Когтев (VKogtev@mail.ru) — эксперт по управлению данными, CDMP, компания «Нейросетевые технологии» (Санкт-Петербург).