как выбрать одну группу с Spacy Matcher - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь перейти от NLTK к Spacy, и одна из необходимых мне функций - сопоставление «поддеревьев» с регулярным выражением. В простых случаях у Matcher все отлично:

matcher = Matcher(nlp.vocab)
matcher.add('GRAMMAR', None, [{'TAG': 'JJ', 'OP': '+'}, {'POS': NOUN', 'OP': '+'}])

Проблема начинается, когда мне нужно сопоставить только одну из групп. Например, если мне нужно существительное, следующее за прилагательным, но я хочу соответствовать только существительному, а не всему шаблону. В простом регулярном выражении я бы поставил нужную группу в круглые скобки следующим образом (с мнимой функцией):

r'JJ+(NOUN+)'

Мое временное решение - получить только некоторые токены в функции обратного вызова, например:

hits = []
matcher = Matcher(nlp.vocab)
matcher.add('GRAMMAR', lambda matcher, doc, i, matches: hits.append(('GRAMMAR', doc[matches[i][1]+1:matches[i][2]].text)), [{'TAG': 'JJ', 'OP': '+'}, {'POS': 'NOUN', 'OP': '+'}])

Однако у этого решения есть несколько проблем:

  1. Я хочу извлечь список шаблонов из внешнего источника, поэтому функция обратного вызова должна быть одинаковой для всех, хотя для каждого шаблона мне нужно выбрать другую группу (иногда первую, иногда вторую, иногда всю шаблон).
  2. Мое решение учитывает токены. Если в паттерне задействованы операторы (например, *, +), я не могу точно знать, с какого токена начинается / заканчивается мое желаемое совпадение.
  3. Я не уверен в этом, но я мог бы избежать добавления совпадений во внешний список. Я предпочитаю решение, которое по-прежнему сохраняет совпадения внутри объекта Matcher.

Есть идеи?

...