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