PhraseMatcher для сопоставления фраз со словами между - PullRequest
2 голосов
/ 17 апреля 2020

Предположим, у меня есть следующие два предложения: "Onions are being cut. However, a great big cut to the onions have been observed", и я w * sh, чтобы соответствовать фразе "Нарезка лука". Это всего лишь минимальный пример.

Мое требование состоит в том, чтобы алгоритм проходил через все предложения и возвращал логическое значение того, содержит ли предложение эту фразу или нет. Кроме того, я только wi sh, чтобы соответствовать на лемматизированной версии, и это нормально, чтобы между фразами было 0 или более слов. Поэтому в приведенном выше примере я ожидаю, что он вернет [False, True]. Как бы я go сделал это?

Моя половина попытки выглядит следующим образом (места, где мне нужна помощь, помечены TODO):

import spacy 
from spacy.matcher import PhraseMatcher 

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

corpus = "onions are being cut. However, a great big cut to the onions have been observed"
pattern = "Cutting onions"
doc = nlp(corpus)
# TODO: how do I change the pattern to lemmatize and include any # of words between
matcher.add('pat1', None, pattern) 

results = []
for s in doc.sents:
    # TODO: can I use sentences as a doc?
    matches = matcher(s)
    if len(matches) > 0:
        results.append(True)
    else:
        results.append(False)

1 Ответ

1 голос
/ 17 апреля 2020

Я предлагаю использовать spacy.matcher.Matcher и получать соответствующие предложения после каждого совпадения.

Посмотреть пример демонстрации:

import spacy 
from spacy.matcher import Matcher
​
nlp = spacy.load('en_core_web_sm') 
matcher = Matcher(nlp.vocab)
​
corpus = "onions are being cut. However, a great big cut to the onions have been observed"
doc = nlp(corpus)
pattern = [{'LEMMA': 'cut'},
           {'IS_ALPHA': True, 'OP': '*'},
           {'LEMMA': 'onion'}]
matcher.add('pat', None, pattern) 
​
matches = matcher(doc)
for match_id, start, end in matches:
    string_id = nlp.vocab.strings[match_id]  # Get string representation
    span = doc[start:end]  # The matched span
    print("Match ID: {}\nString ID: {}\nStart: {}\nEnd: {}\nText: {}\nSentence: {}".format(
      match_id, string_id, start, end, span.text, span.sent))

Вывод:

Match ID: 5387953638794962156
String ID: pat
Start: 10
End: 14
Text: cut to the onions
Sentence: However, a great big cut to the onions have been observed

Обратите внимание, что шаблон pattern = [{'LEMMA': 'cut'},{'IS_ALPHA': True, 'OP': '*'},{'LEMMA': 'onion'}] соответствует строке, которая начинается с cut слово леммы ({'LEMMA': 'cut'}), затем содержит 0 или более вхождений любых буквенных слов ({'IS_ALPHA': True, 'OP': '*'}) и затем имеет лемму onion слово.

...