Тестирование систем машинного обучения (ML) — сложная и малоосвещённая тема. В отличие от классического ПО, ML-системы работают на основе вероятностных моделей и данных, а не жёстких правил. Это вносит свои особенности и вызывает ряд уникальных трудностей. В этой статье — разбор типичных проблем, подходов к тестированию и реальных кейсов из практики.
Кратко о проекте
Работаем над системой автозаказа для сети супермаркетов Spar. Задача — точно рассчитывать объёмы заказов, чтобы товара хватало, но не было излишков. Система учитывает десятки факторов: сезонность, погоду, праздники, календарные события. Например, перед 1 сентября растёт спрос на цветы — модель это учитывает и корректирует поставки.
Почему тестирование ML сложнее обычного
- Вероятностное поведение вместо детерминизма. В классическом ПО одинаковые входные данные всегда дают одинаковый результат. В ML система выдаёт прогноз с определённой вероятностью. Поэтому тестирование сводится не к проверке точного ответа, а к оценке качества прогноза и допустимых отклонений.
- Фокус смещается с кода на данные. Даже самая продвинутая модель даст плохой результат на некачественных данных. Проверка датасетов — критически важная часть тестирования.
- Устаревание модели (model drift). Модель обучается на прошлых данных, но реальность меняется. Появляются новые товары, меняются привычки покупателей. Если не мониторить и не дообучать модель, её точность будет падать.
- Контекст и цена ошибки. Ошибка в 10% для жевательной резинки — не критично. Та же ошибка для дорогого товара — может обернуться серьёзными убытками. Тестирование должно учитывать бизнес-последствия.
- Новые типы ошибок. Появляются проблемы с данными: аномалии, сбои в интеграциях, некорректные источники. Такие ошибки сложнее обнаружить, чем баги в логике кода.
Тестирование ML на этапах разработки
Анализ требований
В классическом тестировании требования чёткие: «сделай X, получи Y». В ML заказчик говорит: «улучшите прогноз». Но как измерить «улучшение»?
Мы вводим метрики:
- Технические — насколько прогноз отличается от факта.
- Бизнес-метрики — влияние отклонения на прибыль и продажи.
Также договариваемся о допустимых отклонениях. Например, прогноз спроса на шоколад может отличаться от реальных продаж не более чем на 10%.
Планирование тестирования
Ожидаемый результат в ML — не конкретное число, а диапазон. Например, прогноз должен попадать в ±10% от факта.
Тестируем и аномальные данные: например, когда компания скупила всё мясо для корпоратива. Такие события нужно отфильтровывать, чтобы они не искажали общий прогноз.
Настройка окружения и подготовка данных
Модели чувствительны к версиям библиотек. Даже небольшое изменение может повлиять на результат. Мы используем Docker, чтобы фиксировать окружение.
Персональные данные защищаем через хэширование: видим продажи, но не можем привязать их к покупателям.
Контролируем дрейф данных: если реальные данные начинают отличаться от обучающих, точность модели падает. Нужно вовремя замечать это и дообучать модель.
Выполнение тестов
Тестирование осложняется отсутствием точного ожидаемого результата. Опираемся на метрики и диапазоны.
Важно тестировать по категориям. Например, модель может хорошо прогнозировать спрос на хлеб, но плохо — на соусы. Поэтому проверяем не только «в среднем», но и по конкретным группам товаров.
Тестируем на выборке: наборе разнообразных магазинов. Это быстрее, чем тестировать всё, но даёт представление о качестве.
Помимо модели, проверяем:
- Дрейф данных — когда входные данные уходят от обучающих.
- Системные баги — например, сбой в передаче данных о продажах. Даже если модель работает, без данных прогноз не будет готов.
Регрессия
После обновления модель может улучшить одну метрику, но ухудшить другую. Важно анализировать такие случаи: критично ли падение?
Иногда новая модель перестаёт справляться с задачами, которые решала старая. Чтобы избежать этого, сохраняем тесты для ключевых сценариев и проверяем их при каждом релизе.
ML-тестирование: шеф-повар, а не повар
Тестирование обычного ПО — как следование рецепту: всё расписано, результат предсказуем. Тестировщик проверяет, что всё сделано по инструкции.
ML-тестирование больше похоже на работу шеф-повара: нет точного рецепта, результат может варьироваться, нужно «пробовать на вкус». Тестировщик оценивает качество, предлагает корректировки и решает, готова ли модель к работе.
Преимущества ML-тестирования
- Полноценное A/B-тестирование. Новую модель можно запустить параллельно со старой и сравнить в реальных условиях.
- Реалистичные данные. Тесты проводятся на данных, близких к продакшену, что позволяет выявить проблемы до релиза.
- Контроль через метрики. Ухудшение качества сразу заметно — можно оперативно дообучить модель.
- Больше данных — больше сценариев. Возможность проверить поведение модели в разных условиях.
- Проверка устойчивости. Можно моделировать сезонность, аномалии и изменения спроса, чтобы заранее выявить слабые места.
Реальные факапы
- Грузовик молочки. Из-за путаницы в параметрах prediction_share и predict_share система выдала завышенный прогноз по молочным продуктам. В магазины приехало избыточное количество творога, сметаны и масла. Пришлось распродавать со скидками. Проблему можно было предотвратить, если бы аномалия была замечена на этапе тестирования.
- Недопрогноз лавашей. После обновления модель перестала учитывать выходные пики спроса на лаваш. Продажи небольшие, поэтому проблему заметили поздно. Покупатели приходили за лавашем, а его не было. Кейс показал важность детального тестирования по всем категориям, даже с низким объёмом продаж.
- Модель не узнала 2025 год. Из-за ошибки в кодировке параметра year модель не распознала начало нового года. Прогнозы стали некорректными. Система аномалий тоже не сработала. Пришлось срочно вручную корректировать заказы. Урок: нужно тестировать модель на будущих данных и проверять работу системы обнаружения аномалий.