当你could修改标记生成器并添加您自己的自定义前缀、后缀和中缀规则(排除引号),我不确定这是这里的最佳解决方案。
对于您的用例,添加一个可能更有意义成分 https://spacy.io/usage/processing-pipelines#custom-components在调用标记器、解析器和实体识别器之前,将(某些)带引号的字符串合并到一个标记中的管道。要实现此目的,您可以使用基于规则的Matcher http://spacy.io/usage/linguistic-features#rule-based-matching并找到由 包围的标记组合'
。以下模式查找一个或多个字母数字字符:
pattern = [{'ORTH': "'"}, {'IS_ALPHA': True, 'OP': '+'}, {'ORTH': "'"}]
交互式匹配器演示中的模式。要进行合并,您可以设置Matcher
,添加模式并编写一个函数,该函数接受Doc
对象,提取匹配的跨度并通过调用它们将它们合并为一个标记.merge
method.
import spacy
from spacy.matcher import Matcher
nlp = spacy.load('en')
matcher = Matcher(nlp.vocab)
matcher.add('QUOTED', None, [{'ORTH': "'"}, {'IS_ALPHA': True, 'OP': '+'}, {'ORTH': "'"}])
def quote_merger(doc):
# this will be called on the Doc object in the pipeline
matched_spans = []
matches = matcher(doc)
for match_id, start, end in matches:
span = doc[start:end]
matched_spans.append(span)
for span in matched_spans: # merge into one token after collecting all matches
span.merge()
return doc
nlp.add_pipe(quote_merger, first=True) # add it right after the tokenizer
doc = nlp("The quoted text 'AA XX' should be tokenized")
print([token.text for token in doc])
# ['The', 'quoted', 'text', "'AA XX'", 'should', 'be', 'tokenized']
对于更优雅的解决方案,您还可以将组件重构为可重用类,在其中设置匹配器__init__
方法 (请参阅文档 https://spacy.io/usage/processing-pipelines#custom-components举些例子)。
如果您首先在管道中添加组件,则所有其他组件(例如标记器、解析器和实体识别器)将只能看到重新标记化的组件Doc
。这也是为什么您可能想要编写更具体的模式,仅合并您关心的某些带引号的字符串。在您的示例中,新的令牌边界improve预测 - 但我也可以想到许多其他情况,但它们没有,特别是如果引用的字符串更长并且包含句子的重要部分。