Как я могу использовать класс SpaCy Matcher (или PhraseMatcher) для извлечения последовательности из 2 элементов? - PullRequest
1 голос
/ 06 августа 2020

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

colors=['red','gray','black','white','brown']
animals=['fox','bear','hare','squirrel','wolf']

В документах SpaCy https://spacy.io/usage/rule-based-matching довольно хорошо описано, как сопоставить все эти слова из обоих списков или как сопоставить последовательность конкретных двух , например:

pattern = [{"LOWER": "red"}, {"LOWER": "fox"}]

Но мне нужно сопоставить любую комбинацию, например «красная белка» или «белый медведь». Могу ли я добиться этого с помощью Matcher (или PhraseMatcher) в SpaCy, или мне нужно использовать какие-либо дополнительные модули python? Есть ли у кого-нибудь идея о незаконном раскрытии?

Заранее благодарим за любую помощь.

1 Ответ

2 голосов
/ 06 августа 2020

Вы также можете использовать регулярное выражение в SpaCy. Например, fr"(?i)^({'|'.join(colors)})$" создаст шаблон, который соответствует токену без учета регистра, который будет соответствовать любому из элементов colors.

import spacy
from spacy.matcher import Matcher

nlp = spacy.load("en_core_web_sm")

matcher = Matcher(nlp.vocab)

colors=['red','gray','black','white','brown']
animals=['fox','bear','hare','squirrel','wolf']
pattern = [
   {'TEXT': {"REGEX": fr"(?i)^({'|'.join(colors)})$"}},
   {'TEXT': {"REGEX": fr"(?i)^({'|'.join(animals)})$"}}
]
matcher.add("ColoredAnimals", None, pattern)

doc = nlp("Hello, red fox! Hello Black Hare! What's up whItE sQuirrel, brown wolf and gray bear!")
matches = matcher(doc)
for match_id, start, end in matches:
    string_id = nlp.vocab.strings[match_id]
    span = doc[start:end]
    print(match_id, string_id, start, end, span.text)

Вывод:

8757348013401056599 ColoredAnimals 2 4 red fox
8757348013401056599 ColoredAnimals 6 8 Black Hare
8757348013401056599 ColoredAnimals 12 14 whItE sQuirrel
8757348013401056599 ColoredAnimals 15 17 brown wolf
8757348013401056599 ColoredAnimals 18 20 gray bear

Вы можете напрямую извлекать фразы с помощью регулярного выражения:

import re
colors=['red','gray','black','white','brown']
animals=['fox','bear','hare','squirrel','wolf']
pattern = fr"(?i)\b(?:{'|'.join(colors)})\s+(?:{'|'.join(animals)})\b"
doc_string = "Hello, red fox! Hello Black Hare! What's up whItE sQuirrel, brown wolf and gray bear!"
print ( re.findall(pattern, doc_string) )
# => ['red fox', 'Black Hare', 'whItE sQuirrel', 'brown wolf', 'gray bear']

См. Демонстрацию Python

Здесь группы без захвата используются, чтобы не создавать дополнительных элементы в результирующем списке, \s+ соответствует 1 или более пробелам, а \b используются в качестве границ слова вместо привязок ^ (начало строки) и $ (конец строки).

...