Правила токенизации в особом случае определены в tokenizer_exceptions.py
в соответствующих данных языка ( см. Здесь для английских сокращений "nt").Когда вы создаете новый Tokenizer
, эти правила особого случая могут быть переданы через аргумент rules
.
Подход 1: Пользовательский токенизатор с различными правилами особого случая
Итак, одну вещь, которую вы могли бы сделать для своего варианта использования, - это восстановить английский Tokenizer
с тем же правилом префикса, суффикса и инфикса, но только с отфильтрованным набором исключений токенизатора.Исключения токенизатора обозначаются строкой, поэтому вы можете удалить записи для "dont"
и все, что вам нужно.Однако код довольно многословен, так как вы воссоздаете весь токенизатор:
from spacy.lang.en import English
from spacy.lang.punctuation import TOKENIZER_PREFIXES, TOKENIZER_SUFFIXES, TOKENIZER_INFIXES
from spacy.lang.en import TOKENIZER_EXCEPTIONS
from spacy.tokenizer import Tokenizer
from spacy.util import compile_prefix_regex, compile_suffix_regex, compile_infix_regex
prefix_re = compile_prefix_regex(TOKENIZER_PREFIXES).search
suffix_re = compile_suffix_regex(TOKENIZER_SUFFIXES).search
infix_re = compile_infix_regex(TOKENIZER_INFIXES).finditer
filtered_exc = {key: value for key, value in TOKENIZER_EXCEPTIONS.items() if key not in ["dont"]}
nlp = English()
tokenizer = Tokenizer(
nlp.vocab,
prefix_search=prefix_re,
suffix_search=suffix_re,
infix_finditer=infix_re,
rules=filtered_exc
)
nlp.tokenizer = tokenizer
doc = nlp("I dont understand")
Подход 2. Слияние (или разделение) токенов впоследствии
Альтернативным подходом было бы сохранитьтокенизация как таковая, но добавьте к ней правила, которые объединяют определенные токены обратно вместе, чтобы соответствовать желаемому токенизации.Это, очевидно, будет медленнее во время выполнения, но это может быть проще для реализации и рассуждений, потому что вы можете подойти к нему с точки зрения «Какие токены в настоящее время разделены, но должны быть единичными?».Для этого вы можете использовать на основе правил Matcher
и retokenizer , чтобы объединить совпавшие токены.Начиная с spaCy v2.1, он также поддерживает разбиение, в случае необходимости.
from spacy.lang.en import English
from spacy.matcher import Matcher
nlp = English()
matcher = Matcher(nlp.vocab)
patterns = [[{"LOWER": "do"}, {"LOWER": "nt"}]]
matcher.add("TO_MERGE", None, *patterns)
doc = nlp("I dont understand")
matches = matcher(doc)
with doc.retokenize() as retokenizer:
for match_id, start, end in matches:
span = doc[start:end]
retokenizer.merge(span)
Приведенный выше шаблон будет соответствовать двум токенам (по одному dict на токен), чьи строчные буквы - "do" и "nt"(например," DONT "," Dont "," DoNt ").Вы можете добавить больше списков диктов к шаблонам, чтобы описать другие последовательности токенов.Для каждого совпадения вы можете создать Span
и объединить его в один токен.Чтобы сделать эту логику более элегантной, вы можете также обернуть ее как пользовательский конвейерный компонент , чтобы она автоматически применялась при вызове nlp
для текста.