私はspaCyで依存関係ツリーを取得する方法を見つけようとしましたが、ツリーを取得する方法については何も見つけることができませんでした、 ツリーをナビゲートする方法 。
誰かがspacyによって生成された依存関係ツリーを簡単に表示したい場合、1つの解決策はそれを 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]
出力:
jumps
________________|____________
| | | | | over
| | | | | |
| | | | | dog
| | | | | ___|____
The quick brown fox . the lazy
Edit:トークン表現を変更するために、これを行うことができます:
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)
結果:
jumps_VBZ
__________________________|___________________
| | | | | over_IN
| | | | | |
| | | | | dog_NN
| | | | | _______|_______
The_DT quick_JJ brown_JJ fox_NN ._. the_DT lazy_JJ
ツリーはそれ自体がオブジェクトではありません。トークン間の関係を介してナビゲートするだけです。そのため、ドキュメントではツリーのナビゲーションについて説明していますが、「取得」については説明していません。
まず、テキストを解析して Doc
オブジェクトを取得しましょう。
>>> import spacy
>>> nlp = spacy.load('en')
>>> doc = nlp('First, I wrote some sentences. Then spaCy parsed them. Hooray!')
doc
は Sequence
の Token
オブジェクトです:
>>> doc[0]
First
>>> doc[1]
,
>>> doc[2]
I
>>> doc[3]
wrote
ただし、単一のルートトークンはありません。 3つの文で構成されるテキストを解析したため、3つの異なるツリーがあり、それぞれに独自のルートがあります。各文のルートから解析を開始する場合、最初に文を個別のオブジェクトとして取得すると役立ちます。幸いなことに、doc
はこれらを .sents
プロパティ:
>>> sentences = list(doc.sents)
>>> for sentence in sentences:
... print(sentence)
...
First, I wrote some sentences.
Then spaCy parsed them.
Hooray!
これらの各文は Span
with .root
そのルートトークンを指すプロパティ。通常、ルートトークンは文の主要な動詞になります(ただし、動詞のない文などの異常な文構造には当てはまらない場合があります)。
>>> for sentence in sentences:
... print(sentence.root)
...
wrote
parsed
Hooray
ルートトークンが見つかったら、.children
各トークンのプロパティ。たとえば、最初の文の動詞の主語と目的語を見つけましょう。 .dep_
各子トークンのプロパティ 親との関係を記述 ;たとえば、dep_
of '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
同様に、これらのトークンの子の1つを表示することにより、ツリーをたどっていきます。
>>> list(obj.children)
[some]
したがって、上記のプロパティを使用して、ツリー全体をナビゲートできます。構造の理解に役立つように、例文の依存ツリーを視覚化する場合は、 displaCy で遊ぶことをお勧めします。
これが新しい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))
名前print_ treeは少し誤った名前で、メソッド自体は何も出力せず、各文に1つずつ辞書のリストを返します。
以下のライブラリを使用して、依存関係ツリーを表示できます。非常に便利です。
from spacy import displacy
nlp = spacy.load('en')
doc = nlp(u'This is a sentence.')
displacy.serve(doc, style='dep')
また、完全なコードの下でそれを行う必要がありました:
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)
そして、ターミナルの間隔が必要な場合:
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)