从 nltk 树中获取单词的深度
Get the depth of words from a nltk tree
我正在做一个 nlp 项目,我想根据它在依赖树中的位置过滤掉单词。
为了绘制树,我使用了这个 :
中的代码
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_
例句:
"A group of people around the world are suddenly linked mentally"
我得到了这棵树:
我想从这棵树中得到一个元组列表,其中包含单词及其在树中的相应深度:
[(linked,1),(are,2),(suddenly,2),(mentally,2),(group,2),(A,3),(of,3),(people,4)....]
对于这种情况,我对没有孩子的单词不感兴趣:[are,suddenly,mentally,A,the]
所以到目前为止我能做的就是只得到有 children 的单词列表,所以我使用这个代码:
def get_words(root,words):
children = list(root.children)
for child in children:
if list(child.children):
words.append(child)
get_words(child,words)
return list(set(words)
[to_nltk_tree(sent.root).pretty_print() for sent in doc.sents]
s_root = list(doc.sents)[0].root
words = []
words.append(s_root)
words = get_words(s_root,words)
words
[around, linked, world, of, people, group]
从这里我怎样才能得到包含单词及其各自深度的所需元组?
您确定您的代码中有 nltk Tree
吗? nltk 的 Tree
class 没有 children
属性。使用 nltk Tree
,您可以使用 "treepositions" 做您想做的事,这些路径是树下的路径。每条路径都是分支选择的元组。 "people"的treeposition是(0, 2, 1, 0)
,你可以看到一个节点的深度就是它的treeposition的长度。
首先我得到了叶子的路径,所以我可以排除它们:
t = nltk.Tree.fromstring("""(linked (are suddenly mentally
(group A (of (people (around (world the)))))))""")
n_leaves = len(t.leaves())
leavepos = set(t.leaf_treeposition(n) for n in range(n_leaves))
现在很容易列出非终端节点及其深度:
>>> for pos in t.treepositions():
if pos not in leavepos:
print(t[pos].label(), len(pos))
linked 0
are 1
group 2
of 3
people 4
around 5
world 6
顺带一提,nltk树有自己的显示方式。尝试 print(t)
或 t.draw()
,这会在弹出窗口中绘制树 window。
我正在做一个 nlp 项目,我想根据它在依赖树中的位置过滤掉单词。
为了绘制树,我使用了这个
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_
例句:
"A group of people around the world are suddenly linked mentally"
我得到了这棵树:
我想从这棵树中得到一个元组列表,其中包含单词及其在树中的相应深度:
[(linked,1),(are,2),(suddenly,2),(mentally,2),(group,2),(A,3),(of,3),(people,4)....]
对于这种情况,我对没有孩子的单词不感兴趣:[are,suddenly,mentally,A,the] 所以到目前为止我能做的就是只得到有 children 的单词列表,所以我使用这个代码:
def get_words(root,words):
children = list(root.children)
for child in children:
if list(child.children):
words.append(child)
get_words(child,words)
return list(set(words)
[to_nltk_tree(sent.root).pretty_print() for sent in doc.sents]
s_root = list(doc.sents)[0].root
words = []
words.append(s_root)
words = get_words(s_root,words)
words
[around, linked, world, of, people, group]
从这里我怎样才能得到包含单词及其各自深度的所需元组?
您确定您的代码中有 nltk Tree
吗? nltk 的 Tree
class 没有 children
属性。使用 nltk Tree
,您可以使用 "treepositions" 做您想做的事,这些路径是树下的路径。每条路径都是分支选择的元组。 "people"的treeposition是(0, 2, 1, 0)
,你可以看到一个节点的深度就是它的treeposition的长度。
首先我得到了叶子的路径,所以我可以排除它们:
t = nltk.Tree.fromstring("""(linked (are suddenly mentally
(group A (of (people (around (world the)))))))""")
n_leaves = len(t.leaves())
leavepos = set(t.leaf_treeposition(n) for n in range(n_leaves))
现在很容易列出非终端节点及其深度:
>>> for pos in t.treepositions():
if pos not in leavepos:
print(t[pos].label(), len(pos))
linked 0
are 1
group 2
of 3
people 4
around 5
world 6
顺带一提,nltk树有自己的显示方式。尝试 print(t)
或 t.draw()
,这会在弹出窗口中绘制树 window。