Определите токен из нескольких слов и извлеките все токены после слов с помощью SpaCy Matcher - PullRequest
1 голос
/ 30 апреля 2020

У меня возникли проблемы с пониманием модуля SpaCy Matcher.

У меня есть предложение: I think this is great, but I would not do it again

Я хочу вернуть текст but I would not do it again.

То, что у меня пока есть:

nlp = spacy.load("en_core_web_sm")
matcher = Matcher(nlp.vocab)

pattern = [{"LOWER": "but"}]
doc = nlp("I think this is great, but I would not do it again")
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(span.text)

Этот код возвращает только but.

Кроме того, возможно ли создать список строк для сопоставления с образцом, например:

list_of_match_words = ['but', 'particularly']
pattern = [{'LOWER'}: list_of_match_words}] 

или подобное? Я знаю, что выше не будет работать.

1 Ответ

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

Вы можете использовать оператор REGEX для сопоставления с указанными c выбранными токенами, а затем вы можете использовать {"OP": "*"}, чтобы получить остальные токены справа от соответствующего токена. :

list_of_match_words = ['but', 'particularly']
pattern = [{"TEXT" : {"REGEX": "(?i)^(?:{})$".format("|".join(list_of_match_words))}}, {"OP": "*"}]
matcher.add("list_of_match_words", None, pattern)

Здесь регулярное выражение будет выглядеть так: (?i)^(?:but|particularly)$ соответствие

  • (?i) - режим без учета регистра при
  • ^ - начало строка (здесь, токен)
  • (?:but|particularly) - группа без захвата, соответствующая but или particularly строк
  • $ - конец строки (здесь, токен).

Партия {"OP": "*"} соответствует любым токенам 0 или более раз.

Полный фрагмент кода SpaCy :

import spacy
from spacy.matcher import Matcher
from itertools import *

nlp = spacy.load("en_core_web_sm")
matcher = Matcher(nlp.vocab)

list_of_match_words = ['but', 'particularly']
pattern = [{"TEXT" : {"REGEX": "(?i)^(?:{})$".format("|".join(list_of_match_words))}}, {"OP": "*"}]
matcher.add("list_of_match_words", None, pattern)
doc = nlp("I think this is great particularly, but I would not do it again")
matches = matcher(doc)
results = [max(list(group),key=lambda x: x[2]) for k, group in groupby(sorted(matches, key=lambda x: x[1]), lambda x: x[1])]
print("Matches:", [doc[start:end].text for match_id, start, end in results])

Вывод:

Matches: ['particularly, but I would not do it again', 'but I would not do it again']
...