7.4 语言结构中的递归 & 7. 5 命名实体识别 & 7.6 关系提取

本文探讨了语言结构中的递归概念,使用级联分块器构建语法树,并介绍了命名实体识别与关系提取的技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#!/usr/bin/env python
# coding: utf-8

7.4 语言结构中的递归

1、用级联分块器构建嵌套结构


# In[2]:


import nltk


# In[3]:


grammar = r'''
    NP: {<DT|JJ|NN.*>+}
    PP: {<IN><NP>}
    VP: {<VB.*><NP|PP|CLAUSE>+$}
    CLAUSE: {<NP><VP>}
'''
cp = nltk.RegexpParser(grammar)
sentence = [('Marry', 'NN'),('saw', 'VBD'),('the', 'DT'),('cat', 'NN'),
            ('sit', 'VB'),('on', 'IN'),('the', 'DT'),('mat', 'NN')]
print(cp.parse(sentence))
# cp.parse(sentence).draw()


# In[4]:


sentence = [('John', 'NNP'),('thinks', 'VBZ'),('Marry', 'NN'),('saw', 'VBD'),('the', 'DT'),('cat', 'NN'),
            ('sit', 'VB'),('on', 'IN'),('the', 'DT'),('mat', 'NN')]
print(cp.parse(sentence)) # 无法识别开始的VP块


# In[6]:


cp = nltk.RegexpParser(grammar, loop=2) # 添加循环loop, 即可解决
print(cp.parse(sentence)) 
# 级联过程只能产生固定深度的树状图,这是不完整的语法分析


# In[ ]:

2、树状图

# In[8]:


# NLTK中,创建树状图的方法:给节点添加标签和一个子链表。
tree1 = nltk.Tree('NP', ['Alice'])
print(tree1)

tree2 = nltk.Tree('NP', ['the', 'rabbit'])
print(tree2)


# In[33]:


# 不断合并形成更大的树状图
tree3 = nltk.Tree('VP', ['chased', tree2])
tree4 = nltk.Tree('S', [tree1, tree3])
print(tree4)


# In[51]:


# 构成树状图对象的一些方法
print(tree4[1])
print(tree4[1].label())


# In[28]:


print(tree4.leaves())
tree4[1][1][1]


# In[29]:


# 输出为postscript文件
tree4.draw()


# In[30]:


tree3.draw()


# In[ ]:

3、树遍历


# In[49]:


# 递归函数遍历树状图
def traverse(t):
    try:
        t.label()
    except AttributeError:
        print(t,end = ' ')
        
    else:
        print('(', t.label(), end = ' ')
        for child in t:
            traverse(child)
        print(')', end = ' ')


# In[50]:


# t = nltk.Tree('(S (NP Alice) (VP chased (NP the rabbit)))')
traverse(tree4)

7.5 命名实体识别

# In[ ]:


·仅仅凭借 地名辞典 来识别众多实体是不可能的。
·我们需要能够识别 多标识符序列的开头和结尾。


# In[53]:


# NLTK 提供了 一个已经训练好的可以识别命名实体的分类器
sent = nltk.corpus.treebank.tagged_sents()[22]
print(nltk.ne_chunk(sent, binary=True))


# In[54]:


# NLTK 提供了 一个已经训练好的可以识别命名实体的分类器
sent = nltk.corpus.treebank.tagged_sents()[22]
print(nltk.ne_chunk(sent, binary=0))

7.6 关系提取

# In[55]:


import re


# In[59]:


IN =re.compile(r'.*\bin\b(?!\b.+ing)') # 这是的名词短语,不是代表 命名实体之间的关系
for doc in nltk.corpus.ieer.parsed_docs('NYT_19980315'):
    for rel in nltk.sem.extract_rels('ORG', 'LOC', doc, corpus='ieer', pattern=IN):
        print(nltk.sem.rtuple(rel))


# In[64]:


# 荷兰语
from nltk.corpus import conll2002
vnv = """
(
is/V|
was/V|
werd/V|
wordt/V
)
.*
van/Prep
"""
VAN = re.compile(vnv, re.VERBOSE)
for doc in conll2002.chunked_sents('ned.train'):
    for r in nltk.sem.extract_rels('PER', 'ORG', doc, corpus='conll2002', pattern=VAN):
        print(nltk.sem.clause(r, relsym = 'VAN'))


# In[66]:


# 荷兰语
from nltk.corpus import conll2002
vnv = """
(
is/V|
was/V|
werd/V|
wordt/V
)
.*
van/Prep
"""
VAN = re.compile(vnv, re.VERBOSE)
for doc in conll2002.chunked_sents('ned.train'):
    for r in nltk.sem.extract_rels('PER', 'ORG', doc, corpus='conll2002', pattern=VAN):
        print(nltk.sem.rtuple(r, lcon=True, rcon=True))# 最后一个条目是误报!!



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值