[МУЗЫКА] [МУЗЫКА] Здравствуйте. В этом видео я расскажу о том, с чего следует начинать работу с текстовыми данными перед применением моделей стандартного и глубокого обучения. Перед тем как начать разговор о предобработке текстовых данных, определимся, что же такое текст применительно к задачам NLP. Итак, в NLP под текстом понимается упорядоченная последовательность токенов, где токены — это символы, слова или предложения. Набор всех текстов, которые мы имеем в наличии в задачах NLP, принято называть корпусом, а набор всех уникальных токенов — словарем. В зависимости от задачи нам могут потребоваться различные виды токенов. Наиболее естественным является разбиение текста по словам. Также текст можно разбивать по символам и предложениям. Вид токена влияет в первую очередь на количество токенов в корпусе, а также на размер словаря. Количество токенов в корпусе будет возрастать с ростом сложности токенов: букв в корпусе больше, чем слов, слов больше, чем предложений и так далее. А вот размер словаря, наоборот, возрастает: количество уникальных символов меньше количества уникальных слов, которое, в свою очередь, меньше количества уникальных предложений. Таким образом, вид токена можно выбирать, исходя из требований на общее количество токенов и на размер словаря, что имеет непосредственное отношение ко времени обучения модели. Итак, текст — это набор токенов. Процесс разбиения текста на токены называют токенизацией. На слайде вы можете видеть пример токенизации текста по предложениям и по словам. Сделать это можно достаточно просто. Необходимо исходный текст разбить по определенным символам пунктуации: точка, вопросительный и восклицательный знаки — если мы хотим хотим получить разбиение по предложениям. Если мы хотим в качестве токенов использовать слова, то нужно разбивать текст по всем символам пунктуации и по пробелам. Оба разбиения можно получить, используя стандартную библиотеку ntlk.tokenize. Но давайте подумаем, всегда ли указанные способы разбиения корректны. Верно ли, что, разбивая текст по пробелам и знакам пунктуации, мы получим корректные токены-слова? В общем случае это неверно. Рассмотрим пример. Используя правило, которое я описал раньше, название города Санкт-Петербург разобьется на два токена: «Санкт» и «Петербург». Хотя было бы более информативно выделить один токен: «Санкт-Петербург». Проблемы могут быть и с разбиением текстов на предложения, поскольку точки встречаются не только в конце предложений, но и в сокращениях, например, имени и отчества. Чтобы корректно обрабатывать такие случаи, используется набор рукописных правил. Например, если точка идет после заглавной буквы, то она не разделяет предложение. Также можно попробовать более сложный подход: разметить достаточное количество текстов со знаками препинания и попытаться обучить модель определять, когда точка является разделителем предложений, а когда нет. Впрочем, если описанные контрпримеры встречаются редко и участвующие в них слова не являются ключевыми, то такую проблему можно игнорировать. Пусть в качестве токенов выбраны слова и произведена токенизация. После этого появляется следующая проблема. Если в тексте несколько раз встречается одно и то же слово, но в одном случае оно начинается с заглавной буквы, в другом — в нем допущена опечатка и так далее, то каждому варианту написания слова будет соответствовать свой токен, хотя по смыслу такие токены не отличаются. Чтобы избежать описанных проблем, токены приводятся к некоторой нормальной форме. Понятие нормальной формы мы уточним позже. Кроме этого, одно и то же слово может присутствовать в корпусе в различных формах: иметь разный падеж, время, наклонение и так далее, что также требует нормализации. Таким образом, приведение слова к нормальной форме состоит из замены верхних регистров и опечаток, а также упорядочивания формы слова. Поговорим о каждом этапе более подробно. Базовая предобработка текста заключается в приведении всех символов токена к нижнему регистру. В Phython это можно сделать с помощью строкового метода lower. Избавиться от опечаток можно следующим образом. Определяется некоторая мера сходства для слов — расстояние Левенштейна, — затем создается некоторый словарь образцов слов, в котором гарантированно нет опечаток. Теперь по расстоянию Левенштейна для каждого нового слова мы можем найти ближайшее слово из словаря и считать его исправленным токеном. Также для определения меры сходства слов используется технология Word2Vec, которой будет посвящена отдельная лекция. После того как токен приведен к нижнему регистру и в нем исправлены опечатки, нужно избавиться от многообразия форм слова. Для этого существуют два подхода: стемминг и лемматизация. Стемминг — это процесс приведения слова к его стемме, что означает основу слова, то есть все слово без окончания. Пример вы видите на экране. В Python для стемминга существует специальный метод из библиотеки ntlk.stem. Другой способ приведения токена к единой форме — лемматизация, это процесс приведения слова к его лемме, что означает словарную форму слова. Преобразование происходит по следующим правилам. Существительные приводятся к именительному падежу единственного числа. Так, существительное «числа» приведется к нормальной форме «число». Глаголы, причастия и деепричастия приводятся к глаголу в инфинитиве. Например, глагол «лечу» приведется к нормальной форме «лететь». Прилагательные и числительные приводятся к форме именительного падежа единственного числа мужского рода. Так, порядковое числительное «второго» приведется к токену «второй». В Python лемматизацию можно произвести с помощью библиотеки pymorphy методом MorphAnalyzer. После нормализации текст необходимо представить в виде вектора, который затем будет использоваться в моделях машинного обучения. Векторизация текста осуществляется следующим способом. Среди всех токенов, встречающихся во всех текстах, мы выбираем некоторое количество особо важных токенов и называем их признаками текста. Теперь каждый текст будет описываться только набором этих признаков. Например, рассмотрим три текста и в качестве признаков выберем слова «нужно», «командировка», «билеты» и «оформить». Теперь каждый текст можно представить в виде четырехмерного вектора, при этом на месте, которое соответствует слову «нужно», стоит 1, если слово «нужно» присутствует в тексте, и 0 — в обратном случае. Выписывая такие вектора в строку, мы получим таблицу, которая называется матрицей объекты — признаки, поскольку каждая строка соответствует признаковому описанию некоторого объекта, а столбец — некоторому признаку. В Python такую матрицу можно получить с помощью метода CountVectorizer библиотеки sklearn. Такой подход выделения признаков имеет название Bag of Words («мешок слов»). Минусом такого подхода, даже исходя из его названия, является невозможность учета порядка слов в тексте, так как после векторизации сохраняется лишь информация о том, содержит ли текст данное слово-признак. Один из способов решения этой проблемы — это введение N-грамм. Подход заключается в том, что теперь признаками могут являться не только отдельные слова-токены, но и пары слов, тройки и так далее. Признаки, состоящие более, чем из одного слова, называются N-граммами. В прошлом примере признак «командировка» мы можем заменить на биграмму «оформить билеты». Единица в соответствующем столбце ставится только в том случае, если текст содержит и слово «оформить», и слово «билеты», причем только в указанном порядке. Такая ситуация наблюдается только в третьем тексте, так что столбец «оформить билеты» в матрице объекты — признаки будет содержать единицу только на третьем месте, а остальные элементы будут равны нулю. В Python для использования N-грамм достаточно указать параметр ngram_range метода CountVectorizer, который позволяет задать необходимый диапазон N-грамм. Введение N-грамм решает проблему порядка слов частично, только внутри N-грамма. О подходах, в полной мере учитывающих порядок слов в тексте, мы поговорим позже, когда речь зайдет о рекуррентных нейронных сетях. Подведем итоги лекции. В задачах NLP текст — это набор токенов. В качестве токенов могут выступать символы, слова и предложения. Процесс разбиения текста на токены называется токенизацией. После токенизации необходима предобработка текста, которая включает в себя приведение к нижнему регистру, исправление опечаток и нормализацию текста, которая производится двумя способами — стеммингом и лемматизацией. После приведения токенов к нормальной форме, в качестве признаков необходимо выделить наиболее значимые токены. Также признаками могут быть N-граммы. Однако даже после того, как выбраны признаки, зафиксирована матрица объекты — признаки, остается множество вопросов. Правильно ли определены признаки? Какой алгоритм машинного обучения является лучшим для поставленной задачи? Как усовершенствовать полученные результаты? Эти вопросы мы обсудим в следующих лекциях.