- 自然语言工具包教程
- 自然语言工具包 - 首页
- 自然语言工具包 - 简介
- 自然语言工具包 - 入门
- 自然语言工具包 - 文本标记化
- 训练标记器 & 过滤停用词
- 在Wordnet中查找单词
- 词干提取 & 词形还原
- 自然语言工具包 - 单词替换
- 同义词 & 反义词替换
- 语料库读取器和自定义语料库
- 词性标注基础
- 自然语言工具包 - 单词标注器
- 自然语言工具包 - 组合标注器
- 自然语言工具包 - 更多NLTK标注器
- 自然语言工具包 - 解析
- 分块 & 信息提取
- 自然语言工具包 - 分块转换
- 自然语言工具包 - 树的转换
- 自然语言工具包 - 文本分类
- 自然语言工具包资源
- 自然语言工具包 - 快速指南
- 自然语言工具包 - 有用资源
- 自然语言工具包 - 讨论
自然语言工具包 - 树的转换
以下是转换树的两个原因:
- 修改深度解析树,以及
- 扁平化深度解析树
将树或子树转换为句子
我们将要讨论的第一个方法是将树或子树转换回句子或块字符串。这非常简单,让我们看下面的例子:
示例
from nltk.corpus import treebank_chunk tree = treebank_chunk.chunked_sents()[2] ' '.join([w for w, t in tree.leaves()])
输出
'Rudolph Agnew , 55 years old and former chairman of Consolidated Gold Fields PLC , was named a nonexecutive director of this British industrial conglomerate .'
深度树扁平化
嵌套短语的深度树不能用于训练分块器,因此我们必须在使用前将其扁平化。在下面的示例中,我们将使用来自treebank语料库的第3个解析句子,这是一个嵌套短语的深度树。
示例
为了实现这一点,我们定义了一个名为deeptree_flat()的函数,它将接收单个树并返回一个新树,该新树只保留最低级别的树。为了完成大部分工作,它使用了一个我们命名为childtree_flat()的辅助函数。
from nltk.tree import Tree
def childtree_flat(trees):
children = []
for t in trees:
if t.height() < 3:
children.extend(t.pos())
elif t.height() == 3:
children.append(Tree(t.label(), t.pos()))
else:
children.extend(flatten_childtrees([c for c in t]))
return children
def deeptree_flat(tree):
return Tree(tree.label(), flatten_childtrees([c for c in tree]))
现在,让我们对来自treebank语料库的第3个解析句子(这是一个嵌套短语的深度树)调用deeptree_flat()函数。我们将这些函数保存在名为deeptree.py的文件中。
from deeptree import deeptree_flat from nltk.corpus import treebank deeptree_flat(treebank.parsed_sents()[2])
输出
Tree('S', [Tree('NP', [('Rudolph', 'NNP'), ('Agnew', 'NNP')]),
(',', ','), Tree('NP', [('55', 'CD'),
('years', 'NNS')]), ('old', 'JJ'), ('and', 'CC'),
Tree('NP', [('former', 'JJ'),
('chairman', 'NN')]), ('of', 'IN'), Tree('NP', [('Consolidated', 'NNP'),
('Gold', 'NNP'), ('Fields', 'NNP'), ('PLC',
'NNP')]), (',', ','), ('was', 'VBD'),
('named', 'VBN'), Tree('NP-SBJ', [('*-1', '-NONE-')]),
Tree('NP', [('a', 'DT'), ('nonexecutive', 'JJ'), ('director', 'NN')]),
('of', 'IN'), Tree('NP',
[('this', 'DT'), ('British', 'JJ'),
('industrial', 'JJ'), ('conglomerate', 'NN')]), ('.', '.')])
构建浅层树
在上一节中,我们通过只保留最低级别的子树来扁平化嵌套短语的深度树。在本节中,我们将只保留最高级别的子树,即构建浅层树。在下面的示例中,我们将使用来自treebank语料库的第3个解析句子,这是一个嵌套短语的深度树。
示例
为了实现这一点,我们定义了一个名为tree_shallow()的函数,它将通过只保留顶层子树标签来消除所有嵌套的子树。
from nltk.tree import Tree
def tree_shallow(tree):
children = []
for t in tree:
if t.height() < 3:
children.extend(t.pos())
else:
children.append(Tree(t.label(), t.pos()))
return Tree(tree.label(), children)
现在,让我们对来自treebank语料库的第3个解析句子(这是一个嵌套短语的深度树)调用tree_shallow()函数。我们将这些函数保存在名为shallowtree.py的文件中。
from shallowtree import shallow_tree from nltk.corpus import treebank tree_shallow(treebank.parsed_sents()[2])
输出
Tree('S', [Tree('NP-SBJ-1', [('Rudolph', 'NNP'), ('Agnew', 'NNP'), (',', ','),
('55', 'CD'), ('years', 'NNS'), ('old', 'JJ'), ('and', 'CC'),
('former', 'JJ'), ('chairman', 'NN'), ('of', 'IN'), ('Consolidated', 'NNP'),
('Gold', 'NNP'), ('Fields', 'NNP'), ('PLC', 'NNP'), (',', ',')]),
Tree('VP', [('was', 'VBD'), ('named', 'VBN'), ('*-1', '-NONE-'), ('a', 'DT'),
('nonexecutive', 'JJ'), ('director', 'NN'), ('of', 'IN'), ('this', 'DT'),
('British', 'JJ'), ('industrial', 'JJ'), ('conglomerate', 'NN')]), ('.', '.')])
我们可以通过获取树的高度来查看差异:
from nltk.corpus import treebank tree_shallow(treebank.parsed_sents()[2]).height()
输出
3
from nltk.corpus import treebank treebank.parsed_sents()[2].height()
输出
9
树标签转换
在解析树中,存在各种在分块树中不存在的Tree标签类型。但在使用解析树来训练分块器时,我们希望通过将一些树标签转换为更常见的标签类型来减少这种多样性。例如,我们有两个替代的NP子树,即NP-SBL和NP-TMP。我们可以将它们都转换为NP。让我们看看如何在下面的示例中实现。
示例
为了实现这一点,我们定义了一个名为tree_convert()的函数,它接收以下两个参数:
- 要转换的树
- 标签转换映射
此函数将返回一个新树,其中所有匹配的标签都根据映射中的值进行了替换。
from nltk.tree import Tree
def tree_convert(tree, mapping):
children = []
for t in tree:
if isinstance(t, Tree):
children.append(convert_tree_labels(t, mapping))
else:
children.append(t)
label = mapping.get(tree.label(), tree.label())
return Tree(label, children)
现在,让我们对来自treebank语料库的第3个解析句子(这是一个嵌套短语的深度树)调用tree_convert()函数。我们将这些函数保存在名为converttree.py的文件中。
from converttree import tree_convert
from nltk.corpus import treebank
mapping = {'NP-SBJ': 'NP', 'NP-TMP': 'NP'}
convert_tree_labels(treebank.parsed_sents()[2], mapping)
输出
Tree('S', [Tree('NP-SBJ-1', [Tree('NP', [Tree('NNP', ['Rudolph']),
Tree('NNP', ['Agnew'])]), Tree(',', [',']),
Tree('UCP', [Tree('ADJP', [Tree('NP', [Tree('CD', ['55']),
Tree('NNS', ['years'])]),
Tree('JJ', ['old'])]), Tree('CC', ['and']),
Tree('NP', [Tree('NP', [Tree('JJ', ['former']),
Tree('NN', ['chairman'])]), Tree('PP', [Tree('IN', ['of']),
Tree('NP', [Tree('NNP', ['Consolidated']),
Tree('NNP', ['Gold']), Tree('NNP', ['Fields']),
Tree('NNP', ['PLC'])])])])]), Tree(',', [','])]),
Tree('VP', [Tree('VBD', ['was']),Tree('VP', [Tree('VBN', ['named']),
Tree('S', [Tree('NP', [Tree('-NONE-', ['*-1'])]),
Tree('NP-PRD', [Tree('NP', [Tree('DT', ['a']),
Tree('JJ', ['nonexecutive']), Tree('NN', ['director'])]),
Tree('PP', [Tree('IN', ['of']), Tree('NP',
[Tree('DT', ['this']), Tree('JJ', ['British']), Tree('JJ', ['industrial']),
Tree('NN', ['conglomerate'])])])])])])]), Tree('.', ['.'])])