Записки из промышленности

Как выбрать правильную модель для классификации текста в организационной среде

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

Типичная реакция на ошибочную посадку мяча для гольфа в песчаную ловушку - это выругаться, вздохнуть, а затем тащиться к песчаной ловушке с песчаным клином. Это не сложное решение. У каждой сумки для гольфа есть песчаный клин, и, в отличие от всех других решений о том, какую клюшку использовать, следует ли мне использовать утюг 5? гибрид? железное дерево? 6 утюг? - у песчаной ловушки есть клюшка, разработанная и названная специально для нее. Поэтому вы можете быть удивлены, узнав, что есть серьезные профессионалы в гольф, которые советуют по возможности использовать клюшку в ловушке для песка. Почему? Если есть лучший инструмент, зачем рекомендовать клюшку? Поскольку лучший инструмент - не тот, который лучше всего подходит для работы, это инструмент, который вы лучше всего используете в работе.

Если вы работали над технической стороной программного обеспечения, вы, вероятно, видели, как один старший инженер легкомысленно рассказывал вам о каком-то инструменте, который они написали на awk 15 лет назад и который отлично решает вашу проблему. Знание правильного инструмента для правильной работы - вот почему консультантам по менеджменту платят так много за разработку планов. Услуги консультантов по вопросам управления не ценны, потому что они единственные люди, достаточно умные, чтобы решать сложные проблемы, они ценны, потому что они видели много похожих проблем, и они достаточно умны, чтобы извлекать у них уроки. Ваша компания может быть приобретена однажды, но большая тройка накопила буквально столетия совместного опыта в сфере слияний и поглощений. Преимущество старого инженера (тегенарианца awk) не в том, что он свободно владеет инструментами командной строки или что он умнее младшего инженера, а в том, что он уже сталкивался с этой проблемой раньше.

Но является ли использование awk хорошим решением? Ответ мало зависит от производительности программы awktegenarian и больше от текущих потребностей и возможностей организации. Если он уходит, или кому-то другому нужно поддерживать или изменять программу, или программу нужно объяснять руководителю, использование awk (древний язык командной строки) хуже, чем электронная таблица, даже если электронная таблица работает медленнее, не может справиться столько же данных и требует, чтобы вы каждый раз вручную редактировали данные в течение двадцати минут, прежде чем вы сможете их использовать.

В Salesforce моя команда разрабатывает и развертывает модели для множества задач НЛП, но наша основная работа - это модели классификации текста для электронных писем. Подбор модели удваивается: вы подбираете модель под свои данные и подбираете модель под свою организацию. В этом посте я собираюсь рассмотреть пример задачи классификации текста, чтобы проиллюстрировать некоторые идеи, которые мы извлекли при выборе правильной модели для проблемы с точки зрения науки о данных. А затем я покажу, как вы выбрасываете все это в окно, чтобы соответствовать вашим организационным ограничениям.

С технической точки зрения, какую модель мы выберем, в конечном итоге зависит от того, насколько хорошо наши обучающие данные отражают разнообразие данных, которые они будут оценивать в производственной среде. В Salesforce огромное разнообразие клиентских организаций. Есть организации с двумя людьми и организации с десятками тысяч. Они продают единицы, пакеты, лицензии и обязательства. Некоторые используют единый простой процесс продаж, другие используют десятки различных конвейеров для различных продуктов. Некоторые компании с большей вероятностью, чем другие компании, позволят нам обучать модели на их данных. Поэтому, когда мы создаем наборы данных, мы всегда априори знаем, что наши обучающие данные неполны и предвзяты, что является основным моментом, о котором мы думаем при выборе модели. Независимо от модели, которую мы выбираем для решения поставленной задачи, ее необходимо развертывать, масштабировать и поддерживать в течение всего срока службы продукта по разумной цене. Продавцы должны иметь возможность демонстрировать его клиентам, а менеджеры по продуктам должны иметь возможность демонстрировать его руководству. Эти организационные потребности обычно перевешивают технические.

Задача и корпус:

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

Для корпуса я использую набор данных, подготовленный Джеком Кингсманом. Этот набор данных особенно полезен для наших целей, поскольку он содержит много вопросов (33,81% предложений), вопросы легко помечать (ни в одном из них не отсутствует знак вопроса) , и многие из вопросов (71,94% вопросов) не грамматические, риторические вопросы, что придает этой проблеме суть. (Поскольку я использую этот корпус для исследовательских целей, конкретное содержание набора данных не имеет значения, кроме множества вопросов со специфической грамматикой.) Есть три основных типа вопросов. Во-первых, это белые-вопросы, в которых используется Пять W (19,55%), например Что на самом деле произошло, когда волшебники и колдуны раскрыли то, что у них было? Далее идут вопросы типа "да-нет", на которые дают ответ "да" или "нет" (8,51%), например: "Это действительно из Йемена?" или "ВЫ ОТВЕТИТЕ?" Наконец, у нас есть неграмотно-риторические вопросы (71,94%), например Дата публикации (ранняя)? или Согласовать с иностранными акторами по плате / разгону денег?

Поскольку все вопросы в этом наборе данных содержат вопросительный знак, я помечаю каждое предложение как вопрос / не вопрос простым наличием конечного вопросительного знака. Затем я разделил набор данных 80/20 для обучения и тестирования. Поскольку основное различие для определения того, какой подход к моделированию лучше всего подходит для данных, сводится к следующему: «сложна ли ваша проблема и насколько полны ваши данные обучения?» Я манипулирую набором данных, чтобы создать разные, но аналогичные контексты, в которых я вижу, насколько хорошо обучающие данные отражают разнообразие тестовых данных. В первом наборе данных набор тестов не затронут. Во втором наборе данных я удаляю все вопросительные знаки из тестовых данных. В третьем наборе данных я удаляю вопросительные знаки и маскирую Пять W с неизвестным токеном («XXXXX») в тестовых данных. В четвертом наборе данных я тестирую только на вопросы «да-нет» (и не на вопросы) и тренируюсь без вопросов «да-нет». Я также убираю вопросительные знаки с тестовых данных. В пятом наборе данных я беру четвертый набор данных, но также удаляю вопросительные знаки из обучающего набора. В таблице ниже описаны наборы данных и их различия.

Нижняя строка вверху:

Моя последняя рекомендация по подгонке модели к вашим данным довольно проста. Используйте Регулярные выражения, если ваши классы тесно связаны с небольшим набором функций. Если для разделения классов требуются более сложные правила и ваши данные обучения отражают разнообразие ваших тестовых данных, используйте традиционное машинное обучение и, в крайнем случае, используйте глубокое обучение. Конечно, фиксация разнообразия данных не является точной или количественной метрикой, поэтому я пройдусь по различным наборам данных и покажу, где случайный лес находится достаточно близко (наборы данных 1, 2, 3 и 5), и один, где его нет (набор данных 4). Это показано на следующей блок-схеме:

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

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

Начните с регулярных выражений

Если вы можете разделить классы с помощью небольшого набора функций, RegEx - лучший путь вперед. Если каждый вопрос содержит конечный вопросительный знак, а конечные вопросительные знаки больше нигде в тексте не появляются, тогда использование RegEx будет идеальным решением. Я мог бы просто поискать наличие терминального вопросительного знака, но это нереально плохая соломинка. Помните, мы уже много знаем о вопросах, и если бы мы этого не сделали, мы бы исследовали данные до тех пор, пока не сделаем это, и мы знаем, что люди не всегда используют вопросительные знаки (например, в обычном разговоре, чате, при грамматических ошибках и т. Д. .) и что в вопросах обычно используются слова из пяти W. Итак, я создал два классификатора RegEx: один, который просто ищет терминальные вопросительные знаки, и пять W, которые я называю классификатором Brittle RegEx, и один, который делает то же самое, но дополнительно ищет шаблоны начала предложения с вопросами да-нет, которые я вызовите надежный классификатор RegEx. Дополнительные шаблоны, помимо терминального вопросительного знака, улучшают запоминание за счет точности. Например, предложение Мы знаем, что это означает. является положительным совпадением с шаблоном Five W, но не является вопросом, а Это связано с вирусом или чем-то еще? Даст положительный ответ. соответствует классификатору Robus RegEx, но не хрупкому. Два классификатора RegEx демонстрируют ценность понимания ваших данных.

В наборе данных 1, где тестовые данные все еще имеют вопросительные знаки, оба классификатора RegEx работают очень хорошо. В наборе данных 2, где в тестовых примерах отсутствуют вопросительные знаки, отзывчивость и точность обоих классификаторов снижаются, но не до нуля, благодаря дополнительным функциям, выходящим за пределы конечного вопросительного знака. В наборе данных 3, где в тестовых примерах отсутствуют вопросительные знаки, а вопросительные слова замаскированы, две модели расходятся по производительности. Отзыв надежного классификатора RegEx требует дальнейшего снижения, так как только шаблон вопросов «да-нет» теперь будет находить вопросы, а вопросы «да-нет» составляют меньшинство вопросов, но производительность классификатора Brittle RegEx полностью падает до нуля. В наборах данных 4 и 5 надежный классификатор RegEx снова демонстрирует отличную производительность.

Как мы могли бы улучшить производительность надежного классификатора RegEx для наборов данных 1, 4 и 5, если он показал себя хорошо? Поскольку отзыв почти идеален, мы хотим повысить точность, то есть найти способ уменьшить количество ложных срабатываний. Первый способ сделать это - добавить в наш шаблон исключения. Я не советую этого делать.

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

Производительность классификатора RegEx резко упала на наборах данных 2 и 3, и по уважительной причине: функции, выбранные нашим RegEx, больше не коррелируют с классами, которые мы хотим разделить. Так что же с этим делать? Нам нужно будет посмотреть на данные и создать больше шаблонов, которые, по нашему мнению, отражают разницу, но как только мы начнем заходить слишком далеко и шаблоны станут неуправляемыми (субъективная оценка), пора пометить данные и позволить данным определять, как сопоставить объекты с классами. Иногда нужно удалять даже самые лучшие регулярные выражения. Это подводит нас к следующему подходу: машинному обучению.

Разработайте модель машинного обучения

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

Интуиция относительно производительности модели машинного обучения намного проще, чем у классификаторов RegEx: модель работает лучше, когда обучающие и тестовые данные более похожи. Наборы данных 1, 2 и 3 фактически имеют одни и те же обучающие данные и отклоняются только от своих тестовых данных, которые последовательно перемещаются все дальше и дальше от обучающего набора.

Удаление вопросительных знаков из набора тестов (Dataset 2) приводит к заметному снижению производительности, поскольку основная функция, на которой фокусируется модель, - это вопросительный знак. Фактически, вопросительный знак и точка - две наиболее важные характеристики, причем по порядку величины. Я выбрал модель случайного леса по двум причинам: она хорошо работает в различных контекстах и ​​обеспечивает важность функций, измеряя ошибку вне пакета для каждой функции. Важность функций, как и многие другие вещи, подобна вероятности, но не совсем - но для каждой функции важность - это число от нуля до единицы, и все они в сумме дают единицу . Для функции чтобы быть важным, он должен обычно выбираться для разветвления небольших деревьев решений в нашем случайном лесу, что означает, что он одновременно сильно разделяет классы и встречается относительно часто. Если ваши самые мощные функции не используются часто (или вообще не встречаются) в вашем тестовом наборе, производительность упадет. Ниже приведена таблица значимости функций для модели случайного леса, обученной на каждом из пяти наборов данных.

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

Этот график легче читать, но он маскирует, что по мере того, как вы углубляетесь в особенности, они становятся менее важными, то есть они появляются в большем количестве ваших тестовых примеров, но они не очень полезны для разделения ваших классов. Наши функции подчиняются закону Ципфа, что означает, что частота этого термина примерно обратно пропорциональна его рангу в частотной таблице. Дискриминационные признаки, скорее всего, встречаются нечасто. Задача идентификации вопроса отчасти обходится стороной, поскольку пять знаков W и вопросительные знаки представляют собой замкнутый набор и появляются относительно часто, но, тем не менее, функции с более низким рейтингом встречаются значительно реже. Чтобы попытаться запечатлеть это явление, я сделал другой, более трудный для чтения сюжет, представленный ниже:

По оси абсцисс отложена совокупная важность функции, а по оси ординат - процент тестовых случаев, содержащих любую из n-граммов. Например, в наборе данных 1 первые две функции («?» И «.») Составляют чуть более 40% важности и появляются почти в каждом отдельном тестовом примере. Модель машинного обучения хорошо работает с набором данных 1, потому что наиболее важные функции часто появляются в тестовых примерах. Набор данных 4, с другой стороны, иллюстрирует почти противоположное: наиболее важные функции не отображаются в таком количестве тестовых случаев, и этот процент начинает расти только по мере того, как мы переходим к все менее полезным функциям.

Можно ли это использовать a priori, чтобы определить, что данные вашего обучения и тестирования недостаточно похожи? Возможно нет. Вы должны были тщательно и серьезно разработать модель, чтобы определить, что модель не годится, а затем вы должны убить свою любимую модель. Каждый раз вам нужно влезать в данные. Надеюсь, этот раздел поможет вам развить интуицию в понимании взаимодействия между тем, что модель узнает из характеристик обучающих данных, и готовностью применить это понимание к тестовым данным.

Один из способов восполнить пробел - удалить информацию из тренировочных данных, чтобы предотвратить переоснащение определенных функций, которые редко (или никогда) появляются в ваших оценочных данных. Набор данных 5 идентичен набору данных 4, за исключением того, что в данных обучения нет вопросительных знаков. Производительность значительно улучшается, и вопросительные знаки исчезают из списка важных функций. Если вы не можете изменить свои данные, попробуйте найти больше источников данных, в идеале те, которые напрямую или не представляют разные измерения данных, которые вы фактически оцениваете. Обратитесь к другим людям в вашей команде или ближайшим командам и посмотрите, смогут ли они придумать какие-либо примеры, которые могут быть сложными для вашей модели. Люди из других команд любят придумывать примеры, показывающие, что они умнее ваших моделей. Я обнаружил удивительную глубину контрпримеров, которые могут придумать мои коллеги, когда я сделал наши модели доступными в SlackBot (подробнее об этом позже). Прежде чем отказываться от TensorFlow, попробуйте найти больше данных для обучения. Если это все, что вы можете сделать, пора заняться глубоким обучением.

Глубокое обучение как последнее средство

Вы пришли к выводу, что данные о ваших тренировках не отражают те данные, которые вы увидите в естественных условиях. Есть множество реальных, простительных причин, почему вы оказались в этом положении. Возможно, были ошибки при сборе данных. Возможно, ваш MSA распространяется только на некоторых из ваших пользователей, поэтому вы получите предвзятую выборку из данных о подписке. Возможно, вы приобрели аналогичный набор данных, но он устарел или является непривычным для работы. Какой бы ни была причина убеждения в том, что ваши данные обучения не охватывают данные в дикой природе, и что вы не можете расширять или исправлять свои наборы данных, пришло время для глубокого обучения.

Глубокое обучение очень популярно, и я далеко не эксперт в этом вопросе. Кажется, что глубокое обучение надежно справляется с множеством задач при условии, что у вас достаточно данных, чтобы оптимизировать миллиард параметров. Я попробовал простую двунаправленную модель LSTM, и она неплохо справляется.

Что еще более важно, он устойчиво работает со всеми пятью наборами данных. Так почему бы мне не порекомендовать вам каждый раз просто использовать глубокое обучение и положить этому конец?

Если вы помните, эта запись в блоге посвящена тому, как выбрать правильную модель. Частично это означает выбор модели, которая соответствует вашим данным. Другая часть этого - выбор модели, подходящей для вашей организации. У регулярных выражений есть много преимуществ в организационной среде. Для обучения им не требуется графический процессор, и их можно развернуть как часть любого кода, который вы уже развертываете. Если ваши руководители или менеджеры настаивают на том, что конкретный пример работает, вы можете убедиться, что он работает. И если быть предельно честным, регулярным выражениям вряд ли понадобится лишь горстка положительных примеров для маркированных данных. Для моделей глубокого обучения требуются графические процессоры, тонны помеченных данных и достаточно времени для изучения огромного пространства гиперпараметров. Если вы тренируете модель глубокого обучения, но ваша компания никогда не развертывала ее раньше, или вы сами собираетесь ее развернуть, это может стоить вашему проекту месяцев или лет времени. Возможно, вам будет лучше с садовой моделью ML с худшим показателем F1, но которую могут своевременно развернуть и обслужить другие люди.

Если я собираюсь сказать вам, что правильная модель - это та, которую вы можете развернуть с имеющимися у вас ресурсами, обученными на данных, которые вы можете получить, за то время, на которое у вашего босса есть терпение, почему я прошел через все этого подробного технического анализа? Если вы попытаетесь подогнать модель под организацию, не понимая, как сначала подогнать ее под данные, у вас ничего не получится. Я поделюсь некоторыми примерами из того, когда я разрабатывал модель парсера подписи для Salesforce.

У меня было три организационных ограничения, которым мне нужно было соответствовать моей модели. Во-первых, команда, развернувшая модель, написала задания для Kafka Streams в Kotlin. Поэтому мне нужно было упаковать мою модель как библиотеку, развертываемую как JAR. Это означало, что две предыдущие структуры машинного обучения, которые использовала моя команда - MLlib и TensorFlow, были отключены. В итоге я использовал SMILE (написанный Haifeng Li), потому что он обеспечивал минимальную функциональность машинного обучения в Scala и сам реализовал недостающие инструменты для моего рабочего процесса в области науки о данных. Второе ограничение заключалось в том, что парсер подписи должен быть обучен работе с информацией, позволяющей установить личность (PII), но мы не используем PII в данных о клиентах в Salesforce. Поскольку подпись является PII, я в конечном итоге сфабриковал данные обучения и тестирования, чтобы иметь статистическое сходство с данными наших клиентов, но фактически не использовал их данные. Я про фальсификацию данных писал здесь. Наконец, я сделал внутреннюю модель оценки заголовков доступной в виде Slack Bot и обнаружил, что у менеджеров по продукту есть пара заголовков, которые им просто нужны, чтобы правильно оценить ее. Теоретически правильный способ решить эту проблему - пройти трудоемкий процесс маркировки большего количества данных и переобучения модели, но это занимает много времени, и есть еще дюжина других проектов, которые более остро нуждаются в моем внимании, поэтому я создал Модель В противном случае. Я поместил перед моделью простой RegEx, который обрабатывал необходимые им особые случаи, в противном случае моя модель ML выполняла свою работу.

PS Если вам интересно, вот график, на котором сравниваются оценки F1 каждой модели с каждым набором данных. Обратите внимание, что здесь нигде не упоминается, что развертывание новой инфраструктуры и компонентов для поддержки TensorFlow в больших масштабах нетривиально.