Spacy自动将单词紧缩(例如“ dont”和“ do n't”)标记为“ do”和“ nt” /“ n't”。例如,类似“我不理解”的句子将被标记为: [“ I”,“ do”,“ nt”,“理解”] 。
我知道这通常在许多NLP任务中很有用,但是有一种方法可以抑制此special tokenization rule in Spacy,使结果为 [“ I”,“ dont”,“理解”] 相反?
这是因为我正在尝试评估自定义Spacy NER模型的性能(对于BIO标记方案为f1-分数),并且输入句子中的标记数量和谓词标记数量不匹配。我的评估代码的问题:
输入(3个令牌): [(“ I”,“ O”),(“ dont”,“ O”),(“理解”,“ O”)]
已预测(4个令牌): [(“ I”,“ O”),(“ do”,“ O”),(“ nt”,“ O”),(“理解” ,“ O”)]
当然,如果有人对Spacy中的顺序标记任务有更好的评估方法(也许像seqeval包,但更兼容Spacy的令牌格式),也将不胜感激。
答案 0 :(得分:0)
特殊情况下的标记化规则在相应语言数据的tokenizer_exceptions.py
中定义(对于英语“ nt”收缩,则为see here)。创建new Tokenizer
时,可以通过rules
参数传递那些特殊情况的规则。
因此,对于您的用例,您可以做的一件事是重建具有相同前缀,后缀和中缀规则的英语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")
另一种方法是保持令牌化不变,但是在规则上添加一些规则,使某些令牌向后合并并重新匹配所需的令牌化。这显然在运行时会变慢,但是可能更易于实现和推理,因为您可以从“哪些标记当前是分离的,但应该是一个?”的角度进行处理。为此,您可以使用rule-based 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)
上述模式将匹配两个令牌(每个令牌一个字典),其小写形式为“ do”和“ nt”(例如“ DONT”,“ dont”,“ DoNt”)。您可以将更多字典列表添加到模式中,以描述其他标记序列。对于每次匹配,您都可以创建一个Span
并将其合并为一个令牌。为了使这种逻辑更加美观,您还可以将其包装为custom pipeline component,这样当您在文本上调用nlp
时它会自动应用。