我想使用spaCy解析文档并应用令牌过滤器,以便最终的spaCy文档不包含过滤的标记。我知道我可以对令牌序列进行过滤,但我对于实际的Doc
结构感兴趣。
text = u"This document is only an example. " \
"I would like to create a custom pipeline that will remove specific tokesn from the final document."
doc = nlp(text)
def keep_token(tok):
# This is only an example rule
return tok.pos_ not not in {'PUNCT', 'NUM', 'SYM'}
final_tokens = list(filter(keep_token, doc))
# How to get a spacy.Doc from final_tokens?
我尝试从令牌列表中重新构建一个新的spaCy Doc
,但API并不清楚如何执行此操作。
答案 0 :(得分:5)
我很确定您到现在为止都找到了解决方案,但是由于它没有在此处发布,所以我认为添加它可能会有用。
您可以通过将文档转换为numpy数组,从numpy数组移除然后再转换回doc来删除令牌。
代码:
import spacy
from spacy.attrs import LOWER, POS, ENT_TYPE, IS_ALPHA
from spacy.tokens import Doc
import numpy
def remove_tokens_on_match(doc):
indexes = []
for index, token in enumerate(doc):
if (token.pos_ in ('PUNCT', 'NUM', 'SYM')):
indexes.append(index)
np_array = doc.to_array([LOWER, POS, ENT_TYPE, IS_ALPHA])
np_array = numpy.delete(np_array, indexes, axis = 0)
doc2 = Doc(doc.vocab, words=[t.text for i, t in enumerate(doc) if i not in indexes])
doc2.from_array([LOWER, POS, ENT_TYPE, IS_ALPHA], np_array)
return doc2
# load english model
nlp = spacy.load('en')
doc = nlp(u'This document is only an example. \
I would like to create a custom pipeline that will remove specific tokens from \
the final document.')
print(remove_tokens_on_match(doc))
您可以查看我回答here的类似问题。
答案 1 :(得分:1)
根据您的目的,有几种方法。
<强> 1。获取原始文档
SpaCy中的标记引用了他们的文档,因此您可以这样做:
original_doc = final_tokens[0].doc
这样你仍然可以从原始句子中获取PoS,解析数据等。
<强> 2。构建一个没有删除令牌的新文档
您可以使用空格追加所有标记的字符串并创建新文档。有关text_with_ws
的信息,请参阅token docs。
doc = nlp(''.join(map(lambda x: x.text_with_ws, final_tokens)))
这可能不会给你你想要的东西--PoS标签不一定是相同的,结果句子可能没有意义。
如果这些都不是你的想法,请告诉我,也许我可以提供帮助。