Spacy - 标记引用字符串

Spacy - Tokenize quoted string

我正在使用 spacy 2.0 并使用带引号的字符串作为输入。

示例字符串

"The quoted text 'AA XX' should be tokenized"

并期待提取

[The, quoted, text, 'AA XX', should, be, tokenized]

然而,我在试验时得到了一些奇怪的结果。名词 chunks 和 ents 失去了引用之一。

import spacy
nlp = spacy.load('en')
s = "The quoted text 'AA XX' should be tokenized"
doc = nlp(s)
print([t for t in doc])
print([t for t in doc.noun_chunks])
print([t for t in doc.ents])

结果

[The, quoted, text, ', AA, XX, ', should, be, tokenized]
[The quoted text 'AA XX]
[AA XX']

解决我需要的最好方法是什么

虽然您可以修改分词器并添加您自己的排除引号的自定义前缀、后缀和中缀规则,但我不确定这是这里的最佳解决方案。

对于您的用例,添加 component to your pipeline that merges (certain) quoted strings into one token before the tagger, parser and entity recognizer are called. To accomplish this, you can use the rule-based Matcher 并查找被 ' 包围的标记组合可能更有意义。以下模式查找一个或多个字母数字字符:

pattern = [{'ORTH': "'"}, {'IS_ALPHA': True, 'OP': '+'}, {'ORTH': "'"}]

Here's a visual example 交互式匹配器演示中的模式。要进行合并,您可以设置 Matcher,添加模式并编写一个函数,该函数接受一个 Doc 对象,提取匹配的跨度并通过调用 [=16] 将它们合并为一个标记=]方法。

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']

为了更优雅的解决方案,您还可以将组件重构为可重用的 class,在其 __init__ 方法中设置匹配器(例如 see the docs)。

如果您首先在管道中添加组件,所有其他组件(如标记器、解析器和实体识别器)将只能看到重新标记的 Doc。这也是为什么您可能想要编写更具体的模式,这些模式只合并您关心的某些带引号的字符串。在您的示例中,新的标记边界 改善了 预测——但我也可以想到许多其他情况,它们不会,特别是如果引用的字符串更长并且包含很大一部分句子.