В предыдущей статье мы начали обсуждение того, как выполнять обработку естественного языка с помощью Python. Мы увидели, как читать и писать текстовые и PDF-файлы. В этой статье мы начнем работать с библиотекой spaCy для выполнения еще нескольких основных задач НЛП, таких как токенизация , стемминг и лемматизация .
Введение в SpaCy
Библиотека spaCy - одна из самых популярных библиотек NLP наряду с NLTK. Основное различие между двумя библиотеками заключается в том, что NLTK содержит широкий спектр алгоритмов для решения одной проблемы, тогда как spaCy содержит только один, но лучший алгоритм для решения проблемы.
NLTK был выпущен еще в 2001 году, в то время как spaCy является относительно новым и был разработан в 2015 году. В этой серии статей о NLP мы в основном будем иметь дело с spaCy из-за его современного состояния. Однако мы также коснемся NLTK, когда легче выполнить задачу, используя NLTK, а не spaCy.
Установка spaCy
Если вы используете установщик pip для установки библиотек Python, перейдите в командную строку и выполните следующую инструкцию:
$ pip install -U spacy
В противном случае, если вы используете Anaconda, вам необходимо выполнить следующую команду в командной строке Anaconda:
$ conda install -c conda-forge spacy
После загрузки и установки spaCy следующим шагом будет загрузка языковой модели. Мы будем использовать англоязычную модель. Языковая модель используется для выполнения множества задач НЛП, которые мы увидим в следующем разделе.
Следующая команда загружает языковую модель:
$ python -m spacy download en
Базовая функциональность
Прежде чем мы углубимся в различные функции spaCy, давайте вкратце посмотрим, как с ним работать.
В качестве первого шага вам необходимо импортировать spacy
библиотеку
следующим образом:
import spacy
Далее нам нужно загрузить языковую модель spaCy.
sp = spacy.load('en_core_web_sm')
В приведенном выше скрипте мы используем функцию load
spacy
библиотеки для загрузки базовой английской языковой модели. Модель
хранится в переменной sp
Давайте теперь создадим небольшой документ, используя эту модель. Документ может быть предложением или группой предложений и может иметь неограниченную длину. Следующий скрипт создает простой документ spaCy.
sentence = sp(u'Manchester United is looking to sign a forward for $90 million')
SpaCy автоматически разбивает ваш документ на токены, когда документ создается с использованием модели.
Токен просто относится к отдельной части предложения, имеющей некоторое семантическое значение. Посмотрим, какие токены есть в нашем документе:
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
Из выходных данных вы можете видеть, что spaCy достаточно умен, чтобы
найти зависимость между токенами, например, в предложении, которое у нас
есть, есть слово 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
Теперь, чтобы увидеть, начинается ли какое-либо предложение в документе
с The
, мы можем использовать is_sent_start
как показано ниже:
document[4].is_sent_start
На выходе вы увидите True
поскольку токен The
используется в начале
второго предложения.
В этом разделе мы увидели несколько основных операций библиотеки spaCy. Давайте теперь копнем глубже и подробно рассмотрим токенизацию, стемминг и лемматизацию.
Токенизация
Как объяснялось ранее, токенизация - это процесс разбиения документа на слова, знаки препинания, числовые цифры и т. Д.
Рассмотрим подробнее токенизацию spaCy. Создайте новый документ, используя следующий скрипт:
sentence3 = sp(u'"They\'re leaving UK for USA"')
print(sentence3)
Вы можете видеть, что предложение содержит кавычки в начале и в конце. Он также содержит знаки препинания в сокращениях «UK» и «USA».
Посмотрим, как spaCy токенизует это предложение.
for word in sentence3:
print(word.text)
Выход:
"
They
're
leaving
UK
for
USA
"
В выходных данных вы можете видеть, что spaCy разметила начальную и конечную двойные кавычки. Тем не менее, он достаточно умен, чтобы не размечать точку пунктуации между аббревиатурами, такими как UK и USA.
Посмотрим еще один пример токенизации:
sentence4 = sp(u"Hello, I am non-vegetarian, email me the menu at [email protected] ")
print(sentence4)
Здесь, в предложении выше, у нас есть тире в слове «невегетарианец» и в адресе электронной почты. Посмотрим, как spaCy это токенизирует:
for word in sentence4:
print(word.text)
Выход:
Hello
,
I
am
non
-
vegetarian
,
email
me
the
menu
at
[email protected]
Из выходных данных видно, что spaCy действительно смог обнаружить электронное письмо и не токенизировал его, несмотря на наличие знака «-». С другой стороны, слово «невегетарианец» было символическим.
Давайте теперь посмотрим, как мы можем подсчитать слова в документе:
len(sentence4)
На выходе вы увидите 14 - количество токенов в sentence4
.
Обнаружение сущностей
Помимо токенизации документов в слова, вы также можете узнать, является ли слово сущностью, такой как компания, место, здание, валюта, учреждение и т. Д.
Давайте посмотрим на простой пример распознавания именованных сущностей:
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
Вы можете видеть, что средство распознавания именованных сущностей spaCy успешно распознало «Манчестер Юнайтед» как организацию, «Гарри Кейна» как личность и «90 миллионов долларов» как денежную ценность.
Обнаружение существительных
Помимо обнаружения именованных сущностей, также могут быть обнаружены
существительные. Для этого noun_chunks
атрибут 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
Из выходных данных вы можете видеть, что существительное также может быть именованным объектом, и наоборот.
Стемминг
Основание относится к приведению слова к его корневой форме. При выполнении задач обработки естественного языка вы столкнетесь с различными сценариями, в которых вы найдете разные слова с одним и тем же корнем. Например, compute, computer, computing, computed и т. Д. Вы можете уменьшить слова до их корневой формы для единообразия. Вот тут-то и вступает в игру стемминг.
Это может вас удивить, но в spaCy нет функции для стемминга, поскольку он полагается только на лемматизацию. Поэтому в этом разделе мы будем использовать NLTK для стемминга.
В NLTK есть два типа стеммеров: Porter Stemmer и Snowball . Оба они были реализованы с использованием разных алгоритмов.
Портер Стеммер
Давайте посмотрим на стеммер портера в действии:
import nltk
from nltk.stem.porter import *
Создадим класс PorterStemmer
.
stemmer = PorterStemmer()
Предположим, у нас есть следующий список, и мы хотим сократить эти слова до основы:
tokens = ['compute', 'computer', 'computed', 'computing']
Следующий скрипт находит основу для слов в списке с помощью стеммера портера:
for token in tokens:
print(token + ' --> ' + stemmer.stem(token))
Результат выглядит следующим образом:
compute --> comput
computer --> comput
computed --> comput
computing --> comput
Вы можете видеть, что все 4 слова были сокращены до «вычислить», что на самом деле вовсе не слово.
Снежок Стеммер
Стеммер Snowball - это немного улучшенная версия стеммера Porter, которую обычно предпочитают последнему. Давайте посмотрим на стеммер снежка в действии:
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, чтобы найти основу тех же 4 слов, что и стеммер портера. Результат выглядит так:
compute --> comput
computer --> comput
computed --> comput
computing --> comput
Вы можете видеть, что результаты такие же. У нас все еще есть «вычислитель» в качестве основы. Опять же, слово «вычислить» на самом деле не словарное.
Вот тут-то и пригодится лемматизация. Лемматизация сокращает слово до основы, как оно появляется в словаре. Основы, возвращаемые посредством лемматизации, являются фактическими словарными словами и семантически полными, в отличие от слов, возвращаемых стеммером.
Лемматизация
Хотя мы не могли выполнить стемминг с помощью spaCy, мы можем выполнить лемматизацию с помощью spaCy.
Для этого нам нужно использовать lemma_
атрибут на Spacy документа.
Предположим, у нас есть следующее предложение:
sentence6 = sp(u'compute computer computed computing')
Мы можем найти корни всех слов с помощью лемматизации spaCy следующим образом:
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
Из выходных данных ясно видно, что слова во второй и третьей формах, такие как «написано», «выпущено» и т. Д., Были преобразованы в первую форму, то есть «запись» и «выпуск».
Заключение
Токенизация, стемминг и лемматизация - одни из самых фундаментальных задач обработки естественного языка. В этой статье мы увидели, как мы можем выполнить токенизацию и лемматизацию с помощью библиотеки spaCy. Мы также увидели, как NLTK можно использовать для стемминга. В следующей статье мы начнем обсуждение словарного запаса и сопоставления фраз в Python.