Как мы построили эффективную модель машинного обучения с грязными данными и недостаточным количеством информации
23 декабря 2023 г.В реальном мире мы часто располагаем очень плохими исходными данными для автоматизации процесса. Например, мы хотим автоматизировать процесс, который сейчас полностью ручной и люди допускают в нем массу ошибок. Более того, исправление ошибок происходит с большой задержкой и из-за этого текущие данные содержат много вводящих в заблуждение ответов.
Однако если данных много, количество неизбежно переходит в качество (привет, эмерджентизм!).
В этой статье я поделюсь реальным примером того, как мы автоматизировали процесс категоризации транзакций в бухгалтерском учете. В результате нам удалось сэкономить компании более 20 000 долларов США на прямых эксплуатационных расходах, а также сократить среднее время выполнения работ с 24 до 2 часов и повысить среднее качество категоризации с ~80 % до 95 %+.
В этой статье я затрону множество практических аспектов автоматизации практически любого повторяющегося ручного процесса.
Для этого вам не нужно создавать свои модели ракетостроения — вам просто нужно выбрать правильную архитектуру из Модель ML, непосредственно принимающая окончательное решение, набор дополнительных алгоритмов для обработки данных и автономные агенты для сбора информации (да, мы будем использовать ChatGPT!) .
Статья будет содержать определенное количество технических подробностей, чтобы она была интересна специалистам по ML высшего уровня, но я также постараюсь погрузить читателя в контекст бизнес-задачи и простым языком объяснить логику принятия тех или иных решений. Так что даже если вы не создаете модели ML вручную, полученные знания наверняка дадут вам много полезных идей для вашего проекта.
Поехали!
Обзор контента
- Выбор архитектуры модели машинного обучения для решения бизнес-задачи
- Инфраструктурные и технические этапы проекта
- Проблемы в обучении модели
- Преимущества глубокого знания бизнес-процесса и наиболее эффективных функций.
- Использование LLM для обогащения данных
- Встроенный поиск аномалий и глобальная оптимизация
- Лирическое отступление: почему наша модель в среднем работает лучше, чем люди
- Вместо итогового результата
Выбор архитектуры модели машинного обучения для решения бизнес-задачи
Категоризация бухгалтерского учета — достаточно простой процесс, который можно объяснить даже пятилетнему ребенку. У вас есть некоторые бизнес-операции, и вам необходимо классифицировать их с точки зрения бухгалтерского учета.
Для небольших компаний нюансов не так много. Вы тратите деньги, вы записываете их в расходы. Получили деньги – вложите их в доход. Но чем крупнее компания, тем сложнее классифицировать ее деятельность.
Кроме того, появляется множество нестандартных форм документов, описание сделок становится все более экзотическим, а некоторые практически никак не описываются.
Возникает вопрос: как в этих условиях бухгалтеры выполняют свою работу?
Мы взяли интервью у многих агентов, занимающихся категоризацией на нашей «Фабрике бухгалтерии», и просмотрели десятки часов записей их работы, чтобы точно понять, как они принимают решения. Оказалось, что они часто выбирали одно ключевое слово, одновременно обращая внимание на второстепенные факторы, такие как контрагент или сумма транзакции.
Быстро стало понятно, что нейронные сети нам не нужны (в начале проекта мы рассматривали именно FCNN, поскольку она часто используется для подобных задач), и мы можем решить задачу с помощью более простой модели, поскольку мы очень редко будем классифицировать полноценные предложения, а сами ключевые слова можно удобно превратить в отдельные околокатегориальные признаки.
<блок-цитата>Важно: старайтесь использовать как можно более простые решения. Не переусердствуйте с архитектурой решения в начале и избегайте более сложных решений на расстоянии. Очень часто вы не получаете охвата/качества из-за непонимания бизнес-контекста и, как следствие, отсутствия важных функций.
Учитывая это, Gradient Boosting оказался наиболее оптимальным алгоритмом для обучения на наших данных. Вот несколько причин, почему алгоритмы повышения градиента превосходны в нашем сценарии:
* Обработка смешанных типов данных. Алгоритмы повышения градиента могут естественным образом обрабатывать смешанные типы данных, включая как скалярные, так и категориальные функции, без необходимости обширной предварительной обработки. Многие другие алгоритмы могут испытывать трудности с категориальными функциями, которые часто требуют кодирования или преобразования.
* Эффективная обработка несбалансированных данных. Несбалансированное распределение классов часто встречается в многоклассовой классификации. Алгоритмы повышения градиента позволяют присваивать разным классам разные веса, что может помочь решить проблемы дисбаланса классов.
* Автоматическое обнаружение взаимодействия объектов. Алгоритмы повышения градиента могут автоматически обнаруживать и использовать взаимодействия объектов, что важно для сложных наборов данных с сочетанием скалярных и категориальных функций.
* Высокая точность прогнозирования. Алгоритмы повышения градиента известны своей высокой точностью прогнозирования, что делает их хорошо подходящими для задач классификации нескольких классов, когда вы хотите максимизировать производительность классификации. (Наиболее частый алгоритм победителя в Kaggle для нескольких классификаций)
* Надежность к зашумленным данным: Модели повышения градиента обычно устойчивы к зашумленным или неполным данным, что часто встречается при работе со смешанными типами объектов.
Мы также параллельно использовали две разные библиотеки для повышения градиента — XGBoost и CatBoost. XGBoost является золотым стандартом в отрасли и не нуждается в представлении. Что касается CatBoost, то это единственная реализация алгоритма Gradient Boosting, которая работает с текстовыми объектами без какой-либо дополнительной предварительной обработки. Кроме того, CatBoost специально разработан для беспрепятственной обработки категориальных функций без необходимости быстрого кодирования или кодирования меток.
В нашем случае CatBoost показал лучшие результаты.
Инфраструктурные и технические этапы проекта
Первое, что мы сделали, — это построили площадку для быстрого тестирования всех новых функций. Мы не могли заранее предсказать все функции и подходы, которые в конечном итоге придумаем, и какие из них покажут лучшие результаты. Однако мы поняли, что хотим проводить эксперименты при проверке новых гипотез как можно быстрее и проще.
Мы назвали эту игровую площадку:
- Подготовка набора данных с помощью одной команды (загрузите фактический набор данных из аналитической базы данных, разделите его на обучение/проверку/тест и подготовьте его к использованию) ол>
- Запустите необходимый экземпляр*. Прежде всего, проверьте, например, количество доступных ядер/потоков, поскольку алгоритм повышения градиента достаточно хорошо распараллеливается;
- Скопировать проект на удаленный сервер;
- Установить зависимости;
- Запустить эксперимент. ол>
- Гораздо более информативный «интерфейс»: в качестве характеристики мы даем на вход статистическое распределение прошлых категоризаций по разным срезам: на уровне компании, контрагента, вида деятельности компании, региона компании и т.д. (см. раздел « Преимущества глубокого знания бизнес-процесса и наиболее эффективных функций»)
- Автосбор дополнительной информации (см. раздел «Использование LLM для обогащения данных»). ол>
2. Удобная настройка экспериментов: при длительной работе над проектом накапливается множество новых функций и гиперпараметров и их лучшее сочетание друг с другом может со временем меняться. Вы хотите очень быстро настроить многие параметры и лучше создать для этого файл конфигурации.
3. Разбиение кода на слои: агрегация данных, предварительная обработка (например, коррекция текста), обогащение (для добавления важных функций), обучение модели, расчет и визуализация результата эксперимента.
4. Сами уровни также разделены на отдельные предметно-ориентированные сервисы. Например, в нашем случае важна дополнительная категоризация контрагентов по сделке. Для этого мы используем автономные агенты на моделях LLM (в частности, ChatGPT) и поэтому строим отдельный сервис с получением информации о контрагентах.
Без существования такой площадки скорость новых экспериментов будет во много раз медленнее. Поэтому я советую вам создать такую среду с самого начала.
Что касается обучения, то внедрение осуществлялось на базе облачного решения Azure, поскольку на тот момент у нас был грант от Microsoft, но аналогичный подход можно использовать с любой облачной платформой.
Процесс обучения состоит из следующих этапов:
Также обратите внимание на тип инстанса, ведь некоторые из них могут иметь ограниченное время работы при полной загрузке, что может увеличить время обучения. Хорошим подходом было бы создать докер и скопировать его. Мы могли бы также сделать обзор экземпляров, но это немного другая тема.
Проблемы в обучении модели
К тому времени, когда мы начали работать над моделью, наш набор данных состоял из 3 000 000 позиций, классифицированных вручную (это одна строка из документа, например, счета-фактуры часто состоят из нескольких позиций). Из них бухгалтерией проверено только около половины: это связано с особенностью работы нашей бухгалтерской фабрики. Чтобы построить бухгалтерский учет в режиме реального времени, мы немедленно отправляем все документы в наш бухгалтерский отдел в Куала-Лумпуре для классификации. Они могут передавать сложные дела бухгалтерам, но большую часть категоризации выполняют сами.
Тем не менее, бухгалтеры обязательно проверяют все классификации самостоятельно перед представлением отчетного периода, поскольку они несут за это ответственность перед правительством. В среднем категоризация на уровне бухгалтера содержит около 20% ошибок разной степени тяжести. Важно отметить, что большинство ошибок не столь критичны с точки зрения анализа финансовых затрат. Например, бухгалтеры часто путают доходы от основных и непрофильных продаж. С точки зрения налогообложения это не влияет на прибыль, но с точки зрения потенциального аудита это не следует путать.
Эти нюансы создавали дополнительные трудности в обучении, но мы смогли их безопасно решить.
Помимо разработки функций, следующие действия существенно повышают производительность модели:
* 2 тестовых набора данных: учитывая, что окончательную точность можно рассчитать только на основе представленных данных (что может занять до нескольких месяцев), а охват модели следует оценивать на основе самых последних данных, мы использовали два разных набора данных, чтобы получить точность/охват модели. Для точности мы использовали последние 10% отправленных записей. А для охвата мы использовали 10 % самых последних данных.
* Балансировка весов классов: поскольку классы не сбалансированы, нам следует скорректировать веса редких кодов учетных записей для обучения, рассчитанные следующим образом: n_samples / (n_classes * np.bincount(y)). Catboost предоставляет специальный параметр class_weights для передачи массива с весами.
* Корректировка весов классов на основе вероятности ошибки: мы также добавили дополнительные веса для каждой записи на основе частоты человеческой ошибки при создании кода учетной записи (это актуально для обучения модели на не полностью проверенных данных)
* Функция с пороговыми значениями: также можно позволить модели определять пороговые значения функций, где это применимо.
Преимущества глубокого знания бизнес-процесса и наиболее эффективных функций
Наиболее важные функции часто возникают на стыке предметной области и технических знаний.
В нашем случае самой сильной особенностью, которая добавила верхние 30 % охвата, оказалась вероятность категоризации ключевых слов по разным параметрам.
Как это работает.
По результатам теневого копирования выяснилось, что очень часто бухгалтеры для принятия решений смотрят на то, как подобные дела классифицировались в прошлом. В то же время они определяют сходство путем сопоставления ключевых слов.
Мы решили формализовать этот процесс инженерным путем. Для этого мы записываем ключевые слова во всех случаях категоризации. Затем для каждого ключевого слова на основе нашего набора данных мы рассчитываем вероятность того, что будет выбран конкретный счет в бухгалтерской книге. Поскольку в однострочном элементе часто содержится более одного ключевого слова, нам нужно каким-то образом присвоить им веса. Это можно сделать либо как простое средневзвешенное значение, т. е. присвоить одинаковый вес каждому ключевому слову, встречающемуся в позиции, либо аналогично tf-idf, т. е. придать больший вес более редким ключевым словам.< /п>
<блок-цитата>
Важно: по нашей практике второй подход (подобный tf-idf) работает лучше, но в итоге мы добавили оба подхода как две отдельные функции — одна учитывается при первом подходе, а другая — при втором. При этом обе функции по сути выбирают значения из одного и того же набора (об этом я расскажу чуть ниже).
Такой подход, как правило, не приводит к падению точности, но позволяет добавить лишний процент покрытия, что всегда приятно. Позвольте мне указать, почему это работает: при правильном обучении алгоритм поймет, что одна из функций имеет более высокую корреляцию с правильным ответом и, следовательно, будет иметь более высокую важность функции. В случае конфликта между двумя функциями приоритет будет иметь тот, у которого более высокая важность.
Поэтому в следующий раз, когда у вас возникнет несколько гипотез о том, как вычислить ту или иную функцию, спросите себя, стоит ли добавлять их все как отдельные функции. Затем измерьте вклад ошибок всех функций. Если он отрицательный, то смело оставляйте все функции.
Затем мы извлекаем из новой позиции ключевые слова, которые хотим классифицировать, и вычисляем произведения вероятностей выбора бухгалтерских счетов для этих ключевых слов. В итоге у вас получится что-то вроде этого:
Счет А - 80%
Аккаунт Б – 15%
Остальное - 5%.
В самой фиче мы напишем только тот класс, который будет проходить порог, указанный в параметрах конфига. При этом вы можете добавить несколько таких характеристик с разными пороговыми уровнями, например, 75%, 95%, 99%. Если какой-то аккаунт имеет вероятность 99%, то все такие характеристики будут иметь одно и то же значение — этот аккаунт. Если учетная запись имеет вероятность 76%, то первый признак будет иметь значение учетной записи, а остальные два будут иметь значение null. Почему это работает? Прочтите предыдущий «важный» раздел выше.
Использование LLM для обогащения данных
LLM — отличная технология для решения множества текстовых задач. Но категоризация небольших словосочетаний, зачастую не имеющих однозначного значения, — не самая подходящая для него задача. Тем не менее, мы можем использовать его для поиска и обобщения дополнительной информации и добавлять результаты его работы в виде отдельных функций.
В нашем случае мы хотим понять, является ли контрагент некоторой транзакции тем же контрагентом, который встречался в предыдущей транзакции. Если да, это значительно увеличивает вероятность категоризации по одному и тому же аккаунту. Если это новый контрагент, мы хотим получить о нем дополнительную полезную информацию.
Для этого сначала хотим убедиться, что разница в именах не является опечаткой/ошибкой на этапе оптического распознавания символов, и посчитать расстояние между именами контрагентов. Алгоритм расстояния Дамерау–Левенштейна. Если оно не превышает пороговое значение, мы запускаем наш автономный агент в ChatGPT для сканирования местных реестров компаний (например, для Сингапура это Acra Register) с именем этого контрагента. Благодаря этому мы можем убедиться в правильности написания названия компании, а также узнать основную сферу деятельности контрагента.
Мы проделываем аналогичную операцию, когда встречаем непонятные слова — гуглим это слово и просим Chatgpt сделать какой-то вывод о том, что это за слово. Например, «М1133» может оказаться названием конкретной модели телефона, а может остаться непонятным набором букв, и тогда нам придется спрашивать у клиента, что это значит.
Важно: используйте любые технологии для тех задач, для которых они созданы/показывают наилучшие результаты. В нашем случае мы учимся прогнозировать вероятность категоризации на основе статистического распределения многих факторов, вес значимости которых нам неизвестен, и для этого не существует формализованного списка правил. В таких обстоятельствах нам лучше подойдут более простые модели, которые строят некоторое статистическое распределение значений в зависимости от входных данных. Это то, что повышение градиента может сделать очень хорошо. И то, что архитектура Transformer, на которой построены все текущие модели LLM, может легко упростить.
Встроенный поиск аномалий и глобальная оптимизация
Одним из приятных бонусов построения моделей машинного обучения стало следующее наблюдение.
Поскольку повышение градиента возвращает вероятности классов, мы можем рассматривать их как достоверность ответа. Очевидным применением уровня достоверности является определение порога, при котором мы используем ответ модели. Если порог не достигнут (модель недостаточно достоверна), то мы отправляем ее на человеческую классификацию.
Менее очевидным является то, что очень низкая достоверность может коррелировать с действительно сложными случаями, требующими дополнительной проверки человеком. Именно такая была у нас ситуация!
В большинстве случаев, когда наиболее вероятный класс имел очень низкую вероятность, как правило, наблюдается более высокий уровень ошибок в человеческом процессе. Если такие дела отправляются через стандартный процесс, в котором бухгалтеры классифицируют их, вероятность получения неправильного ответа гораздо выше.
С точки зрения продукта выгоднее отправлять такие запросы напрямую бухгалтерам или клиентам. Поэтому мы выставили внизу второй порог: при его нарушении документ отправляется в отдельный поток.
Хотя такой подход приводит к локальным затратам, в целом он способствует глобальной оптимизации процесса: меньше ошибок в данных ->; больше доверия к бухгалтерскому учету в реальном времени (более высокий NPS) => меньше времени на проверку бухгалтеров (оптимизация операционных расходов).
Лирическое отступление: почему наша модель в среднем работает лучше, чем люди
Помимо самой модели машинного обучения, которая принимает окончательное решение о категоризации, мы создали для нее два важных вспомогательных компонента:
Без этих двух составляющих результат модели был бы в разы хуже. Поэтому мы не можем сказать, что наша модель машинного обучения волшебным образом стала умнее людей. Просто мы добавили дополнительные функции, которые позволяют модели принимать более обоснованное решение, и провели качественное обучение.
<блок-цитата>Важно: в реальной жизни существующий бизнес-процесс, над которым мы работаем, зачастую далек от идеала. Чтобы вас не заблокировали при разработке продукта, рассмотрите возможность сбора важной информации на внутренней стороне. Отключив визуальный интерфейс, который нужен людям, но не нужен моделям ML, вы сэкономите значительное количество ресурсов. А с помощью технологий LLM можно гораздо быстрее реализовать многие рутинные процессы сбора и обобщения информации, особенно если они не требуют высокой точности.
Вместо итогов
Проблема, которую мы решили, одновременно уникальна и стандартна.
С одной стороны, он уникален, поскольку в каждой предметной области и бизнес-процессе есть свои нюансы, которые необходимо анализировать, осмысливать и учитывать при построении модели ML. В этой статье я подробно раскрыл несколько таких нюансов в контексте построения классификатора бухгалтерского учета. Но, конечно, их гораздо больше.
С другой стороны, подходы, изложенные в этой статье, можно широко использовать повторно для автоматизации многих других бизнес-процессов, причем не обязательно тех, где нужно что-то явно классифицировать. Ведь по сути любой бизнес-процесс — это ансамбль классификаторов: вы выбираете одно из возможных решений на этапе 1, затем принимаете одно из возможных решений на этапе 2 и так далее.
Сочетая технологии LLM с более простыми моделями ML и глубиной понимания бизнес-процесса, можно добиться потрясающих результатов. В нашем случае нам удалось автоматизировать 90%+ операций и добиться гораздо лучшего качества (98%+) ответов, чем у людей, чью работу мы автоматизировали. Кроме того, мы предотвратили множество ошибок и сэкономили трудозатраты в ручном процессе, отправив аномалии на отдельный этап.
Удачи в экспериментах с машинным обучением!)
автор Петр Потапов,
особая благодарность Андрею Мещерякову
Оригинал