В предыдущей статье мы начали обсуждение того , как обрабатывать естественный язык с помощью Python. Мы видели, как читать и писать текстовые и PDF-файлы. В этой статье мы начнем работать с библиотекой space для выполнения еще нескольких базовых задач НЛП, таких как токенизация , стемминг и лемматизация .
Введение в космос
Космическая библиотека является одной из самых популярных библиотек НЛП наряду с НЛТК. Основное различие между этими двумя библиотеками заключается в том, что NLTK содержит большое разнообразие алгоритмов для решения одной задачи, в то время как spaCy содержит только один, но лучший алгоритм для решения задачи.
NLTK был выпущен еще в 2001 году, в то время как space является относительно новым и был разработан в 2015 году. В этой серии статей по НЛП мы будем в основном иметь дело с пространством, в силу его современной природы. Однако мы также коснемся NLTK, когда легче выполнить задачу с помощью NLTK, а не пространства.
Установка пространства
Если вы используете установщик pip для установки библиотек Python, перейдите в командную строку и выполните следующую инструкцию:
$ pip install -U spacy
В противном случае, если вы используете Anaconda, вам необходимо выполнить следующую команду в командной строке Anaconda:
$ conda install -c conda-forge spacy
После загрузки и установки space следующим шагом будет загрузка языковой модели. Мы будем использовать модель английского языка. Языковая модель используется для выполнения различных задач НЛП, которые мы увидим в следующем разделе.
Следующая команда загружает языковую модель:
$ python -m spacy download en
Основные Функциональные возможности
Прежде чем мы углубимся в различные функции пространства, давайте кратко рассмотрим, как с ним работать.
В качестве первого шага вам нужно импортировать библиотеку space
следующим образом:
import spacy
Далее нам нужно загрузить модель языка пространства.
sp = spacy.load('en_core_web_sm')
В приведенном выше сценарии мы используем функцию load
из библиотеки space
для загрузки основной модели английского языка. Модель хранится в переменной sp
.
Давайте теперь создадим небольшой документ, используя эту модель. Документ может быть предложением или группой предложений и может иметь неограниченную длину. Следующий сценарий создает простой документ пространства.
sentence = sp(u'Manchester United is looking to sign a forward for $90 million')
Пространство автоматически разбивает ваш документ на маркеры, когда документ создается с помощью модели.
Лексема просто относится к отдельной части предложения, имеющей некоторое семантическое значение. Давайте посмотрим, какие токены у нас есть в нашем документе:
for word in sentence: print(word.text)
Вывод приведенного выше скрипта выглядит следующим образом:
Manchester United is looking to sign a forward for $ 90 million
Вы можете видеть, что у нас есть следующие маркеры в нашем документе. Мы также можем видеть части речи каждого из этих токенов, используя атрибут .pos_
, показанный ниже:
for word in sentence: print(word.text, word.pos_)
Выход:
Manchester PROPN United PROPN is VERB looking VERB to PART sign VERB a DET forward NOUN for ADP $ SYM 90 NUM million NUM
Вы можете видеть, что каждому слову или знаку в нашем предложении была присвоена часть речи. Например,” Манчестер “был помечен как имя собственное,” Смотреть ” – как глагол и так далее.
Наконец, в дополнение к частям речи мы также можем видеть зависимости.
Давайте создадим еще один документ:
sentence2 = sp(u"Manchester United isn't looking to sign any forward.")
Для анализа зависимостей используется атрибут dep_
, как показано ниже:
for word in sentence2: print(word.text, word.pos_, word.dep_)
Вывод выглядит следующим образом:
Manchester PROPN compound United PROPN nsubj is VERB aux n't ADV neg looking VERB ROOT to PART aux sign VERB xcomp any DET advmod forward ADV advmod . PUNCT punct
Из выходных данных вы можете видеть, что пространство достаточно разумно, чтобы найти зависимость между токенами, например, в предложении у нас было слово is'nt
. Синтаксический анализатор зависимостей разбил его на два слова и указывает, что n't
на самом деле является отрицанием предыдущего слова.
Для получения подробного понимания синтаксического анализа зависимостей обратитесь к этой статье .
Помимо печати слов, вы также можете печатать предложения из документа.
document = sp(u'Hello from Stackabuse. The site with the best Python Tutorials. What are you looking for?')
Теперь мы можем повторить каждое предложение, используя следующий сценарий:
for sentence in document.sents: print(sentence)
Вывод скрипта выглядит следующим образом:
Hello from Stackabuse. The site with the best Python Tutorials. What are you looking for?
Вы также можете проверить, начинается ли предложение с определенного маркера или нет. Вы можете получить отдельные токены, используя индекс и квадратные скобки, как массив:
document[4]
В приведенном выше сценарии мы ищем 5-е слово в документе. Имейте в виду, что индекс начинается с нуля, а период считается токеном. В выводе вы должны увидеть:
The
Теперь посмотрим, начинается ли какое-либо предложение в документе с , мы можем использовать атрибут
is_sent_start
, как показано ниже:
document[4].is_sent_start
В выводе вы увидите True
так как токен используется в начале второго предложения.
В этом разделе мы увидели несколько основных операций космической библиотеки. Давайте теперь копнем глубже и рассмотрим Токенизацию, Стемминг и лемматизацию в деталях.
Токенизация
Как объяснялось ранее, токенизация-это процесс разбиения документа на слова, знаки препинания, цифры и т. Д.
Давайте подробно рассмотрим маркировку пространства. Создайте новый документ с помощью следующего сценария:
sentence3 = sp(u'"They\'re leaving U.K. for U.S.A."') print(sentence3)
Вы можете видеть, что предложение содержит кавычки в начале и в конце. Он также содержит знаки препинания в аббревиатурах “U. K” и “U. S. A.”
Давайте посмотрим, как Спейси маркирует это предложение.
for word in sentence3: print(word.text)
Выход:
" They 're leaving U.K. for U.S.A. "
В выходных данных вы можете видеть, что пробел маркировал начальные и конечные двойные кавычки. Однако он достаточно умен, чтобы не маркировать точку препинания, используемую между аббревиатурами, такими как Великобритания и США.
Давайте рассмотрим еще один пример токенизации:
sentence4 = sp(u"Hello, I am non-vegetarian, email me the menu at [email protected]") print(sentence4)
Здесь, в приведенном выше предложении, у нас есть тире в слове “невегетарианский” и в адресе электронной почты. Давайте посмотрим, как пространство будет маркировать это:
for word in sentence4: print(word.text)
Выход:
Hello , I am non - vegetarian , email me the menu at [email protected]
Из выходных данных видно, что Спейси действительно смог обнаружить электронное письмо, и он не маркировал его, несмотря на наличие “-“. С другой стороны, слово “невегетарианский” было маркировано.
Давайте теперь посмотрим, как мы можем считать слова в документе:
len(sentence4)
В выходных данных вы увидите 14, что является количеством токенов в предложении 4
.
Обнаружение Сущностей
В дополнение к маркировке документов словами, вы также можете узнать, является ли это слово сущностью, такой как компания, место, здание, валюта, учреждение и т. Д.
Давайте рассмотрим простой пример распознавания именованных сущностей:
sentence5 = sp(u'Manchester United is looking to sign Harry Kane for $90 million')
Давайте сначала попробуем просто токенизировать его:
for word in sentence5: print(word.text)
Выход:
Manchester United is looking to sign Harry Kane for $ 90 million
Мы знаем, что “Манчестер Юнайтед” – это одно слово, поэтому его не следует делить на два слова. Точно так же “Гарри Кейн” – это имя человека, а “90 миллионов долларов” – это стоимость валюты. Они также не должны быть токенизированы.
Вот тут-то и вступает в игру распознавание именованных сущностей . Чтобы получить именованные сущности из документа, необходимо использовать атрибут ents
. Давайте извлекем именованные сущности из приведенного выше предложения. Выполните следующий сценарий:
for entity in sentence.ents: print(entity.text + ' - ' + entity.label_ + ' - ' + str(spacy.explain(entity.label_)))
В приведенном выше сценарии мы печатаем текст сущности, метку сущности и детали сущности. Вывод выглядит следующим образом:
Выход:
Manchester United - ORG - Companies, agencies, institutions, etc. Harry Kane - PERSON - People, including fictional $90 million - MONEY - Monetary values, including unit
Вы можете видеть, что распознаватель именованных сущностей Спейси успешно распознал “Манчестер Юнайтед” как организацию, “Гарри Кейна” как личность и “90 миллионов долларов” как денежную ценность.
Обнаружение Существительных
В дополнение к обнаружению именованных сущностей, существительные также могут быть обнаружены. Для этого используется атрибут noun_chunks
. Рассмотрим следующее предложение:
sentence5 = sp(u'Latest Rumours: Manchester United is looking to sign Harry Kane for $90 million')
Давайте попробуем найти существительные из этого предложения:
for noun in sentence5.noun_chunks: print(noun.text)
Выход:
Latest Rumours Manchester United Harry Kane
Из выходных данных вы можете видеть, что существительное также может быть именованной сущностью и наоборот.
Вытекающий
Стеммирование означает приведение слова к его корневой форме. При выполнении задач обработки естественного языка вы столкнетесь с различными сценариями, в которых вы найдете разные слова с одним и тем же корнем. Например, вычислить, компьютер, вычисление, компьютер и т. Д. Возможно, вы захотите свести слова к их корневой форме ради единообразия. Вот тут-то и вступает в игру стемминг.
Возможно, вас это удивит, но пространство не содержит никакой функции для стемминга, поскольку оно опирается только на лемматизацию. Поэтому в этом разделе мы будем использовать NLTK для стемминга.
В NLTK есть два типа стеммеров: Porter Stemmer и Snowball stemmer . Оба они были реализованы с использованием различных алгоритмов.
Porter Stemmer
Let’s see porter stemmer в действии:
import nltk from nltk.stem.porter import *
Let’s create a class of PorterStemmer
.
stemmer = PorterStemmer()
Предположим, у нас есть следующий список, и мы хотим свести эти слова к stem:
tokens = ['compute', 'computer', 'computed', 'computing']
Следующий сценарий находит основу для слов в списке с помощью porter stemmer:
for token in tokens: print(token + ' --> ' + stemmer.stem(token))
Результат выглядит следующим образом:
compute --> comput computer --> comput computed --> comput computing --> comput
Вы можете видеть, что все 4 слова были сведены к “компьютеру”, который на самом деле вообще не является словом.
Стеммер снежного кома
Snowball stemmer является слегка улучшенной версией Porter stemmer и обычно предпочтительнее последнего. Давайте посмотрим снежок стеммер в действии:
from nltk.stem.snowball import SnowballStemmer stemmer = SnowballStemmer(language='english') tokens = ['compute', 'computer', 'computed', 'computing'] for token in tokens: print(token + ' --> ' + stemmer.stem(token))
В приведенном выше сценарии мы использовали Snowball stemmer, чтобы найти стебель тех же 4 слов, которые мы использовали с porter stemmer. Вывод выглядит следующим образом:
compute --> comput computer --> comput computed --> comput computing --> comput
Вы можете видеть, что результаты те же. У нас все еще есть “компут” в качестве стержня. Опять же, это слово “компьютер” на самом деле не является словарным словом.
Вот тут-то и пригодится лемматизация. Лемматизация сводит слово к его корню, как оно появляется в словаре. Стебли, возвращаемые посредством лемматизации, являются реальными словарными словами и семантически полны в отличие от слов, возвращаемых стеммером.
Лемматизация
Хотя мы не могли бы выполнить стемминг с пространством, мы можем выполнить лемматизацию с использованием пространства.
Для этого нам нужно использовать атрибут lemma_
в документе space. Предположим, у нас есть следующее предложение:
sentence6 = sp(u'compute computer computed computing')
Мы можем найти корни всех слов с помощью пространственной лемматизации следующим образом:
for word in sentence6: print(word.text, word.lemma_)
Вывод приведенного выше скрипта выглядит следующим образом:
compute compute computer computer computed compute computing computing
Вы можете видеть, что в отличие от стемминга, где корень, который мы получили, был “вычислить”, корни, которые мы получили здесь, являются реальными словами в словаре.
Лемматизация преобразует слова во второй или третьей формах в их варианты первой формы. Посмотрите на следующий пример:
sentence7 = sp(u'A letter has been written, asking him to be released') for word in sentence7: print(word.text + ' ===>', word.lemma_)
Выход:
A ===> a letter ===> letter has ===> have been ===> be written ===> write , ===> , asking ===> ask him ===> -PRON- to ===> to be ===> be released ===> release
Из выходных данных ясно видно, что слова во второй и третьей формах, такие как “написано”, “выпущено” и т. Д., Были преобразованы в первую форму, т. е.
Вывод
Токенизация, Стеммирование и лемматизация являются одними из самых фундаментальных задач обработки естественного языка. В этой статье мы рассмотрели, как мы можем выполнять токенизацию и лемматизацию с помощью космической библиотеки. Мы также видели, как NLTK можно использовать для стемминга. В следующей статье мы начнем наше обсуждение лексики и сопоставления фраз в Python.