Главная » Хабрахабр » [Перевод] Основы Natural Language Processing для текста

[Перевод] Основы Natural Language Processing для текста

Обработка естественного языка сейчас не используются разве что в совсем консервативных отраслях. В большинстве технологических решений распознавание и обработка «человеческих» языков давно внедрена: именно поэтому обычный IVR с жестко заданными опциями ответов постепенно уходит в прошлое, чатботы начинают все адекватнее общаться без участия живого оператора, фильтры в почте работают на ура и т.д. Как же происходит распознавание записанной речи, то есть текста? А вернее будет спросить, что лежит в основе соврменных техник распознавания и обработки? На это хорошо отвечает наш сегодняшний адаптированный перевод – под катом вас ждет лонгрид, который закроет пробелы по основам NLP. Приятного чтения!

Что такое Natural Language Processing?

Natural Language Processing (далее – NLP) – обработка естественного языка – подраздел информатики и AI, посвященный тому, как компьютеры анализируют естественные (человеческие) языки. NLP позволяет применять алгоритмы машинного обучения для текста и речи.

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

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

Примеры

Cortana

С помощью Cortana можно создавать напоминания, открывать приложения, отправлять письма, играть в игры, узнавать погоду и т.д. В Windows есть виртуальный помощник Cortana, который распознает речь.

Siri

Siri это помощник для ОС от Apple: iOS, watchOS, macOS, HomePod и tvOS. Множество функций также работает через голосовое управление: позвонить/написать кому-либо, отправить письмо, установить таймер, сделать фото и т.д.

Gmail

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

Dialogflow

Платформа от Google, которая позволяет создавать NLP-ботов. Например, можно сделать бота для заказа пиццы, которому не нужен старомодный IVR, чтобы принять ваш заказ.

Python-библиотека NLTK

NLTK (Natural Language Toolkit) – ведущая платформа для создания NLP-программ на Python. У нее есть легкие в использовании интерфейсы для многих языковых корпусов, а также библиотеки для обработки текстов для классификации, токенизации, стемминга, разметки, фильтрации и семантических рассуждений. Ну и еще это бесплатный опенсорсный проект, который развивается с помощью коммьюнити.
Мы будем использовать этот инструмент, чтобы показать основы NLP. Для всех последующих примеров я предполагаю, что NLTK уже импортирован; сделать это можно командой import nltk

Основы NLP для текста

В этой статье мы рассмотрим темы:

  1. Токенизация по предложениям.
  2. Токенизация по словам.
  3. Лемматизация и стемминг текста.
  4. Стоп-слова.
  5. Регулярные выражения.
  6. Мешок слов.
  7. TF-IDF.

1. Токенизация по предложениям

Токенизация (иногда – сегментация) по предложениям – это процесс разделения письменного языка на предложения-компоненты. Идея выглядит довольно простой. В английском и некоторых других языках мы можем вычленять предложение каждый раз, когда находим определенный знак пунктуации – точку.

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

Пример:

Возьмем небольшой текст про настольную игру нарды:

Backgammon is one of the oldest known board games. Its history can be traced back nearly 5,000 years to archeological discoveries in the Middle East. It is a two player game where each player has fifteen checkers which move between twenty-four points according to the roll of two dice.

Чтобы сделать токенизацию предложений с помощью NLTK, можно воспользоваться методом nltk.sent_tokenize
На выходе мы получим 3 отдельных предложения:

Backgammon is one of the oldest known board games. Its history can be traced back nearly 5,000 years to archeological discoveries in the Middle East. It is a two player game where each player has fifteen checkers which move between twenty-four points according to the roll of two dice.

2. Токенизация по словам

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

И тут вновь нам помогают библиотеки. Тем не менее, могут возникнуть проблемы, если мы будем использовать только пробел – в английском составные существительные пишутся по-разному и иногда через пробел.

Пример:

Давайте возьмем предложения из предыдущего примера и применим к ним метод nltk.word_tokenize

Вывод:

['Backgammon', 'is', 'one', 'of', 'the', 'oldest', 'known', 'board', 'games', '.'] ['Its', 'history', 'can', 'be', 'traced', 'back', 'nearly', '5,000', 'years', 'to', 'archeological', 'discoveries', 'in', 'the', 'Middle', 'East', '.'] ['It', 'is', 'a', 'two', 'player', 'game', 'where', 'each', 'player', 'has', 'fifteen', 'checkers', 'which', 'move', 'between', 'twenty-four', 'points', 'according', 'to', 'the', 'roll', 'of', 'two', 'dice', '.']

3. Лемматизация и стемминг текста

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

Примеры:

Приведение разных словоформ к одной:

dog, dogs, dog’s, dogs’ => dog

То же самое, но уже применительно к целому предложению:

the boy’s dogs are different sizes => the boy dog be differ size

Лемматизация и стемминг – это частные случаи нормализации и они отличаются.

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

Лемматизация – это более тонкий процесс, который использует словарь и морфологический анализ, чтобы в итоге привести слово к его канонической форме – лемме.

Однако у стеммеров есть и свои преимущества: их проще внедрить и они работают быстрее. Отличие в том, что стеммер (конкретная реализация алгоритма стемминга – прим.переводчика) действует без знания контекста и, соответственно, не понимает разницу между словами, которые имеют разный смысл в зависимости от части речи. Плюс, более низкая «аккуратность» может не иметь значения в некоторых случаях.

Примеры:

  1. Слово good – это лемма для слова better. Стеммер не увидит эту связь, так как здесь нужно сверяться со словарем.
  2. Слово play – это базовая форма слова playing. Тут справятся и стемминг, и лемматизация.
  3. Слово meeting может быть как нормальной формой существительного, так и формой глагола to meet, в зависимости от контекста. В отличие от стемминга, лемматизация попробует выбрать правильную лемму, опираясь на контекст.

Теперь, когда мы знаем, в чем разница, давайте рассмотрим пример:
Вывод:

Stemmer: seen
Lemmatizer: see Stemmer: drove
Lemmatizer: drive

4. Стоп-слова

Когда мы применяем машинное обучение к текстам, такие слова могут добавить много шума, поэтому необходимо избавляться от нерелевантных слов. Стоп-слова – это слова, которые выкидываются из текста до/после обработки текста.

При этом надо понимать, что не существует универсального списка списка стоп-слов, все зависит от конкретного случая. Стоп-слова это обычно понимают артикли, междометия, союзы и т.д., которые не несут смысловой нагрузки.

Перед первым использованием вам понадобится его скачать: nltk.download(“stopwords”). В NLTK есть предустановленный список стоп-слов. После скачивания можно импортировать пакет stopwords и посмотреть на сами слова:

Вывод:

['i', 'me', 'my', 'myself', 'we', 'our', 'ours', 'ourselves', 'you', "you're", "you've", "you'll", "you'd", 'your', 'yours', 'yourself', 'yourselves', 'he', 'him', 'his', 'himself', 'she', "she's", 'her', 'hers', 'herself', 'it', "it's", 'its', 'itself', 'they', 'them', 'their', 'theirs', 'themselves', 'what', 'which', 'who', 'whom', 'this', 'that', "that'll", 'these', 'those', 'am', 'is', 'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had', 'having', 'do', 'does', 'did', 'doing', 'a', 'an', 'the', 'and', 'but', 'if', 'or', 'because', 'as', 'until', 'while', 'of', 'at', 'by', 'for', 'with', 'about', 'against', 'between', 'into', 'through', 'during', 'before', 'after', 'above', 'below', 'to', 'from', 'up', 'down', 'in', 'out', 'on', 'off', 'over', 'under', 'again', 'further', 'then', 'once', 'here', 'there', 'when', 'where', 'why', 'how', 'all', 'any', 'both', 'each', 'few', 'more', 'most', 'other', 'some', 'such', 'no', 'nor', 'not', 'only', 'own', 'same', 'so', 'than', 'too', 'very', 's', 't', 'can', 'will', 'just', 'don', "don't", 'should', "should've", 'now', 'd', 'll', 'm', 'o', 're', 've', 'y', 'ain', 'aren', "aren't", 'couldn', "couldn't", 'didn', "didn't", 'doesn', "doesn't", 'hadn', "hadn't", 'hasn', "hasn't", 'haven', "haven't", 'isn', "isn't", 'ma', 'mightn', "mightn't", 'mustn', "mustn't", 'needn', "needn't", 'shan', "shan't", 'shouldn', "shouldn't", 'wasn', "wasn't", 'weren', "weren't", 'won', "won't", 'wouldn', "wouldn't"]

Рассмотрим, как можно убрать стоп-слова из предложения:
Вывод:

['Backgammon', 'one', 'oldest', 'known', 'board', 'games', '.']

Если вы не знакомы с list comprehensions, то можно узнать побольше здесь. Вот другой способ добиться того же результата:
Тем не менее, помните, что list comprehensions быстрее, так как оптимизированы – интерпретатор выявляет предиктивный паттерн во время цикла.

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

5. Регулярные выражения.

Регулярное выражение (регулярка, regexp, regex) – это последовательность символов, которая определяет шаблон поиска. Например:

  • . – любой символ, кроме перевода строки;
  • \w – одно слово;
  • \d – одна цифра;
  • \s – один пробел;
  • \W – одно НЕслово;
  • \D – одна НЕцифра;
  • \S – один НЕпробел;
  • [abc] – находит любой из указанных символов match any of a, b, or c;
  • [^abc] – находит любой символ, кроме указанных;
  • [a-g] – находит символ в промежутке от a до g.

Выдержка из документации Python:

Это противоречит использованию обратного слеша в Python: например, чтобы буквально обозначить обратный слеш, необходимо написать '\\\\' в качестве шаблона для поиска, потому что регулярное выражение должно выглядеть как \\, где каждый обратный слеш должен быть экранирован. Регулярные выражение используют обратный слеш (\) для обозначения специальных форм или чтобы разрешить использование спецсимволов.

Таким образом, r”\n” – это строка с двумя символами (‘\’ и ‘n’), а “\n” – строка с одним символом (перевод строки).
Решение – использовать нотацию raw string для шаблонов поиска; обратные слеши не будут особым образом обрабатываться, если использованы с префиксом ‘r’.

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

Мы можем использовать функцию re.sub, чтобы заменить все, что подходит под шаблон поиска, на указанную строку. Модуль re в Python представляет операции с регулярными выражениями. Вот так можно заменить все НЕслова на пробелы:

Вывод:

'The development of snowboarding was inspired by skateboarding sledding surfing and skiing '

Регулярки – это мощный инструмент, с его помощью можно создавать гораздо более сложные шаблоны. Если вы хотите узнать больше о регулярных выражениях, то могу порекомендовать эти 2 веб-приложения: regex, regex101.

6. Мешок слов

Алгоритмы машинного обучения не могут напрямую работать с сырым текстом, поэтому необходимо конвертировать текст в наборы цифр (векторы). Это называется извлечением признаков.

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

Чтобы использовать модель, нам нужно:

  1. Определить словарь известных слов (токенов).
  2. Выбрать степень присутствия известных слов.

Любая информация о порядке или структуре слов игнорируется. Вот почему это называется МЕШКОМ слов. Эта модель пытается понять, встречается ли знакомое слово в документе, но не знает, где именно оно встречается.

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

Мы используем только 4 предложения, чтобы понять, как работает модель. Пример:
Рассмотрим шаги создания этой модели. В реальной жизни вы столкнетесь с бОльшими объемами данных.

1. Загружаем данные

Представим, что это наши данные и мы хотим загрузить их в виде массива:

I like this movie, it's funny.
I hate this movie.
This was awesome! I like it.
Nice one. I love it.

Для этого достаточно прочитать файл и разделить по строкам:
Вывод:

["I like this movie, it's funny.", 'I hate this movie.', 'This was awesome! I like it.', 'Nice one. I love it.']

2. Определяем словарь

Соберем все уникальные слова из 4 загруженных предложений, игнорируя регистр, пунктуацию и односимвольные токены. Это и будет наш словарь (известные слова).

Переходим к следующему шагу. Для создания словаря можно использовать класс CountVectorizer из библиотеки sklearn.

3. Создаем векторы документа

Далее, мы должны оценить слова в документе. На этом шаге наша цель – превратить сырой текст в набор цифр. После этого, мы используем эти наборы как входные данные для модели машинного обучения. Простейший метод скоринга – это отметить наличие слов, то есть ставить 1, если есть слово и 0 при его отсутствии.

Теперь мы можем создать мешок слов используя вышеупомянутый класс CountVectorizer.

Вывод:

Это наши предложения. Теперь мы видим, как работает модель «мешок слов».

Еще пару слов про мешок слов

Сложность этой модели в том, как определить словарь и как подсчитать вхождение слов.

В примере выше, длина вектора равна количеству известных слов. Когда размер словаря увеличивается, вектор документа тоже растет.

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

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

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

  • игнорирование регистра слов;
  • игнорирование пунктуации;
  • выкидывание стоп-слов;
  • приведение слов к их базовым формам (лемматизация и стемминг);
  • исправление неправильно написанных слов.

Другой, более сложный способ создания словаря – использовать сгруппированные слова. Это изменит размер словаря и даст мешку слов больше деталей о документе. Такой подход называется «N-грамма».

В контексте языковых корпусов, под N-граммой обычно понимают последовательность слов. N-грамма это последовательность каких-либо сущностей (слов, букв, чисел, цифр и т.д.). Цифра N обозначает, сколько сгруппированных слов входит в N-грамму. Юниграмма это одно слово, биграмма это последовательность двух слов, триграмма – три слова и так далее. В модель попадают не все возможные N-граммы, а только те, что фигурируют в корпусе.

Пример:

Рассмотрим такое предложение:

The office building is open today

Вот его биграммы:

  • the office
  • office building
  • building is
  • is open
  • open today

Как видно, мешок биграмм – это более действенный подход, чем мешок слов.

Оценка (скоринг) слов

Мы уже рассматривали простой, бинарный подход (1 – есть слово, 0 – нет слова). Когда создан словарь, следует оценить наличие слов.

Есть и другие методы:

  1. Количество. Подсчитывается, сколько раз каждое слово встречается в документе.
  2. Частотность. Подсчитывается, как часто каждое слово встречается в тексте (по отношению к общему количеству слов).

7. TF-IDF

У частотного скоринга есть проблема: слова с наибольшей частотностью имеют, соответственно, наибольшую оценку. В эти словах может быть не так много информационного выигрыша для модели, как в менее частых словах. Один из способов исправить ситуацию – понижать оценку слова, которое часто встречается во всех схожих документах. Это называется TF-IDF.

TF-IDF (сокращение от term frequency — inverse document frequency) – это статистическая мера для оценки важности слова в документе, который является частью коллекции или корпуса.

Скоринг по TF-IDF растет пропорционально частоте появления слова в документе, но это компенсируется количеством документов, содержащих это слово.

Формула скоринга для слова X в документе Y:

Источник: filotechnologia.blogspot.com/2014/01/a-simple-java-class-for-tfidf-scoring.html
Формула TF-IDF.

TF (term frequency — частота слова) – отношение числа вхождений слова к общему числу слов документа.

IDF (inverse document frequency — обратная частота документа) — инверсия частоты, с которой некоторое слово встречается в документах коллекции.

В итоге, вычислить TF-IDF для слова term можно так:

Пример:

Давайте проделаем это с теми же сообщениями, что мы использовали в примере с мешком слов. Можно использовать класс TfidfVectorizer из библиотеки sklearn, чтобы вычислить TF-IDF.

I like this movie, it's funny.
I hate this movie.
This was awesome! I like it.
Nice one. I love it.

Код:
Вывод:

Заключение

В этой статье были разобраны основы NLP для текста, а именно:

  • NLP позволяет применять алгоритмы машинного обучения для текста и речи;
  • NLTK (Natural Language Toolkit) – ведущая платформа для создания NLP-программ на Python;
  • токенизация по предложениям – это процесс разделения письменного языка на предложения-компоненты;
  • токенизация по словам – это процесс разделения предложений на слова-компоненты;
  • лемматизация и стемминг преследуют цель привести все встречающиеся словоформы к одной, нормальной словарной форме;
  • стоп-слова – это слова, которые выкидываются из текста до/после обработки текста;
  • регулярное выражение (регулярка, regexp, regex) – это последовательность символов, которая определяет шаблон поиска;
  • мешок слов – это популярная и простая техника извлечения признаков, используемая при работе с текстом. Она описывает вхождения каждого слова в текст.

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

Если вы хотите увидеть все описанные концепции в одном большом примере, то вам сюда.


Оставить комментарий

Ваш email нигде не будет показан
Обязательные для заполнения поля помечены *

*

x

Ещё Hi-Tech Интересное!

Прыжки китайского «Кузнечика» от LinkSpace

Китайская частная космическая компания LinkSpace построила тестовый ракетный стенд вертикального взлета и посадки, аналогичный «Кузнечику» от SpaceX, и с января этого года проводит все более сложные испытания. После тестов зависания на привязи компания перешла к полноценным подскокам, 27 марта поднявшись ...

Искусственный интеллект улучшает качество графики старых видеоигр и делает это действительно хорошо

Недавно стало известно еще об одной задаче, которую ИИ решает очень хорошо. Технологии искусственного интеллекта постепенно развиваются, помогая решать задачи и проблемы самых разных сфер — от бизнеса до медицины и развлечений. Речь идет об игровых модах — как оказалось, ...