要将句子拆分成标记,我正在执行以下缓慢的操作
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()
答案 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)
,就无需在循环中的句子上再次运行它。所有注释都应该在那儿,而只是复制注释。特别是慢。)