В частности, возможно ли получить соответствующий идентификатор правила в совпадении совпадений

В Spacy 2.x я использую сопоставление для поиска определенных токенов в моем текстовом корпусе. У каждого правила есть идентификатор (например, 'class-1_0'). Во время синтаксического анализа я использую обратный вызов on_match для обработки каждого совпадения. Есть ли решение для получения правила, используемого для поиска совпадения, непосредственно в обратном вызове.

Вот мой пример кода.

txt = ("Aujourd'hui, je vais me faire une tartine au beurre "
       "de cacahuète, c'est un pilier de ma nourriture "
       "quotidienne.")

nlp = spacy.load('fr')

def on_match(matcher, doc, id, matches):
    span = doc[matches[id][1]:matches[id][2]]
    print(span)
    # find a way to get the corresponding rule without fuzz

matcher = Matcher(nlp.vocab)
matcher.add('class-1_0', on_match, [{'LEMMA': 'pilier'}])
matcher.add('class-1_1', on_match, [{'LEMMA': 'beurre'}, {'LEMMA': 'de'}, {'LEMMA': 'cacahuète'}])

doc = nlp(txt)
matches = matcher(doc)

В этом случае matches возврат:

[(12071893341338447867, 9, 12), (4566231695725171773, 16, 17)]

12071893341338447867 - это уникальный идентификатор, основанный на class-1_0. Я не могу найти исходное название правила, даже если провожу самоанализ в matcher._patterns.

Было бы здорово, если бы кто-нибудь мне помог. Большое тебе спасибо.


person k3z    schedule 26.11.2017    source источник


Ответы (2)


Да, вы можете просто найти идентификатор в StringStore вашего словаря, доступного через nlp.vocab.strings или doc.vocab.strings. Переход через Doc здесь довольно удобен, потому что вы можете сделать это в своем обратном вызове on_match:

def on_match(matcher, doc, match_id, matches):
   string_id = doc.vocab.strings[match_id]

Для эффективности spaCy кодирует все строки в целые числа и сохраняет ссылку на отображение в таблице поиска StringStore. В spaCy v2.0 целые числа являются хеш-значениями, поэтому они всегда будут соответствовать моделям и словарям. Подробнее об этом см. в этом разделе документации.

Конечно, если ваши классы и идентификаторы в любом случае выглядят загадочно, другой ответ, предлагающий целочисленные идентификаторы, тоже подойдет. Просто имейте в виду, что выбранные вами целочисленные идентификаторы, вероятно, также будут сопоставлены с какой-то случайной строкой в ​​StringStore (например, словом, тегом части речи или чем-то еще). Обычно это не имеет значения, если вы не ищите их и не разрешаете где-нибудь в строки, но если вы это сделаете, результат может сбивать с толку. Например, если ваш идентификатор правила сопоставления 99 и вы вызываете doc.vocab.strings[99], это вернет 'VERB'.

person Ines Montani    schedule 28.11.2017
comment
Спасибо. Я проверил ваш ответ, он указывает правильное направление. Но чтобы получить идентификатор строки, вам нужно использовать правило соответствия с целочисленной кодировкой, а не match_id. string_id = doc.vocab.strings[matches[id][0]] Еще раз спасибо. - person k3z; 29.11.2017
comment
И спасибо за невероятное достижение с Spacy 2.0 :) - person k3z; 29.11.2017

Как часто я писал свой вопрос, но нашел решение.

Это очень просто, вместо использования идентификатора правила Юникода, такого как class-1_0, просто используйте промежуточное число. Идентификатор будет сохраняться на протяжении всего процесса.

matcher.add(1, on_match, [{'LEMMA': 'pilier'}])

Совпадает с

[(1, 16, 17),]
person k3z    schedule 26.11.2017