Привет, Хаброжители! Мы хотим поделиться с вами главой из книги «Машинное обучение. Проектирование систем от идеи до реализации» Валерия Бабушкина и Арсения Кравченко. Это подробное пошаговое руководство, призванное помочь вам на всех этапах разработки ML-системы: от сбора информации и выполнения предварительных шагов до разработки, запуска в эксплуатацию и последующего сопровождения.
Как следует из названия, книга посвящена именно проектированию ML-систем. Мы не сосредоточиваемся на какой-то одной технологии, а предлагаем универсальный фреймворк для решения задач, связанных с созданием, сопровождением и совершенствованием ML-систем различного масштаба и сложности.
Подготовка датасета
Опытные инженеры, работающие с данными, знают, что в подавляющем большинстве случаев данные в их исходном виде слишком «сырые» для эффективного использования. Отсюда и название — «сырые данные», то есть хаотично собранная, неорганизованная масса информации. Сырые датасеты редко бывают в таком состоянии, чтобы их можно было сразу использовать. Необходимо сначала их «приготовить», а уже потом вводить в вашу ML‑систему.
Мы собрали список техник, которые вы можете использовать для подготовки датасета, каждая из которых представлена в отдельном подразделе. Этот список не имеет строгой последовательности, и порядок действий может варьироваться в зависимости от вашей предметной области, поэтому не существует какого-то одного универсального ответа. В некоторых случаях невозможно отфильтровать данные до их разметки, в других — фильтрация может проводиться несколько раз. Давайте кратко рассмотрим эти техники.
ETL
ETL расшифровывается как «extract, transform, load» (извлечение, преобразование, загрузка) и представляет собой этап подготовки данных, на котором происходит получение информации из внешнего источника и преобразование ее структуры в соответствии с вашими потребностями. В качестве упрощенного примера: вы можете получить JSON-файлы из стороннего API и сохранить их в локальное хранилище в формате CSV или Parquet.
ПРИМЕЧАНИЕ Основная цель ETL — решить проблему доступности данных.
Доступность данных на этом этапе означает следующее:
Данные можно легко и эффективно извлекать для процесса обучения модели (например, если целевой датасет является результатом взаимодействия нескольких источников, необходимо понять, как сделать его доступным с помощью одного клика, командой или вызовом).
Данные будут доступны как на этапе обучения, так и на этапе выполнения. Нас пока не волнует, насколько эффективно происходит извлечение данных для инференса (мы обсудим это позже, в главе 11), но мы должны гарантировать, что те же источники данных будут доступны и для инференса.
ПРИМЕЧАНИЕ Проектирование эффективного ETL-процесса — это своего рода искусство, поскольку оно требует знания различных хранилищ данных и инструментов их обработки. В нашей книге мы лишь поверхностно касаемся этой темы и рекомендуем обратиться к другим источникам для более глубокого изучения.
Важный вопрос, который возникает на данном этапе: «Стоит ли уже сейчас задумываться о структуре и хранилище данных?» Ответ на этот вопрос зависит от следующих моментов:
Иногда датасеты небольшие, и вероятность их внезапного увеличения в несколько раз крайне мала. Это означает, что вы можете выбрать практически любое хранилище (например, то, которое уже активно используется в вашей компании, или то, с которым вы привыкли работать). Вы удивитесь, насколько часто неопытные ML‑инженеры склонны чрезмерно усложнять ситуацию, разрабатывая распределенное многокластерное хранилище для статического табличного датасета с тысячами строк и десятками столбцов.
Иногда с самого начала очевидно, что ваш датасет будет огромным и будет быстро расти, поэтому при проектировании модели данных следует уделить этому особое внимание. Мы не являемся экспертами в данной сфере, а поэтому рекомендуем ознакомиться с другими книгами, если этот вопрос актуален для вашей системы. Нам больше всего нравится «Designing Data-Intensive Applications» Мартина Клеппмана (Martin Kleppman).
Фильтрация
Ни один источник данных не бывает совершенно идеальным. Под идеальностью мы понимаем чистоту, согласованность и релевантность вашей задаче. В небольшой истории в начале этой главы мы упомянули API, предоставляющие спутниковые изображения, но компании были нужны только те из них, на которых не было слишком много облаков и которые отображали сельскохозяйственные районы; в противном случае хранение нерелевантных данных значительно увеличило бы издержки. Это означало, что большая часть предварительной работы по отбору подходящих спутниковых снимков должна была быть выполнена на самых первых этапах проекта.
Фильтрация данных — это операция, строго зависящая от предметной области. В одних случаях ее можно полностью автоматизировать с использованием набора правил или статистических методов; в других же требуется участие человека. Практика показывает, что итоговый подход, как правило, находится где-то посередине между этими двумя крайностями. Наилучший результат дает комбинация человеческого вклада и автоматических процессов. Распространен следующий алгоритм: просматривается подмножество данных (случайным образом или на основе предварительных наблюдений или обратной связи), выявляются закономерности, которые затем отражаются в коде для расширения охвата, после чего анализируется уже более узкое подмножество.
Отсутствие фильтрации данных приводит к значительному шуму в датасете и, как следствие, к снижению производительности всей системы. Однако чрезмерно строгая фильтрация также может оказать негативное влияние — она способна исказить распределение данных, что ухудшит работу модели на реальных данных.
Генерация признаков
Генерация признаков означает преобразование представления данных таким образом, чтобы оно стало максимально ценным для ML-алгоритма. Мы подробно рассмотрим эту тему позже, когда речь пойдет о промежуточных этапах работы, поскольку на ранних стадиях проектирования ML-систем ей редко уделяется достаточное внимание. На текущем этапе мы, как правило, сосредоточиваемся на том, как получить исходные данные для построения базовой модели (baseline), что требует определенного уровня абстракции.
Иногда признаки создаются не вручную, а с помощью более сложной модели; в отличие от «обычных» признаков, они могут представлять собой векторы, не интерпретируемые человеком. В таких случаях точнее использовать термин «представления», хотя в каком-то смысле это одно и то же — входные данные для ML‑модели.
Например, в крупной компании, ориентированной на ML, может существовать основная команда, создающая модель, генерирующую наилучшие представления пользователей, товаров или чего-либо другого. Эта модель не решает бизнес-задачи напрямую, но прикладные команды могут использовать ее для создания представлений под свои конкретные нужды. Подобный подход распространен при работе с изображениями, видео, текстами или аудио.
Разметка
Сам по себе датасет зачастую не представляет особой ценности, но добавление дополнительных аннотаций, известных в сфере машинного обучения как метки, может кардинально изменить ситуацию. Определение того, какие именно метки следует использовать, крайне важно, так как это влияет на множество последующих решений.
Представим, что вы разрабатываете медицинскую систему, помогающую рентгенологам анализировать снимки пациентов. Это одно из самых известных применений ML в медицине, которое по-прежнему крайне сложно правильно спроектировать. Казалось бы, задача проста: врач смотрит на снимок и определяет наличие злокачественного образования, так что вам нужно, чтобы врачи разметили датасет.
Существует множество способов такой разметки (рис. 6.2), в том числе:
Бинарная классификация — есть ли на снимке злокачественное образование?
Многоклассовая классификация — какой тип злокачественного образования на снимке, если таковое имеется?
Детекция — какая область снимка содержит злокачественное образование, если таковое имеется?
Сегментация — какие именно пиксели изображения представляют злокачественное образование, если таковое имеется?

Эти способы разметки данных требуют разных инструментов аннотирования и различной квалификации от команды разметчиков. Кроме того, они различаются по временным затратам. Метод разметки влияет на выбор модели для решения проблемы и, что особенно важно, определяет ограничения продукта. Принять правильное решение на данном этапе невозможно без выполнения шагов, описанных в главе 2, и сбора достаточной информации о целях и требованиях продукта.
В некоторых случаях разметка данных с нужным уровнем детализации оказывается практически невозможной. Например, на это может потребоваться слишком много времени, недостаточно специалистов для охвата необходимого объема данных либо инструменты для разметки еще не готовы. В таких случаях стоит рассмотреть использование методов слабоконтролируемого обучения (weakly supervised learning), которые допускают использование неточных или частичных меток. Если вы не знакомы с этой стороной машинного обучения, рекомендуем прочитать «A Brief Introduction to Weakly Supervised Learning» (https://mng.bz/75My), а дополнительные материалы можно найти в подборке «Awesome-Weak-Supervision» (https://mng.bz/mRp2).
Эффективная разметка данных требует выбора подходящей платформы, грамотной декомпозиции задач, четких и понятных инструкций, удобных пользовательских интерфейсов, методов контроля качества, обзора способов агрегирования и анализа стоимости. Кроме того, необходимо соблюдать лучшие практики при создании инструкций и интерфейсов, настройке различных типов шаблонов, обучении и проверке исполнителей, а также построении пайплайнов для оценки процесса разметки.
Когда данные необходимо разметить вручную, существуют два основных подхода: внутренняя команда разметки или использование сторонних краудсорсинговых сервисов. Первый подход обеспечивает более контролируемый и стабильный процесс разметки, в то время как второй позволяет ускорить процесс, зачастую с меньшими затратами. Выбор между ними зависит от сложности разметки: если она требует специализированных знаний или навыков, стоит сформировать собственную команду опытных специалистов; если же нет, то можно использовать и сторонний сервис.
Существует множество краудсорсинговых платформ, наиболее популярной, скорее всего, является Amazon Mechanical Turk. Поскольку в этой книге мы делаем акцент на широте охвата, а не на глубине, мы не будем подробно рассматривать особенности разных платформ. Вместо этого сосредоточимся на общих характеристиках краудсорсинговой разметки:
Разметчики склонны к ошибкам даже в самых простых заданиях, например при бинарной классификации обычных объектов. Большинство разметчиков работают одновременно с несколькими заказчиками, поэтому они вряд ли запомнят все нюансы ваших инструкций. Следовательно, резметчики должны быть взаимозаменяемыми, а инструкции — максимально простыми и однозначными.
Некоторые разметчики более внимательны, чем другие; вы можете замотивировать их уделять больше времени вашим задачам, чем остальным проектам. Другие могут быть менее внимательными или даже работать недобросовестно, например пользоваться ботами, генерирующими непроверенные метки, вместо того чтобы полагаться на собственное суждение. Крайне важно уметь отличать первых от вторых. Наиболее распространенный способ это сделать — включить в процесс разметки тесты. Возьмите ту часть датасета, метки которой вам точно известны, и используйте ее в заданиях на разметку, чтобы установить точность каждого конкретного разметчика. Также можно вести логирование определенных аспектов процесса разметки для получения более полной картины. Например, если метки генерируются слишком быстро, это может быть сигналом о том, что исполнитель использует бот или другой запрещенный инструмент автоматизации.
Задание на разметку должно быть сформулировано таким образом, чтобы минимизировать вариативность, вызванную участием краудсорс-работников. Рассмотрим следующую ситуацию: компания разрабатывает чат-бота и нанимает разметчиков для оценки его ответов (вопросы и несколько возможных вариантов ответа). Наиболее очевидный способ оценки — попросить разметчиков присвоить каждому ответу числовую оценку (например, от 1 до 5). Однако такие метки могут быть непоследовательными, поэтому лучше ввести несколько критериев оценки, чтобы каждый ответ оценивался отдельно: по фактической корректности, стилю высказывания и т. д. Такие метки будут более последовательными, хотя все еще далекими от идеала. Еще одно возможное улучшение — использование парного сравнения. Вместо присваивания числовой оценки каждому ответу разметчики выполняют тройное сравнение на основе критериев (версия A лучше / версия B лучше / A и B равны). Такие метки легче собирать, и ожидаемая вариативность между разметчиками будет ниже.
В XVIII веке французский математик и философ маркиз де Кондорсе (Marquis de Condorcet) сформулировал теорему, применяемую в политической науке. Де Кондорсе высказал следующую идею: если группе необходимо принять бинарное решение на основе большинства голосов и каждый член группы принимает правильное решение с вероятностью p > 0.5, то вероятность правильного коллективного решения возрастает с увеличением числа участников, асимптотически приближаясь к единице. Это стало обоснованием коллективного принятия решений в ранний период Французской революции — и та же логика применима к ML‑системам!
Представим, что у нас есть три исполнителя, размечающих один и тот же объект для задачи бинарной классификации. Задача сложная, поэтому каждый из них прав только в 70 % случаев. Тогда можно ожидать, что результат выбора большинства из трех разметчиков будет правильным в 0.7*0.7*0.7+0.3*0.7*0.7+0.7*0.3*0.7+0.7*0.7*0.3 = 78.4 % случаев. Неплохая точность!
Однако к этим числам стоит относиться с долей скепсиса. Теорема де Кондорсе предполагает выполнение ряда условий, которые здесь не соблюдаются: разметчики не являются полностью независимыми, и источники их ошибок могут быть взаимосвязаны (например, если семплы шумные и трудны для восприятия). Тем не менее группа разметчиков дает более точные результаты по сравнению с одним исполнителем, что может быть использовано для улучшения качества разметки.
В целях снижения затрат данную идею можно немного преобразовать. Один из известных нам вариантов алгоритма выглядит следующим образом:
Объект размечается двумя разметчиками.
Если они согласны, метка принимается.
Если нет — добавляются еще три голоса, и итоговая метка определяется по большинству голосов.
Таким образом, больше голосов используется для сложных, неоднозначных семплов, в то время как для простых случаев требуется меньше голосов.
Данная идея проста, но весьма эффективна. Однако если разметка данных является ключевым элементом вашей проблемы и вы хотите вложить в нее дополнительные усилия, существует множество научных исследований, посвященных улучшению дизайна разметки. Мы порекомендуем «A Survey on Task Assignment in Crowdsourcing» (https://arxiv.org/abs/2111.08501) и обучающий курс от краудсорсинговой платформы Toloka.ai (https://toloka.ai/events/tutorial-wsdm/).
Постоянство и взаимное согласие разметчиков можно и нужно измерять. Специалисты в области ML зачастую стремятся использовать стандартные метрики для оценки данных показателей, однако те, кто имеет опыт работы со статистикой, знакомы с концепцией, известной как межоценочная надежность (interrater reliability), и соответствующим ей набором метрик (в числе которых — каппа Коэна, пи Скотта, альфа Криппендорфа и др.). Данные метрики позволяют обеспечить надежность работы команды разметки, отфильтровать недобросовестные метки (тем самым значительно повышая общую эффективность системы) и в отдельных случаях предоставляют верхнюю границу возможной производительности модели (вспомним упомянутый ранее в главе 3 стандартный уровень производительности).
Для эффективной работы команды разметки необходим соответствующий инструментарий, который может повысить эффективность и улучшить качество меток. Если вы используете сторонний ресурс, он, скорее всего, уже будет включать инструментарий для наиболее распространенных задач; при работе с собственной командой потребуется настроить или разработать такие инструменты самостоятельно. Выбор между готовым решением и созданием собственного сильно зависит от конкретной предметной области, однако в целом действует следующее правило: чем более распространена ваша проблема, тем выше вероятность найти современный и качественный инструментарий для команды разметки. Например, существует множество программных решений для разметки изображений в рамках задач детектирования, но если вам потребуется разметить видео с помощью 3D-полигональной сетки, скорее всего, придется разработать собственное решение.
Последние достижения в области крупных базовых моделей стали поворотным моментом и в процессе разметки — они могут использоваться для получения начальных меток во few-shot-сценариях с точностью, превышающей результаты разметчиков-неэкспертов. Один из многочисленных инструментов, применяемых для разметки с помощью LLM, — это Refuel Docs (https://docs.refuel.ai/), ориентированный на работу с текстовыми данными. Однако базовые модели могут использоваться и в других сферах, например в универсальных моделях сегментации, таких как Segment Anything (https://segment-anything.com/), или в мультимодальных решениях вроде LLaVA (https://llava-vl.github.io/).
Существует множество алгоритмов, позволяющих упростить процесс разметки данных в рамках построения системы, однако в этой книге мы не будем подробно их рассматривать, так как выбор сильно зависит от конкретной задачи. Тем не менее мы хотим подчеркнуть, что вложенные в процесс разметки данных и соответствующие инструменты усилия зачастую определяют успех вашей ML-системы.
Данные и метаданные
Хотя именно датасеты используются для построения ML-системы, над ними существует дополнительный уровень информации — назовем его метаданными. Метаданные — это информация, описывающая определенные характеристики ваших датасетов. Например:
временные атрибуты — включают информацию о том, когда произошло событие, когда оно было обработано и когда сохранено;
атрибуты источника — указывают, собираются ли данные из нескольких источников;
атрибуты пользователя — если пользователь каким-либо образом участвует в генерации датасета (а это не редкость), его метаданные становятся частью связанных с ним семплов;
версии — если данные уже обработаны, полезно знать, какая версия программного обеспечения использовалась при обработке.
Метаданные играют ключевую роль в управлении потоками данных и обеспечении их согласованности. Вернемся к предыдущему примеру с медицинским приложением. Представим, что компания наняла 10 специалистов-медиков с целью разметки данных для вашей системы. После более чем года работы они наконец разметили большой датасет. Внезапно приходит электронное письмо: один из разметчиков оказался мошенником, его диплом — подделка, а лицензия приостановлена. Такая ситуация недопустима, поскольку значительная часть данных становится ненадежной, что ставит под угрозу весь датасет. Единственно разумное решение в данном случае — немедленно прекратить использование его меток в модели. И хотя такой пример может показаться немного утрированным, в вашей системе со временем обязательно возникнут десятки менее критичных, но все же значимых проблем. Проблемы с источниками данных, регуляторные вмешательства и попытки интерпретировать ошибки модели заставят вас обратиться к метаданным.
Как мы уже обсуждали ранее, несмотря на то что существуют разные способы «приготовления» датасетов, в процессе работы вы наверняка выявите какие-то новые аспекты проблемы и, соответственно, будете корректировать структуру датасета, внося в него определенные изменения, которые и найдут свое отражение в метаданных.
Другим источником изменений может стать тестирование и исправление ошибок. Допустим, вы работаете в агрегаторе такси и решаете задачу оценки времени, необходимого для того, чтобы доехать из точки A в точку B. Вы начинаете с исторических данных компании, которые предварительно обрабатываются, — информация извлекается из логов и сохраняется в выбранную вами базу данных, в результате чего вы получаете следующую таблицу: latitude_from, longitude_from, datetime_start, datetime_finish, distance, data_source.
В какой-то момент компания поглощает своего крупного конкурента, и вы решаете включить его данные в ваш ETL-процесс. Новый инженер в команде начинает писать код, подключаются новые источники, в ваш датасет добавляются новые точки данных с той же схемой — и неожиданно производительность модели падает. Что случилось?
Ответ — ваша компания измеряла расстояние в километрах, а команда приобретенной компании — в милях. Инженер, отвечавший за интеграцию, знал об этом и реализовал поддержку миль для нового источника, но по ошибке включил ее и для старого. Таким образом, новые данные корректны для нового источника, но некорректны для старого. Если бы у вас были метаданные, например preprocessing_function_version, вы могли бы легко найти семплы, затронутые изменением, но без них вам придется собирать датасет заново.
Ошибки такого рода — не единственный случай, когда необходимо знать дату появления семпла данных. Некоторые ML-системы могут влиять на источники данных, создавая феномен, известный как «петля обратной связи». Самый распространенный пример — системы рекомендаций. Допустим, маркетплейс продает множество товаров, и на сайте есть блок «Вас также может заинтересовать». Выбрав пойти по простому пути, компания может просто отображать там самые популярные товары. Но когда такой подход заменяется системой на основе ML, появляются новые товары, а старые лидеры теряют популярность в пользу новых, рекомендованных. При недостаточно продуманном дизайне такая система может позволить товару сомнительного качества занять лидирующее положение и удерживать его в течение длительного времени. Сохранив информацию о моменте генерации семпла и о том, какие версии связанных систем были активны в тот момент, мы сможем предотвратить петлю обратной связи.
Еще один важный сценарий, связанный с метаданными, — стратификация, то есть процесс выборки данных, формирующий распределение различных подгрупп. Например, представим, что компания начала свою деятельность в стране X, собрав большое количество данных о клиентах из этой страны. Позже компания вышла на новый рынок — в страну Y — и поставила цель обеспечить одинаково высокий уровень обслуживания, включая точность ML‑моделей, для клиентов обеих стран. Для этого необходимо, чтобы данные о клиентах из X и Y были сбалансированно представлены в обучающих и тестовых выборках.
Стратификация имеет решающее значение для корректной валидации и борьбы с алгоритмическими искажениями, и обе эти темы будут подробно рассмотрены в следующих главах.
Оформить предзаказ на книгу «Машинное обучение. Проектирование систем от идеи до реализации» со скидкой 35% можно на нашем сайте по промокоду - Машинное обучение