《Python自然语言处理(第二版)-Steven Bird等》学习笔记:第07章 从文本提取信息

import nltk, re, pprint

回答下列问题:

  1. 我们如何能构建一个系统,从非结构化文本中提取结构化数据?
  2. 有哪些稳健的方法识别一个文本中描述的实体和关系?
  3. 哪些语料库适合这项工作,我们如何使用它们来训练和评估我们的模型?

7.1 信息提取

信息提取结构

信息提取系统的简单的流水线结构。以一个文档的原始文本作为其输入,生成(entity, relation, entity)元组的一个链表作为输出。例如:假设一个文档表明Georgia-Pacific 公司位于Atlanta,它可能产生元组([ORG: ‘Georgia-Pacific’] ‘in’ [LOC: ‘Atlanta’])。

def ie_preprocess(document):
    sentences = nltk.sent_tokenize(document) # 句子分割器
    sentences = [nltk.word_tokenize(sent) for sent in sentences] #分词器
    sentences = [nltk.pos_tag(sent) for sent in sentences] # 词性标注器

7.2 分块

分块(chunk)就像分词忽略空白符,通常选择标识符的一个子集,分块构成的源文本中的片段不能重叠。

名词短语分块

NP-分块(NP-chunking),NP-块用方括号标记:例如:

[ The/DT market/NN ] for/IN [ system-management/NN software/NN ] for/
IN [ Digital/NNP ] [ ’s/POS hardware/NN ] is/VBZ fragmented/JJ enough/RB
that/IN [ a/DT giant/NN ] such/JJ as/IN [ Computer/NNP Associates/NNPS ]
should/MD do/VB well/RB there/RB ./.

NP-分块信息最有用的来源之一是词性标记。为了创建一个NP-块,首先定义一个块语法,规则句子应如何分块。下例中将用一个正则表达式规则定义一个简单的语法。这条规则是说一个NP-块由一个可选的限定词(DT)
后面跟着任何数目的形容词(JJ)然后是一个名词(NN)组成。使用此语法,我们创建了一个块分析器,测试例句。结果是一棵树,我们可以输出或图形显示。

例7-1. 一个简单的基于正则表达式的NP 分块器的例子

sentence = [("the", "DT"), ("little", "JJ"), ("yellow", "JJ"), 
            ("dog", "NN"), ("barked", "VBD"), ("at", "IN"), ("the", "DT"), ("cat", "NN")]
grammar = "NP: {<DT>?<JJ>*<NN>}"
cp = nltk.RegexpParser(grammar)
result = cp.parse(sentence)
print(result)
(S
  (NP the/DT little/JJ yellow/JJ dog/NN)
  barked/VBD
  at/IN
  (NP the/DT cat/NN))
result.draw()

在这里插入图片描述

标记模式

组成一个块语法的规则使用标记模式来描述已标注的词的序列。一个标记模式是一个用尖括号分隔的词性标记序列,如

?*。

another/DT sharp/JJ dive/NN

trade/NN figures/NNS

any/DT new/JJ policy/NN measures/NNS

earlier/JJR stages/NNS

Panamanian/JJ dictator/NN Manuel/NNP Noriega/NNP

?

例7-2 显示了一个由2 个规则组成的简单的块语法。第一条规则匹配一个可选的限定词或所有格代名词,零个或多个形容词,然后跟一个名词。第二条规则匹配一个或多个专有名词。

例7-2. 简单的名词短语分块器。

grammar = r"""
NP: {<DT|PP\$>?<JJ>*<NN>} # chunk determiner/possessive, adjectives and nouns
{<NNP>+} # chunk sequences of proper nouns
"""
cp = nltk.RegexpParser(grammar)
sentence = [("Rapunzel", "NNP"), ("let", "VBD"), ("down", "RP"),("her", "PP$"), ("long", "JJ"), ("golden", "JJ"), ("hair", "NN")]
print(cp.parse(sentence))
(S
  (NP Rapunzel/NNP)
  let/VBD
  down/RP
  (NP her/PP$ long/JJ golden/JJ hair/NN))

注意:KaTeX parse error: Expected 'EOF', got '\来' at position 25: …的一个特殊字符,必须使用转义符\̲来̲匹配PP标记。
如果标记模式匹配位置重叠,最左边的匹配优先。

nouns = [("money", "NN"), ("market", "NN"), ("fund", "NN")]
grammar = "NP: {<NN><NN>} # Chunk two consecutive nouns"
cp = nltk.RegexpParser(grammar)
print(cp.parse(nouns))
(S (NP money/NN market/NN) fund/NN)
grammar = "NP: {<NN>+}"  #更加宽容的块规则
cp = nltk.RegexpParser(grammar)
print(cp.parse(nouns))
(S (NP money/NN market/NN fund/NN))

探索文本语料库

cp = nltk.RegexpParser('CHUNK: {<V.*> <TO> <V.*>}')
brown = nltk.corpus.brown
for sent in brown.tagged_sents():
    tree = cp.parse(sent)
    for subtree in tree.subtrees():
        if subtree.label() == 'CHUNK': print(subtree)
(CHUNK combined/VBN to/TO achieve/VB)
(CHUNK continue/VB to/TO place/VB)
(CHUNK serve/VB to/TO protect/VB)


(CHUNK transfer/VB to/TO ride/VB)
(CHUNK managed/VBN to/TO automate/VB)

(CHUNK want/VB to/TO buy/VB)
cp = nltk.RegexpParser('CHUNK: {<V.*> <TO><V.*>}')
for sent in brown.tagged_sents():
    tree = cp.parse(sent)
    for subtree in tree.subtrees():
        if subtree.label(
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值