是否有一种快速的方法来获取spaCy中每个句子的标记?

时间:2019-08-27 15:42:22

标签: spacy

要将句子拆分成标记,我正在执行以下缓慢的操作

 import spacy nlp = spacy.load("en_core_web_lg")

 text = "This is a test. This is another test"

 sentence_tokens = []
 doc = nlp(text) 
 for sent in doc.sents:
     words = nlp(sent.text)
     all = []
     for w in words:
         all.append(w)
         sentence_tokens.append(all)

我有点想用nltk处理它的方式来实现,在这种情况下,您可以使用sent_tokenize()将文本分成多个句子,然后为每个句子运行word_tokenize()

2 个答案:

答案 0 :(得分:3)

您的方法的主要问题是您要处理所有两次doc.sents中的句子是Span对象,即Token的序列。因此,无需在句子文本上再次调用nlp – spaCy已经在后台为您完成了所有这些工作,并且您返回的Doc已经包含了您需要的所有信息。

因此,如果您需要一个字符串列表,每个令牌一个,则可以执行以下操作:

sentence_tokens = []
for sent in doc.sents:
    sentence_tokens.append([token.text for token in sent])

或更短:

sentence_tokens = [[token.text for token in sent] for sent in doc.sents]

如果要处理大量文本,您可能还想使用nlp.pipe来提高效率。这将批量处理文本并产生Doc对象。您可以详细了解here

texts = ["Some text", "Lots and lots of texts"]
for doc in nlp.pipe(texts):
   sentence_tokens = [[token.text for token in sent] for sent in doc.sents]
   # do something with the tokens 

答案 1 :(得分:1)

只需快速执行基于规则的令牌化,请运行:

nlp = spacy.load('en_core_web_sm') # no need for large model
doc = nlp.make_doc(text)
print([token.text for token in doc])

但是不会有句子边界。为此,您目前仍需要解析器。如果您需要标记和句子边界:

nlp = spacy.load("en_core_web_sm", disable=["tagger", "ner"]) # just the parser
doc = nlp(text)
print([token.text for token in doc])
print([sent.text for sent in doc.sents])

如果文本很多,请运行nlp.tokenizer.pipe(texts)(类似于make_doc())或nlp.pipe(texts)

(一旦运行doc = nlp(text),就无需在循环中的句子上再次运行它。所有注释都应该在那儿,而只是复制注释。特别是慢。)