- 自然語言工具包教程
- 自然語言工具包 - 首頁
- 自然語言工具包 - 簡介
- 自然語言工具包 - 入門
- 自然語言工具包 - 文字標記化
- 訓練標記器 & 過濾停用詞
- 在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('.', ['.'])])