
Введение
Обработка естественного языка — это область искусственного интеллекта, которая направлена на то, чтобы дать компьютерам возможность понимать язык так же, как люди. Он поддерживает множество реальных приложений, таких как обнаружение спама в электронной почте, машинный перевод и суммирование текста.
В Python есть много библиотек, очень полезных для обработки естественного языка, каждая из которых хороша по-своему. В этой статье я сделаю обзор трех библиотек: NLTK, spaCy и TextBlob. Я также продемонстрирую, как выполнять некоторые общие задачи НЛП, используя каждую из этих библиотек.
НЛТК
Natural Language Toolkit (NLTK) — это мощный пакет Python, предоставляющий набор алгоритмов естественного языка. NLTK — одна из самых известных библиотек Python NLP, состоящая из множества распространенных алгоритмов, таких как токенизация, маркировка частей речи, выделение корней, анализ настроений и распознавание именованных сущностей.
Установка:
NLTK можно установить с помощью диспетчера пакетов pip с помощью команды, показанной ниже:
pip install nltk
После этого вам нужно будет установить данные, чтобы использовать NLTK для различных задач, которые мы рассмотрим в этой статье. Для этого вам нужно будет создать и запустить программу на Python со следующим кодом:
import nltk nltk.download(["punkt", "tagsets", "words", "stopwords", "wordnet", "vader_lexicon", "maxent_ne_chunker", "averaged_perceptron_tagger"])
TextBlob
TextBlob — еще одна замечательная библиотека НЛП на Python. Он построен на основе NLTK и предлагает аналогичную функциональность, но с более интуитивно понятным интерфейсом и плавной кривой обучения. По этой причине TextBlob обычно проще в использовании, если вы только начинаете работать с обработкой естественного языка.
Установка:
TextBlob можно установить с помощью диспетчера пакетов pip с помощью команды, показанной ниже:
pip install textblob
Поскольку TextBlob построен поверх NLTK, и мы загрузили данные NLTK на предыдущем шаге, мы закончили настройку TextBlob.
СПАСИ
spaCy — более новая и более быстрая библиотека NLP, чем NLTK и TextBlob. Говорят, что это «сила отрасли» с «самой современной скоростью» и в основном используется для приложений, которые обрабатывают и понимают большие объемы текста.
Установка:
Вы должны использовать следующие команды для установки spaCy:
pip install -U pip setuptools wheel pip install -U spacy
Если приведенные выше команды не работают, перейдите по этой ссылке для получения инструкций по установке: https://spacy.io/usage.
После установки вы загрузите обученный пайплайн. Для получения дополнительной информации и доступных пакетов смотрите каталог моделей по следующей ссылке: https://spacy.io/models.
В этой статье мы будем использовать англоязычный конвейер. Вы можете установить его, используя следующую команду в терминале/командной строке.
python -m spacy download en_core_web_sm
Токенизация
Токенизация — это способ разделения фрагмента текста на более мелкие единицы, называемые токенами. Компьютеры могут интерпретировать значение текста, анализируя эти токены.
Токенизация — фундаментальная и важная задача НЛП. Токенизация предложений разделяет предложения в тексте, а токенизация слов разделяет слова внутри предложения. Как правило, токенизация слов разбивает текст по пробелам для создания списка слов, а токенизация предложений разбивает текст по точкам препинания (например, точка или восклицательный знак) для создания списка предложений.
Пример токенизации слова:
«Я люблю обработку естественного языка!» → [«Я», «люблю», «естественный», «язык», «обработка»]
Токенизация в NLTK
NLTK имеет две функции для токенизации: одну для токенизации слов, а другую для токенизации предложений. Мы можем вызвать эти функции для строки текста, и она вернет токенизированный список, который вы можете вывести.
Токенизация в TextBlob
Токенизация в Textblob очень проста — все, что нам нужно сделать, это создать объект TextBlob со строкой текста, которую вы хотите использовать. Затем нам просто нужно вывести атрибуты .words и .sentences объекта, как показано ниже.
TextBlob имеет собственный объект, называемый WordList, который создается после токенизации слов. Вы можете обращаться с этим списком как с обычным списком, так как он имеет почти те же функции. Вы также можете преобразовать его в список, если хотите.
Токенизация в spaCy
Во-первых, мы импортируем библиотеку spaCy. Мы можем загрузить установленный конвейер через spacy.load(). Это вернет объект Language с именем nlp, содержащий функциональные возможности, необходимые для обработки текста. Вызов объекта nlp для текстовой строки возвращает обработанный Doc, который мы пройдем по циклу для вывода отдельных токенов. Первый цикл проходит через сам doc для получения токенов слов, а второй цикл проходит через doc.sents для вывода предложений.
Тегирование части речи
Тегирование части речи (сокращенно POS-тегирование) — это процесс маркировки слова в тексте как определенной части речи (существительного, глагола, прилагательного и т. д.) на основе его определения и контекста в предложении.
Тегирование POS — важная концепция NLP, которую можно использовать для извлечения отношений между словами, построения деревьев синтаксического анализа и многого другого.
Все три из этих библиотек имеют полезные функции для выполнения тегов POS.
Маркировка POS в NLTK
NLTK предоставляет очень простую функцию для тегов POS, которая называется pos_tag(). Он берет список токенов и выводит часть речи каждого из них.
Результатом является список кортежей. Первый элемент каждого кортежа — это токен, а второй элемент — это часть речи:
[('I', 'PRP'), ('нравится', 'VBP'), ('естественный', 'JJ'), ('язык', 'NN'), ('обработка', 'NN') , ('.', '.'), ('Это', 'ПРП'), ('есть', 'ВБЗ'), ('интересно', 'ЖЖ'), ('.', '.') ]
Чтобы узнать, что означает каждая аббревиатура (например, NN или PRP), запустите следующий код:
#Outputs a list of tags and their meanings nltk.help.upenn_tagset()
Маркировка POS в TextBlob
В TextBlob мы создадим объект TextBlob и будем использовать свойство tags. Выходные данные имеют тот же формат, что и NLTK: список кортежей в формате (токен, тег).
Вывод: [('I', 'PRP'), ('like', 'VBP'), ('естественный', 'JJ'), ('язык', 'NN'), ('обработка', 'NN '), ('Это', 'ПРП'), ('есть', 'ВБЗ'), ('интересно', 'ЖЖ')]
Результат почти такой же, как у NLTK; однако единственное отличие состоит в том, что TextBlob не включает точки, тогда как NLTK включает.
Маркировка POS в SpaCy
Подобно тому, что мы делали ранее для вывода каждого отдельного токена, мы пройдемся по каждому токену и воспользуемся атрибутом tag_ для вывода тега POS. Поскольку мы зацикливаем и печатаем каждый отдельный тег, каждый тег будет выводиться в отдельной строке, но теги будут такими же, как те, что выводятся TextBlob и NLTK.
Вывод (Они напечатаны в разных строках, но я удалил лишние строки для экономии места): PRP VBP JJ NN NN . ПРП ВБЗ ЖЖ.
Удаление стоп-слов
Стоп-слова — это часто повторяющиеся английские слова, такие как я, я, и, должен и т. д. Удаление стоп-слов — это процесс фильтрации стоп-слов из текста. Удаляя стоп-слова, мы уделяем больше внимания важной информации, поскольку во многих сценариях стоп-слова не нужны (не во всех сценариях, но во многих!).
Удаление стоп-слов в NLTK
Встроенной функции для удаления стоп-слов из строки нет, но в NLTK есть список английских стоп-слов, доступ к которому можно получить с помощью класса стоп-слов (показан ниже). Мы напишем собственный код для фильтрации стоп-слов, присутствующих в этом списке. Весь список стоп-слов NLTK написан строчными буквами, поэтому нам нужно будет изменить каждый отдельный токен на строчный и проверить, присутствует ли он в списке стоп-слов. Если это не так, то мы добавим его в отфильтрованный список. Все это можно сделать в одной строке, используя понимание списка, как показано ниже:
Вывод: [‘нравится’, ‘естественный’, ‘язык’, ‘обработка’, ‘.’, ‘интересный’, ‘.’]
После фильтрации стоп-слова они обычно не восстанавливаются, поскольку отфильтрованное предложение, вероятно, будет использоваться для других целей, таких как классификация текста; однако, если вы хотите сделать его строкой, NLTK предоставляет удобный детокенизатор под названием Treebank detokenizer.
Удаление стоп-слова в TextBlob
TextBlob не предоставляет функции для удаления стоп-слов, поэтому лучший способ сделать это — использовать список стоп-слов, предоставленный NLTK. После создания объекта TextBlob мы используем тот же процесс, что и для NLTK. Мы используем понимание списка для создания списка filtered_sentence, проверяя каждый отдельный токен, чтобы увидеть, находится ли он в списке стоп-слов или нет.
Вывод: [‘нравится’, ‘естественно’, ‘язык’, ‘обработка’, ‘интересно’]
Удаление стоп-слов в SpaCy
Процесс удаления стоп-слов в SpaCy немного отличается. Вместо использования списка, который предоставляет SpaCy (что он и делает), мы можем вместо этого использовать атрибут is_stop для каждого токена, чтобы проверить, является ли он стоп-словом. Мы снова будем использовать понимание списка, так как оно уменьшает объем кода, который нам нужно написать.
Вывод: [нравится, естественный, язык, обработка, ., интересный, .]
Лемматизация и стемминг
Лемматизация и стемминг похожи: в обоих случаях мы сводим слово к корню. При стемминге этот корень называется стеблем, а при лемматизации этот корень называется леммой.
Основное различие между ними заключается в том, что лемматизация группирует слова на основе определения корня и может использоваться для различения настоящего, прошедшего и неопределенного времени. Давайте рассмотрим несколько примеров:
Учеба → Учеба
Прогулки → Прогулка
Лучше → Хорошо
Корпус → Корпус
С другой стороны, основное работает, отсекая конец (суффикс) или начало (префикс) слова, используя список общих префиксов и суффиксов.
Учеба → Студии
Прогулка → Прогулка
Прогулки → Прогулка
Прогулка → Прогулка
Лучше → Лучше
Корпуса → Корпуса
Поскольку стемминг удаляет последние несколько символов слова, это может привести к неправильному значению и написанию, как мы видим в первом примере (Учеба → Учеба).
Лемматизация в NLTK
В NLTK есть класс WordNetLemmatizer, который мы и будем использовать. Сначала мы создаем объект WordNetLemmatizer, а затем вызываем функцию lemmatize для слова. Примечание. Для WordNetLemmatizer слова должны быть в нижнем регистре.
По умолчанию функция lemmatize предполагает, что слово является существительным. Если это не так, функция имеет параметр с именем «pos», где вы можете ввести часть речи. Например, если у вас есть прилагательное, вы должны передать «а» в качестве второго аргумента.
Стемминг в NLTK
NLTK имеет класс под названием PorterStemmer, стеммер слов, основанный на алгоритме стемминга Портера. Сначала мы создадим список слов, создадим объект PorterStemmer, затем пройдемся по списку и воспользуемся функцией stem() для определения основы каждого слова.
Лемматизация в TextBlob
TextBlob содержит объект Word, который мы можем создать. Затем мы можем использовать функцию lemmatize() этого объекта, а параметр, который мы передаем, является частью речи. По умолчанию это существительное, аналогично NLTK.
Для каждого слова мы создаем объект слова и вызываем функцию lemmatize() этого объекта. В скобках указана часть речи («a» для прилагательного, «v» для глагола, по умолчанию существительное).
Стемминг в TextBlob
Процесс выделения в TextBlob аналогичен тому, что мы делали для лемматизации. Сначала мы создаем объект слова, а затем вызываем функцию stem(). TextBlob по умолчанию использует алгоритм PorterStemmer. Так как функция Stem() не требует каких-либо параметров части речи, которые варьируются от слова к слову, мы можем создать список слов, пройтись по списку и выделить каждое слово.
Лемматизация в SpaCy
В SpaCy мы создадим объект nlp, как мы делали это раньше, а затем пройдемся по токенам. Для каждого токена есть атрибут с именем lemma_, и мы можем получить к нему доступ с помощью token.lemma_, как показано ниже.
Стемминг в spaCy
spaCy не содержит никаких функций для стемминга. Поэтому для стемминга нам придется использовать библиотеку NLTK:
Распознавание именованных объектов
Цель NER (распознавание именованных объектов) состоит в том, чтобы найти и классифицировать именованные объекты (имена людей, организаций, стран, количества и т. д.) в тексте. Это этап извлечения информации, который можно использовать для ответа на конкретные вопросы, например, какие компании или организации упоминались в статье.
Давайте используем следующее предложение для NER: Илон Маск — генеральный директор Tesla, которая была основана в 2003 году.
NER в NLTK
Сначала мы разберем предложение выше и найдем теги частей речи. Затем мы будем использовать функцию ne_chunk() для фрагментации (извлечения фраз из неструктурированного текста) заданного списка помеченных токенов.
Он возвращает объект Tree, который мы можем вывести в виде текста или создать график с помощью функции draw().
Выход:
(S
(ЛИЦО Илон/NNP)
(ОРГАНИЗАЦИЯ Маск/ННП)
есть/ВБЗ
/ДТ
(ГЕНЕРАЛЬНЫЙ ДИРЕКТОР ОРГАНИЗАЦИИ/Н.Н./В Тесла/Н.П.)
,/,
который / ВДТ
был/ВБД
основано/VBN
in/IN
2003/CD
./.)
Это в основном правильно. Он классифицировал «Илона» как человека, «Маска» как организацию (неверно) и «генерального директора Tesla» как организацию. Он пропустил 2003 год (дата считается именованной сущностью). Распознавание именованных сущностей пока не является точным на 100%, но, вероятно, в будущем оно будет улучшаться.
NER в TextBlob
TextBlob не содержит никаких функций для NER; следовательно, это необходимо сделать с помощью NLTK, как мы сделали для удаления стоп-слова (ранее в этой статье).
NER в spaCy
Когда мы создаем объект NLP в spaCy, он имеет атрибут ents, в котором перечислены именованные объекты, найденные в заданном тексте. Мы можем прокрутить этот список и распечатать текст и метку каждой сущности. В spaCy также есть визуализатор под названием displacy, который выделяет именованные объекты в предложении.
Выход:
Тесла ОРГ
2003 ДАТА
Как видите, две найденные сущности помечены правильно, но Илон Маск пропущен как сущность.
Анализ настроений
Последняя задача НЛП, которую мы рассмотрим в этой статье, — анализ настроений. Основная цель анализа тональности — определить полярность текста (будь то положительная, отрицательная или нейтральная).
Анализ настроений в NLTK
NLTK имеет встроенный предварительно обученный анализатор настроений под названием VADER (Valence Aware Dictionary and SEntiment Reasoner). В нем есть функция polarity_scores(), которая принимает строку в качестве параметра и выводит словарь, содержащий следующую информацию: отрицательные, нейтральные и положительные оценки (все они в сумме дают 1 и не могут быть отрицательным), а также составной балл, который может варьироваться от -1 (самый крайний отрицательный) до 1 (самый крайний положительный). Чем ближе составной балл к +1, тем выше позитивность текста.
Вот как мы будем использовать NLTK для анализа настроений:
Вывод: {'отрицательный': 0.0, 'neu': 0.461, 'pos': 0.539, 'составной': 0.8478}
Анализ настроений в TextBlob
TextBlob позволяет очень легко выполнять анализ тональности. Мы можем использовать атрибут sentiment объекта TextBlob, который возвращает два значения — полярность (от -1 до 1) и субъективность (от 0 до 1). Субъективность определяет, насколько субъективен или объективен текст, где значения ближе к 1 более субъективны.
Выход:
0.55
1.0
Анализ настроений в spaCy
В spaCy нет удобной функции для анализа настроений, как в NLTK и TextBlob. По этой причине мы не будем рассматривать анализ настроений в spaCy, так как это процесс, который включает в себя множество шагов, включая разработку и обучение модели машинного обучения. Если вам интересно, вы можете ознакомиться с официальной документацией spaCy, чтобы узнать, как обучать модели. Ссылка: https://spacy.io/usage/training
Заключение
NLTK, TextBlob и spaCy — отличные библиотеки для НЛП. Как вы видели, между ними есть несколько различий, но по большей части все они могут использоваться для большинства задач обработки естественного языка. Основываясь на моем личном опыте, TextBlob является самой простой в освоении из трех вышеупомянутых библиотек, и я рекомендую начать с TextBlob, а для более продвинутых функций хорошим выбором будет NLTK. Если вы ищете еще более продвинутую обработку естественного языка, было бы полезно также изучить spaCy.
Спасибо за чтение!