是否可以将 spacy 与已经标记化的输入一起使用?

Is it possible to use spacy with already tokenized input?

我有一个句子已经被标记化为单词。我想获取句子中每个单词的词性标记。当我查看 SpaCy 中的文档时,我意识到它是从原始句子开始的。我不想这样做,因为在那种情况下,spacy 可能会以不同的标记化结束。因此,我想知道是否可以将 spaCy 与单词列表(而不是字符串)一起使用?

这是关于我的问题的一个例子:

# I know that it does the following sucessfully :
import spacy
nlp = spacy.load('en_core_web_sm')
raw_text = 'Hello, world.'
doc = nlp(raw_text)
for token in doc:
    print(token.pos_)

但我想做类似下面的事情:

import spacy
nlp = spacy.load('en_core_web_sm')
tokenized_text = ['Hello',',','world','.']
doc = nlp(tokenized_text)
for token in doc:
    print(token.pos_)

我知道,它不起作用,但是否可以做类似的事情?

您可以通过将 spaCy 的默认分词器替换为您自己的分词器来做到这一点:

nlp.tokenizer = custom_tokenizer

其中 custom_tokenizer 是一个将原始文本作为输入并返回 Doc 对象的函数。

您没有具体说明您是如何获得令牌列表的。如果您已经有一个接受原始文本和 returns 标记列表的函数,只需对其进行一些小改动:

def custom_tokenizer(text):
    tokens = []

    # your existing code to fill the list with tokens

    # replace this line:
    return tokens

    # with this:
    return Doc(nlp.vocab, tokens)

参见 Doc 上的 documentation

如果由于某种原因你不能这样做(也许你没有访问标记化功能),你可以使用字典:

tokens_dict = {'Hello, world.': ['Hello', ',', 'world', '.']}

def custom_tokenizer(text):
    if text in tokens_dict:
        return Doc(nlp.vocab, tokens_dict[text])
    else:
        raise ValueError('No tokenization available for input.')

无论哪种方式,您都可以像第一个示例中那样使用管道:

doc = nlp('Hello, world.')

如果标记化文本不是常量,另一种选择是跳过标记化:

spacy_doc = Doc(nlp.vocab, words=tokenized_text)
for pipe in filter(None, nlp.pipeline):
    pipe[1](spacy_doc)

使用Doc对象

import spacy
from spacy.tokens import Doc
nlp = spacy.load("en_core_web_sm")

sents = [['Hello', ',','world', '.']]
for sent in sents:
    doc = Doc(nlp.vocab, sent)
    for token in nlp(doc):
        print(token.text, token.pos_)