Python для NLP: токенизация, стемминг и лемматизация с библиотекой SpaCy

В предыдущей статье [/ python-for-nlp-working-with-text-and-pdf-files /] мы начали обсуждение того, как выполнять обработку естественного языка с помощью Python. Мы увидели, как читать и писать текстовые и PDF-файлы. В этой статье мы начнем работать с библиотекой spaCy [https://spacy.io/] для выполнения еще нескольких основных задач НЛП, таких как токенизация [https://en.wikipedia.org/wiki/Lexical_analysis#Tokenization] , стемминг и лемматизация [https://nlp.stanford.edu/IR-book/html/htmledition/stemming-

В предыдущей статье мы начали обсуждение того, как выполнять обработку естественного языка с помощью 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.

comments powered by Disqus