8.5 依存关系 和 依存文法 & 8.6 文法开发
8.5 依存关系 和 依存文法 & 8.6 文法开发8.5 依存关系 和 依存文法1、配价 与 词汇2、扩大规模8.6 文法开发1、树库 和 文法2、有害的歧义3、加权文法#!/usr/bin/env python# coding: utf-88.5 依存关系 和 依存文法·依存文法:一个中心词(通常是动词)与其从属之间的二元非对称关系。(集中关注的是词与其他词之间的关系)·如...
·
#!/usr/bin/env python
# coding: utf-8
8.5 依存关系 和 依存文法
·依存文法:一个中心词(通常是动词)与其从属之间的二元非对称关系。(集中关注的是词与其他词之间的关系)
·如下nltk依存文法编码的一种方式,只能捕捉依存关系信息。
# import nltk
# groucho_dep_grammar = nltk.parse_dependency_grammar('''
# 'shot' -> 'I' | 'elephant' | 'in'
# 'elephant' -> 'an' | 'in'
# 'in' -> 'pajamas'
# 'pajamas' -> 'my'
# ''')
# In[ ]:
# nltk.parse_dependency_grammar 改用了 DependencyGrammar.fromstring。
from nltk.grammar import DependencyGrammar
from nltk.parse import (
DependencyGraph,
ProjectiveDependencyParser, # 这个是有的!!!!!!
NonprojectiveDependencyParser,
)
# In[ ]:
dep_grammar = DependencyGrammar.fromstring(
"""
'shot' -> 'I' | 'elephant' | 'in'
'elephant' -> 'an' | 'in'
'in' -> 'pajamas'
'pajamas' -> 'my'
"""
)
print(dep_grammar)
# In[ ]:
# 依存关系图是一个投影
# In[ ]:
# 演示了dep_grammar如何使用另一种替代方法来捕捉附着歧义
pdp = nltk.ProjectiveDependencyParser(dep_grammar)
sent = 'I shot an elephant in my pajamas'.split()
trees = pdp.parse(sent)
# for tr in trees:
# print(tr)
#ProjectiveDependencyParser 返回的是generator,所以必须重复下面行,才可以画出图。
# trees = ProjectiveDependencyParser(dep_grammar).parse(sent)
for tree in trees:
print(tree)
print(tree.draw())
1、配价 与 词汇
·及物动词TV,子类别
·修饰语:介词短语、形容词和副词;补语:受中心词选择。
2、扩大规模
·小型文法扩展到大型语料库非常困难。
·歧义会随着覆盖范围的扩大而增加。
·为几种语言开发基于规则的文法的一些大的合作项目:
(1)词汇功能语法(LFG)Pargram项目;
(2)中心词驱动语法结构文法LinGo矩阵框架;
(3)领接着文法XTAG的词汇化树项目。
8.6 文法开发
1、树库 和 文法
# In[ ]:
from nltk.corpus import treebank
t = treebank.parsed_sents('wsj_0001.mrg')[0]
print(t)
# In[ ]:
# 搜索树库找出句子的补语
def filter(tree):
child_nodes = [child.label() for child in tree
if isinstance(child, nltk.Tree)]
return (tree.label() == 'VP') and ('S' in child_nodes)
[subtree for tree in treebank.parsed_sents()
for subtree in tree.subtrees(filter)]
·PP附着语料库:nltk.corpus.ppattach是另一个有关特别动词配价的信息源
# In[ ]:
entries = nltk.corpus.ppattach.attachments('training')
table = nltk.defaultdict(lambda: nltk.defaultdict(set))
for entry in entries:
key = entry.noun1 + '-' + entry.prep + '-' + entry.noun2
table[key][entry.attachment].add(entry.verb)
# In[ ]:
for key in sorted(table):
if len(table[key]) > 1:
print(key, 'N:', sorted(table[key]['N']), 'V:', sorted(table[key]['V']))
# In[6]:
nltk.corpus.sinica_treebank.parsed_sents()[3450].draw()
2、有害的歧义
# In[20]:
import nltk
# 'fish'句子的玩具文法
grammar = nltk.CFG.fromstring('''
S -> NP V NP
NP -> NP Sbar
Sbar -> NP V
NP -> 'fish'
V -> 'fish'
''')
# In[21]:
tokens = ['fish'] * 5
cp = nltk.ChartParser(grammar)
for tree in cp.parse(tokens):
print(tree)
·即使某句话不可能(the a are of me),但它仍是符合语法的;
·看上去没有歧义的句子,结果却出现没有想到的其他读法,导致低效率!
为此,出现了概率分析。
3、加权文法
# In[33]:
# 宾州树库样本中的give和gave用法
def give(t):
return t.label() == 'VP' and len(t) > 2 and t[1].label() == 'NP'
and (t[2].label() == 'PP-DTV' or t[2].label() == 'NP')
and ('give' in t[0].leaves() or 'gave' in t[0].leaves())
# In[34]:
def sent(t):
return ' '.join(token for token in t.leaves() if token[0] not in '*-0')
# In[35]:
def print_node(t, width):
output = '%s %s: %s / %s: %s' % (sent(t[0]), t[1].label(), sent(t[1]), t[2].label(), sent(t[2]))
if len(output) > width:
output = output[:width] + '...'
print(output)
# In[36]:
for tree in nltk.corpus.treebank.parsed_sents():
for t in tree.subtrees(give):
print_node(t, 72)
# In[ ]:
·概率上下文无关文法(PCFG)
# In[51]:
# 定义一个概率上下文无关文法(PCFG)
# nltk.parse_pcfg 改成了 nltk.PCFG.fromstring
grammar = nltk.PCFG.fromstring('''
S -> NP VP [1.0]
VP -> TV NP [0.4]
VP -> IV [0.3]
VP -> DatV NP NP [0.3]
TV -> 'saw' [1.0]
IV -> 'ate' [1.0]
DatV -> 'gave' [1.0]
NP -> 'telescopes' [0.8]
NP -> 'Jack' [0.2]
''')
# In[49]:
print(grammar)
# In[52]:
viterbi_parser = nltk.ViterbiParser(grammar)
# In[61]:
sent = 'Jack saw telescopes'.split()
for i in viterbi_parser.parse(sent):
print(i.draw(), i)
更多推荐
已为社区贡献11条内容
所有评论(0)