如何从spaCy文档中过滤标记

时间:2017-07-28 14:02:39

标签: python nlp spacy

我想使用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并不清楚如何执行此操作。

2 个答案:

答案 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标签不一定是相同的,结果句子可能没有意义。

如果这些都不是你的想法,请告诉我,也许我可以提供帮助。