Chr*_*tis 54
如果有人想要轻松查看spacy生成的依赖关系树,一种解决方案是将其转换为a nltk.tree.Tree并使用该nltk.tree.Tree.pretty_print方法.这是一个例子:
import spacy
from nltk import Tree
en_nlp = spacy.load('en')
doc = en_nlp("The quick brown fox jumps over the lazy dog.")
def to_nltk_tree(node):
if node.n_lefts + node.n_rights > 0:
return Tree(node.orth_, [to_nltk_tree(child) for child in node.children])
else:
return node.orth_
[to_nltk_tree(sent.root).pretty_print() for sent in doc.sents]
Run Code Online (Sandbox Code Playgroud)
输出:
jumps
________________|____________
| | | | | over
| | | | | |
| | | | | dog
| | | | | ___|____
The quick brown fox . the lazy
Run Code Online (Sandbox Code Playgroud)
编辑:要更改令牌表示,您可以执行以下操作:
def tok_format(tok):
return "_".join([tok.orth_, tok.tag_])
def to_nltk_tree(node):
if node.n_lefts + node.n_rights > 0:
return Tree(tok_format(node), [to_nltk_tree(child) for child in node.children])
else:
return tok_format(node)
Run Code Online (Sandbox Code Playgroud)
结果如下:
jumps_VBZ
__________________________|___________________
| | | | | over_IN
| | | | | |
| | | | | dog_NN
| | | | | _______|_______
The_DT quick_JJ brown_JJ fox_NN ._. the_DT lazy_JJ
Run Code Online (Sandbox Code Playgroud)
Mar*_*ery 35
树本身不是一个物体; 你只需通过令牌之间的关系来导航它.这就是为什么文档谈论导航树,而不是'得到'它.
首先,让我们解析一些文本来获取一个Doc对象:
>>> import spacy
>>> nlp = spacy.load('en')
>>> doc = nlp('First, I wrote some sentences. Then spaCy parsed them. Hooray!')
Run Code Online (Sandbox Code Playgroud)
>>> doc[0]
First
>>> doc[1]
,
>>> doc[2]
I
>>> doc[3]
wrote
Run Code Online (Sandbox Code Playgroud)
但它没有单个根令牌.我们解析了由三个句子组成的文本,因此有三个不同的树,每个树都有自己的根.如果我们想从每个句子的根开始解析,首先将有助于将句子作为不同的对象.幸运的是,doc通过该.sents属性向我们公开这些:
>>> sentences = list(doc.sents)
>>> for sentence in sentences:
... print(sentence)
...
First, I wrote some sentences.
Then spaCy parsed them.
Hooray!
Run Code Online (Sandbox Code Playgroud)
这些句子中的每一个都Span具有.root指向其根令牌的属性.通常,根令牌将是句子的主要动词(尽管对于不常见的句子结构可能不是这样,例如没有动词的句子):
>>> for sentence in sentences:
... print(sentence.root)
...
wrote
parsed
Hooray
Run Code Online (Sandbox Code Playgroud)
找到根令牌后,我们可以通过.children每个令牌的属性向下导航树.例如,让我们在第一句中找到动词的主语和宾语..dep_每个子令牌的属性描述了它与父节点的关系 ; 例如dep_,'nsubj'表示令牌是其父母的名义主题.
>>> root_token = sentences[0].root
>>> for child in root_token.children:
... if child.dep_ == 'nsubj':
... subj = child
... if child.dep_ == 'dobj':
... obj = child
...
>>> subj
I
>>> obj
sentences
Run Code Online (Sandbox Code Playgroud)
我们也可以通过查看其中一个令牌的孩子继续沿着树走下去:
>>> list(obj.children)
[some]
Run Code Online (Sandbox Code Playgroud)
因此,使用上面的属性,您可以导航整个树.如果你想用一些依赖树来形象化例句来帮助你理解结构,我建议你用displaCy来玩.
您可以使用下面的库查看您的依赖树,发现它很有帮助!
from spacy import displacy
nlp = spacy.load('en')
doc = nlp(u'This is a sentence.')
displacy.serve(doc, style='dep')
Run Code Online (Sandbox Code Playgroud)
你想找到树的根,你可以通过文件:
def find_root(docu):
for token in docu:
if token.head is token:
return token
Run Code Online (Sandbox Code Playgroud)
然后,要在树中导航,令牌都有API来通过孩子
我不知道这是一个新的API调用还是什么,但是在Document类上有一个.print_tree()方法可以使此工作快速进行。
https://spacy.io/api/doc#print_tree
它将依赖关系树转储到JSON。它处理多个句子的词根以及所有这些:
import spacy
nlp = spacy.load('en')
doc1 = nlp(u'This is the way the world ends. So you say.')
print(doc1.print_tree(light=True))
Run Code Online (Sandbox Code Playgroud)
名称print _tree有点用词不当,该方法本身不输出任何内容,而是返回一列字典,每个句子一个。
我还需要在完整代码下执行此操作:
import sys
def showTree(sent):
def __showTree(token):
sys.stdout.write("{")
[__showTree(t) for t in token.lefts]
sys.stdout.write("%s->%s(%s)" % (token,token.dep_,token.tag_))
[__showTree(t) for t in token.rights]
sys.stdout.write("}")
return __showTree(sent.root)
Run Code Online (Sandbox Code Playgroud)
如果您想为终端设置间距:
def showTree(sent):
def __showTree(token, level):
tab = "\t" * level
sys.stdout.write("\n%s{" % (tab))
[__showTree(t, level+1) for t in token.lefts]
sys.stdout.write("\n%s\t%s [%s] (%s)" % (tab,token,token.dep_,token.tag_))
[__showTree(t, level+1) for t in token.rights]
sys.stdout.write("\n%s}" % (tab))
return __showTree(sent.root, 1)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24160 次 |
| 最近记录: |