Добавление объектов REGEX в SpaCy's Matcher - PullRequest
1 голос
/ 10 июня 2019

Я пытаюсь добавить сущности, определенные регулярными выражениями, в конвейер NER SpaCy. В идеале я должен иметь возможность использовать любое регулярное выражение, загруженное из файла json с определенным типом сущности. В качестве примера я пытаюсь выполнить приведенный ниже код.

Приведенный ниже код показывает, что я пытаюсь сделать, следуя примеру, приведенному в дискуссии Spacy о пользовательских атрибутах с использованием регулярных выражений. Я пытался вызвать метод 'set_extension' различными способами (для Doc, Span, Token), но безрезультатно. Я даже не уверен, что мне следует их устанавливать.

    nlp = spacy.load("en_core_web_lg")
    matcher = Matcher(nlp.vocab)
    pattern = [{"_": {"country": {"REGEX": "^[Uu](\.?|nited) ?[Ss](\.|tates)$"}}}]
    matcher.add("US", None, pattern)
    doc = nlp(u"I'm from the United States.")
    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)

Я ожидаю, что match_id, string_id 3 4 United States будет распечатан.

Вместо этого я получаю AttributeError: [E046] Can't retrieve unregistered extension attribute 'country'. Did you forget to call the 'set_extension' method?

1 Ответ

0 голосов
/ 11 июня 2019

Здесь есть документация по атрибутам расширения: https://spacy.io/usage/processing-pipelines#custom-components-attributes

По сути, вам нужно определить эту переменную country как атрибут расширения, что-то вроде этого:

Token.set_extension("country", default="")

Однако в приведенном вами коде вы фактически никогда не устанавливаете атрибут _.country для какого-либо токена (или диапазона), поэтому все они по-прежнему имеют значение по умолчанию, и сопоставитель никогда не сможет найти совпадение с ними.Приведенная вами строка:

pattern = [{"_": {"country": {"REGEX": "^[Uu](\.?|nited) ?[Ss](\.?|tates)$"}}}]

Пытается сопоставить регулярное выражение США для значений пользовательских атрибутов вместо текста документа, как вы ожидаете (я думаю).

Одно из решений - просто запустить reg-exps для текстов напрямую:

nlp = spacy.load("en_core_web_lg")
matcher = Matcher(nlp.vocab)
pattern = [{"TEXT": {"REGEX": "^[Uu](\.?|nited)$"}},
           {"TEXT": {"REGEX": "^[Ss](\.?|tates)$"}}]
matcher.add("US", None, pattern)
doc = nlp(u"I'm from the United States.")
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)

Какие выходные данные

15397641858402276818 US 4 6 Соединенные Штаты

Затем вы можете использовать эти совпадения, например, для установки пользовательского атрибута на Span или Token (в данном случае на Span, потому что ваше совпадение потенциально включает несколько токенов)

...