DevGang
Авторизоваться

Использование Python для задач NLP: работа с словарным запасом и поиск соответствия фраз с помощью библиотеки SpaCy

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

Задаем правила и находим соответствия  

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

Выполним следующие шаги:

Создание объекта Matcher

Первым делом создадим объект Matcher:

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

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

Следующим шагом мы определим шаблоны, которые будут использоваться для фильтрации похожих фраз. Предположим, мы хотим найти фразы"quick-brown-fox", "quick brown fox", "quickbrownfox" или "quick brownfox". Для этого нам нужно создать следующие шаблоны:

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. Вы можете дать ему любое имя.

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

У нас есть готовый 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')

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

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 содержит сведения обо всех токенах и подстановочных знаках, которые можно использовать для сопоставления фраз.

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

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

Давайте сначала удалим предыдущее совпадение 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  

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

Соответствие по фразам

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

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

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

import bs4 as bs  
import urllib.request  
import re  
import nltkscrapped_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.

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

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

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

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

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

Здесь наше совпадение называется AI.

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

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

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)

В выводе вы увидите строковое значение совпавших фраз, как показано ниже:

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, мы можем использовать атрибут 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» не является стоп-словом, на выходе вы получите «False».

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

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

Далее нам нужно установить тег is_stop в значение «True», как показано ниже:

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

Заключение

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

Перевод статьи: https://stackabuse.com/python-for-nlp-vocabulary-and-phrase-matching-with-spacy/

#Python
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

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

Попробовать

Оплатив хостинг 25$ в подарок вы получите 100$ на счет

Получить