Python для НЛП: словарный запас и сопоставление фраз с помощью SpaCy

Это третья статья из этой серии статей о Python для обработки естественного языка. В предыдущей статье [/ python-for-nlp-tokenization-stemming-and-lemmatization-with-spacy-library /] мы увидели, как библиотеки Python NLTK и spaCy [https://spacy.io/] могут использоваться для выполнять простые задачи НЛП, такие как токенизация [https://en.wikipedia.org/wiki/Lexical_analysis#Tokenization], стемминг и лемматизация [https://nlp.stanford.edu/IR-book/html/htmledition/stemming-and -лемматизация-1.html

Это третья статья из этой серии статей о Python для обработки естественного языка. В предыдущей статье мы увидели, как библиотеки Python NLTK и spaCy могут использоваться для выполнения простых задач NLP, таких как токенизация , стемминг и лемматизация . Мы также увидели, как выполнять части речевого тегирования, распознавания именованных сущностей и синтаксического анализа существительных. Однако все эти операции выполняются над отдельными словами.

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

Соответствие на основе правил

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

Для сопоставления на основе правил вам необходимо выполнить следующие шаги:

Создание объекта соответствия

Первым шагом является создание объекта сопоставления:

 import spacy 
 nlp = spacy.load('en_core_web_sm') 
 
 from spacy.matcher import Matcher 
 m_tool = Matcher(nlp.vocab) 

Определение шаблонов

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

 p1 = [{'LOWER': 'quickbrownfox'}] 
 p2 = [{'LOWER': 'quick'}, {'IS_PUNCT': True}, {'LOWER': 'brown'}, {'IS_PUNCT': True}, {'LOWER': 'fox'}] 
 p3 = [{'LOWER': 'quick'}, {'LOWER': 'brown'}, {'LOWER': 'fox'}] 
 p4 = [{'LOWER': 'quick'}, {'LOWER': 'brownfox'}] 

В приведенном выше сценарии

  • p1 ищет фразу "quickbrownfox"
  • p2 ищет фразу "quick-brown-fox"
  • p3 пытается найти "qucik brown fox"
  • p4 ищет фразу "quick brownfox"

Атрибут токена LOWER определяет, что фраза должна быть преобразована в нижний регистр перед сопоставлением.

Как только шаблоны определены, нам нужно добавить их к Matcher который мы создали ранее.

 m_tool.add('QBF', None, p1, p2, p3, p4) 

Здесь QBF - это имя нашего сопоставителя. Вы можете дать ему любое имя.

Применение Matcher к документу

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

 sentence = nlp(u'The quick-brown-fox jumps over the lazy dog. The quick brown fox eats well. \ 
 the quickbrownfox is dead. the dog misses the quick brownfox') 

Чтобы применить сопоставление к документу. Документ необходимо передать в качестве параметра объекту сопоставления. Результатом будут все идентификаторы фраз, сопоставленных в документе, а также их начальная и конечная позиции в документе. Выполните следующий скрипт:

 phrase_matches = m_tool(sentence) 
 print(phrase_matches ) 

Результат выполнения сценария выше выглядит следующим образом:

 [(12825528024649263697, 1, 6), (12825528024649263697, 13, 16), (12825528024649263697, 21, 22), (12825528024649263697, 29, 31)] 

Из вывода вы можете видеть, что найдено четыре фразы. Первое длинное число в каждом выводе - это идентификатор совпавшей фразы, второе и третье числа - это начальная и конечная позиции фразы.

Чтобы на самом деле лучше просмотреть результат, мы можем перебирать каждую совпавшую фразу и отображать ее строковое значение. Выполните следующий скрипт:

 for match_id, start, end in phrase_matches: 
 string_id = nlp.vocab.strings[match_id] 
 span = sentence[start:end] 
 print(match_id, string_id, start, end, span.text) 

Выход:

 12825528024649263697 QBF 1 6 quick-brown-fox 
 12825528024649263697 QBF 13 16 quick brown fox 
 12825528024649263697 QBF 21 22 quickbrownfox 
 12825528024649263697 QBF 29 31 quick brownfox 

На выходе вы можете увидеть все совпавшие фразы вместе с их словарными идентификаторами, а также начальной и конечной позицией.

Дополнительные параметры сопоставления на основе правил

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

Например, атрибут «*» определен для поиска одного или нескольких экземпляров токена.

Давайте напишем простой шаблон, который может идентифицировать фразу «быстро - коричневый - лисица» или быстро - коричневый - лиса.

Сначала удалим предыдущее сопоставление QBF .

 m_tool.remove('QBF') 

Далее нам нужно определить наш новый паттерн:

 p1 = [{'LOWER': 'quick'}, {'IS_PUNCT': True, 'OP':'*'}, {'LOWER': 'brown'}, {'IS_PUNCT': True, 'OP':'*'}, {'LOWER': 'fox'}] 
 m_tool.add('QBF', None, p1) 

Шаблон p1 будет соответствовать всем фразам, в которых есть одна или несколько знаков препинания во фразе quick brown fox . Теперь давайте определим наш документ для фильтрации:

 sentence = nlp(u'The quick--brown--fox jumps over the quick-brown---fox') 

Вы можете видеть, что в нашем документе есть две фразы quick - brown - fox и quick-brown - fox, которые должны соответствовать нашему шаблону. Применим нашу матрицу к документу и посмотрим на результат:

 phrase_matches = m_tool(sentence) 
 
 for match_id, start, end in phrase_matches: 
 string_id = nlp.vocab.strings[match_id] 
 span = sentence[start:end] 
 print(match_id, string_id, start, end, span.text) 

Результат выполнения сценария выше выглядит следующим образом:

 12825528024649263697 QBF 1 6 quick--brown--fox 
 12825528024649263697 QBF 10 15 quick-brown---fox 

Из вывода вы можете видеть, что наш сопоставитель успешно сопоставил две фразы.

Фразовое соответствие

В последнем разделе мы увидели, как мы можем определить правила, которые можно использовать для идентификации фраз из документа. Помимо определения правил, мы можем напрямую указать фразы, которые мы ищем.
Это более эффективный способ сопоставления фраз.

В этом разделе мы будем выполнять сопоставление фраз в статье Википедии об искусственном интеллекте.

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

 import bs4 as bs 
 import urllib.request 
 import re 
 import nltk 
 
 scrapped_data = urllib.request.urlopen('https://en.wikipedia.org/wiki/Artificial_intelligence') 
 article = scrapped_data .read() 
 
 parsed_article = bs.BeautifulSoup(article,'lxml') 
 
 paragraphs = parsed_article.find_all('p') 
 
 article_text = "" 
 
 for p in paragraphs: 
 article_text += p.text 
 
 
 processed_article = article_text.lower() 
 processed_article = re.sub('[^a-zA-Z]', ' ', processed_article ) 
 processed_article = re.sub(r'\s+', ' ', processed_article) 

Сценарий подробно описан в моей статье « Реализация Word2Vec с библиотекой Gensim в Python». Вы можете пойти и прочитать статью, если хотите понять, как работает синтаксический анализ в Python.

processed_article содержит документ, который мы будем использовать для сопоставления фраз.

Действия по выполнению сопоставления фраз очень похожи на сопоставление на основе правил.

Создать объект сопоставления фраз

В качестве первого шага вам нужно создать объект PhraseMatcher Это делает следующий сценарий:

 import spacy 
 nlp = spacy.load('en_core_web_sm') 
 
 
 from spacy.matcher import PhraseMatcher 
 phrase_matcher = PhraseMatcher(nlp.vocab) 

Обратите внимание, что в предыдущем разделе мы создали объект Matcher В данном случае мы PhraseMathcer объект PhraseMathcer.

Создать список фраз

На втором этапе вам нужно создать список фраз для сопоставления, а затем преобразовать этот список в документы spaCy NLP, как показано в следующем скрипте:

 phrases = ['machine learning', 'robots', 'intelligent agents'] 
 
 patterns = [nlp(text) for text in phrases] 

Наконец, вам нужно добавить список фраз в средство сопоставления фраз.

 phrase_matcher.add('AI', None, *patterns) 

Здесь имя нашего сопоставителя - AI.

Применение Matcher к документу

Как и сопоставление на основе правил, нам снова нужно применить наш сопоставитель фраз к документу. Однако наша проанализированная статья не в формате документа spaCy. Поэтому мы преобразуем нашу статью в формат документа sPacy, а затем применим к статье наш сопоставитель фраз.

 sentence = nlp (processed_article) 
 
 matched_phrases = phrase_matcher(sentence) 

На выходе у нас будут все идентификаторы всех совпавших фраз вместе с их начальным и конечным индексами в документе, как показано ниже:

 [(5530044837203964789, 37, 39), 
 (5530044837203964789, 402, 404), 
 (5530044837203964789, 693, 694), 
 (5530044837203964789, 1284, 1286), 
 (5530044837203964789, 3059, 3061), 
 (5530044837203964789, 3218, 3220), 
 (5530044837203964789, 3753, 3754), 
 (5530044837203964789, 5212, 5213), 
 (5530044837203964789, 5287, 5288), 
 (5530044837203964789, 6769, 6771), 
 (5530044837203964789, 6781, 6783), 
 (5530044837203964789, 7496, 7498), 
 (5530044837203964789, 7635, 7637), 
 (5530044837203964789, 8002, 8004), 
 (5530044837203964789, 9461, 9462), 
 (5530044837203964789, 9955, 9957), 
 (5530044837203964789, 10784, 10785), 
 (5530044837203964789, 11250, 11251), 
 (5530044837203964789, 12290, 12291), 
 (5530044837203964789, 12411, 12412), 
 (5530044837203964789, 12455, 12456)] 

Чтобы увидеть строковое значение совпадающих фраз, выполните следующий скрипт:

 for match_id, start, end in matched_phrases: 
 string_id = nlp.vocab.strings[match_id] 
 span = sentence[start:end] 
 print(match_id, string_id, start, end, span.text) 

В выводе вы увидите значение strig для совпадающих фраз, как показано ниже:

 5530044837203964789 AI 37 39 intelligent agents 
 5530044837203964789 AI 402 404 machine learning 
 5530044837203964789 AI 693 694 robots 
 5530044837203964789 AI 1284 1286 machine learning 
 5530044837203964789 AI 3059 3061 intelligent agents 
 5530044837203964789 AI 3218 3220 machine learning 
 5530044837203964789 AI 3753 3754 robots 
 5530044837203964789 AI 5212 5213 robots 
 5530044837203964789 AI 5287 5288 robots 
 5530044837203964789 AI 6769 6771 machine learning 
 5530044837203964789 AI 6781 6783 machine learning 
 5530044837203964789 AI 7496 7498 machine learning 
 5530044837203964789 AI 7635 7637 machine learning 
 5530044837203964789 AI 8002 8004 machine learning 
 5530044837203964789 AI 9461 9462 robots 
 5530044837203964789 AI 9955 9957 machine learning 
 5530044837203964789 AI 10784 10785 robots 
 5530044837203964789 AI 11250 11251 robots 
 5530044837203964789 AI 12290 12291 robots 
 5530044837203964789 AI 12411 12412 robots 
 5530044837203964789 AI 12455 12456 robots 

В выходных данных вы можете увидеть все три фразы, которые мы пытались найти, а также их начальный и конечный индексы и идентификаторы строк.

Стоп-слова

Прежде чем мы закончим эту статью, я просто хотел коснуться концепции стоп-слов. Стоп-слова - это английские слова, такие как «the», «a», «an» и т. Д., Которые сами по себе не имеют никакого значения. Стоп-слова часто не очень полезны для задач НЛП, таких как классификация текста или языковое моделирование. Поэтому часто лучше удалить эти стоп-слова перед дальнейшей обработкой документа.

Библиотека spaCy содержит 305 стоп-слов. Кроме того, в зависимости от наших требований, мы также можем добавлять или удалять стоп-слова из библиотеки spaCy.

Чтобы увидеть Spacy по умолчанию стоп - слова в, мы можем использовать stop_words атрибут модели Spacy , как показано ниже:

 import spacy 
 sp = spacy.load('en_core_web_sm') 
 print(sp.Defaults.stop_words) 

На выходе вы увидите все стоп-слова sPacy:

 {'less', 'except', 'top', 'me', 'three', 'fifteen', 'a', 'is', 'those', 'all', 'then', 'everyone', 'without', 'must', 'has', 'any', 'anyhow', 'keep', 'through', 'bottom', 'get', 'indeed', 'it', 'still', 'ten', 'whatever', 'doing', 'though', 'eight', 'various', 'myself', 'across', 'wherever', 'himself', 'always', 'thus', 'am', 'after', 'should', 'perhaps', 'at', 'down', 'own', 'rather', 'regarding', 'which', 'anywhere', 'whence', 'would', 'been', 'how', 'herself', 'now', 'might', 'please', 'behind', 'every', 'seems', 'alone', 'from', 'via', 'its', 'become', 'hers', 'there', 'front', 'whose', 'before', 'against', 'whereafter', 'up', 'whither', 'two', 'five', 'eleven', 'why', 'below', 'out', 'whereas', 'serious', 'six', 'give', 'also', 'became', 'his', 'anyway', 'none', 'again', 'onto', 'else', 'have', 'few', 'thereby', 'whoever', 'yet', 'part', 'just', 'afterwards', 'mostly', 'see', 'hereby', 'not', 'can', 'once', 'therefore', 'together', 'whom', 'elsewhere', 'beforehand', 'themselves', 'with', 'seem', 'many', 'upon', 'former', 'are', 'who', 'becoming', 'formerly', 'between', 'cannot', 'him', 'that', 'first', 'more', 'although', 'whenever', 'under', 'whereby', 'my', 'whereupon', 'anyone', 'toward', 'by', 'four', 'since', 'amongst', 'move', 'each', 'forty', 'somehow', 'as', 'besides', 'used', 'if', 'name', 'when', 'ever', 'however', 'otherwise', 'hundred', 'moreover', 'your', 'sometimes', 'the', 'empty', 'another', 'where', 'her', 'enough', 'quite', 'throughout', 'anything', 'she', 'and', 'does', 'above', 'within', 'show', 'in', 'this', 'back', 'made', 'nobody', 'off', 're', 'meanwhile', 'than', 'neither', 'twenty', 'call', 'you', 'next', 'thereupon', 'therein', 'go', 'or', 'seemed', 'such', 'latterly', 'already', 'mine', 'yourself', 'an', 'amount', 'hereupon', 'namely', 'same', 'their', 'of', 'yours', 'could', 'be', 'done', 'whole', 'seeming', 'someone', 'these', 'towards', 'among', 'becomes', 'per', 'thru', 'beyond', 'beside', 'both', 'latter', 'ours', 'well', 'make', 'nowhere', 'about', 'were', 'others', 'due', 'yourselves', 'unless', 'thereafter', 'even', 'too', 'most', 'everything', 'our', 'something', 'did', 'using', 'full', 'while', 'will', 'only', 'nor', 'often', 'side', 'being', 'least', 'over', 'some', 'along', 'was', 'very', 'on', 'into', 'nine', 'noone', 'several', 'i', 'one', 'third', 'herein', 'but', 'further', 'here', 'whether', 'because', 'either', 'hereafter', 'really', 'so', 'somewhere', 'we', 'nevertheless', 'last', 'had', 'they', 'thence', 'almost', 'ca', 'everywhere', 'itself', 'no', 'ourselves', 'may', 'wherein', 'take', 'around', 'never', 'them', 'to', 'until', 'do', 'what', 'say', 'twelve', 'nothing', 'during', 'sixty', 'sometime', 'us', 'fifty', 'much', 'for', 'other', 'hence', 'he', 'put'} 

Вы также можете проверить, является ли слово стоп-словом или нет. Для этого вы можете использовать is_stop как показано ниже:

 sp.vocab['wonder'].is_stop 

Так как «wonder» не является стоп-словом spaCy, в выходных данных False

Чтобы добавить или удалить стоп-слова в spaCy, вы можете использовать sp.Defaults.stop_words.add() и sp.Defaults.stop_words.remove() соответственно.

 sp.Defaults.stop_words.add('wonder') 

Затем нам нужно установить для тега is_stop wonder значение True, как показано ниже:

 sp.vocab['wonder'].is_stop = True 

Заключение

Сопоставление фраз и словарного запаса - одна из важнейших задач обработки естественного языка. В этой статье мы продолжили обсуждение того, как использовать Python для выполнения сопоставления на основе правил и фраз. Кроме того, мы видели стоп-слова spaCy.

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

comments powered by Disqus