Рубрики
Без рубрики

Python для НЛП: Словарь и сопоставление фраз с пространством

Автор оригинала: Usman Malik.

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

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

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

Библиотека space поставляется с инструментом 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 brown fox”. Для этого нам нужно создать следующие четыре паттерна:

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 ищет фразу “быстрая бурая лиса”
  • p2 ищет фразу “quick-brown-fox”
  • p3 пытается найти “быстрый коричневый лис”
  • р4 ищет фразу “быстрая бурая лиса”

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

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

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

Здесь “QBF” – это название наших матчей. Вы можете дать ему любое имя.

Применение совпадений к документу

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

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

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

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

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

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

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

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

Шаги для выполнения сопоставления фраз очень похожи на сопоставление на основе правил.

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

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

import spacy
nlp = spacy.load('en_core_web_sm')


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

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

Создание списка фраз

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

phrases = ['machine learning', 'robots', 'intelligent agents']

patterns = [nlp(text) for text in phrases]

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

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

Здесь название наших матчей-AI.

Применение совпадений к документу

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

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” и т. Д., Которые не имеют никакого собственного значения. Стоп-слова часто не очень полезны для задач НЛП, таких как классификация текста или моделирование языка. Поэтому часто лучше удалить эти стоп-слова перед дальнейшей обработкой документа.

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

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

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

В выводе вы увидите все пробельные стоп-слова:

{'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

Поскольку “чудо” не является пробелом стоп-слова, вы увидите False в выводе.

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

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