NLTK学习笔记(七):文本信息提取
如何构建一个系统,用于从非结构化的文本中提取结构化的信息和数据?哪些方法使用这类行为?哪些语料库适合这项工作?是否可以训练和评估模型?
信息提取,特别是结构化信息提取,可以类比数据库的记录。对应的关系绑定了对应的数据信息。针对自然语言这类非结构化的数据,为了获取对应关系,应该搜索实体对应的特殊关系,并且用字符串、元素等一些数据结构记录。
实体识别:分块技术
比如:We saw the yellow dog ,按照分块的思想,会将后三个词语分到NP中,而里面的三个词又分别对应 DT/JJ/NN;saw 分到VBD中;We 分到NP中。对于最后三个词语来说,NP就是组块(较大的集合)。为了做到这点,可以借助NLTK自带的分块语法,类似于正则表达式,来实现句子分块。
分块语法的构建
注意三点即可:
- 基本的分块:
组块 :{组块下的子组块}(类似于:"NP: {<DT>?<JJ>*<NN>}"这样的字符串)。而?*+保存了正则表达式的意义。 
import nltk
sentence = [('the','DT'),('little','JJ'),('yellow','JJ'),('dog','NN'),('brak','VBD')]
grammer = "NP: {<DT>?<JJ>*<NN>}"
cp = nltk.RegexpParser(grammer) #生成规则
result = cp.parse(sentence) #进行分块
print(result)
result.draw() #调用matplotlib库画出来
- 可以为不包括再大块中的标识符序列定义一个缝隙:
}<VBD|IN>+{ 
import nltk
sentence = [('the','DT'),('little','JJ'),('yellow','JJ'),('dog','NN'),('bark','VBD'),('at','IN'),('the','DT'),('cat','NN')]
grammer = """NP:
            {<DT>?<JJ>*<NN>}
            }<VBD|NN>+{
            """  #加缝隙,必须保存换行符
cp = nltk.RegexpParser(grammer) #生成规则
result = cp.parse(sentence) #进行分块
print(result)
- 可以递归式的调用,这符合语言结构中的递归嵌套。例如:
VP: {<NP|PP|CLAUSE>*} PP:{<NN><VP>}。此时,RegexpParser函数的参数loop即可以设置为2,多次循环,来防止遗漏。 
树状图
如果调用print(type(result))查看类型就会发现,是	nltk.tree.Tree。从名字看出来这是一种树状结构。nltk.Tree 可以实现树状结构,并且支持拼接技术,提供结点的查询和树的绘制。
tree1 = nltk.Tree('NP',['Alick'])
print(tree1)
tree2 = nltk.Tree('N',['Alick','Rabbit'])
print(tree2)
tree3 = nltk.Tree('S',[tree1,tree2])
print(tree3.label()) #查看树的结点
tree3.draw()
IOB标记
分别代表内部,外部,开始(就是英语单词的首字母)。对于上面讲的 NP,NN这样的分类,只需要在前面加上 I-/B-/O-即可。这样就能使规则外的集合被显式出来,类似上面的加缝隙。
开发和评估分块器
NLTK已经为我们提供了分块器,减少了手动构建规则。同时,也提供了已经分块好的内容,供我们自己构建规则时候进行参考。
#这段代码在python2下运行
from nltk.corpus import conll2000
print conll2000.chunked_sents('train.txt')[99] #查看已经分块的一个句子
text = """
   he /PRP/ B-NP
   accepted /VBD/ B-VP
   the DT B-NP
   position NN I-NP
   of IN B-PP
   vice NN B-NP
   chairman NN I-NP
   of IN B-PP
   Carlyle NNP B-NP
   Group NNP I-NP
   , , O
   a DT B-NP
   merchant NN I-NP
   banking NN I-NP
   concern NN I-NP
   . . O
"""
result = nltk.chunk.conllstr2tree(text,chunk_types=['NP'])
对于之前自己定义的规则cp,可以使用cp.evaluate(conll2000.chunked_sents('train.txt')[99]) 来测试正确率。利用之前学过的Unigram标注器,可以进行名词短语分块,并且测试准确度
class UnigramChunker(nltk.ChunkParserI):
    """
        一元分块器,
        该分块器可以从训练句子集中找出每个词性标注最有可能的分块标记,
        然后使用这些信息进行分块
    """
    def __init__(self, train_sents):
        """
            构造函数
            :param train_sents: Tree对象列表
        """
        train_data = []
        for sent in train_sents:
            # 将Tree对象转换为IOB标记列表[(word, tag, IOB-tag), ...]
            conlltags = nltk.chunk.tree2conlltags(sent)
            # 找出每个词性标注对应的IOB标记
            ti_list = [(t, i) for w, t, i in conlltags]
            train_data.append(ti_list)
        # 使用一元标注器进行训练
        self.__tagger = nltk.UnigramTagger(train_data)
    def parse(self, tokens):
        """
            对句子进行分块
            :param tokens: 标注词性的单词列表
            :return: Tree对象
        """
        # 取出词性标注
        tags = [tag for (word, tag) in tokens]
        # 对词性标注进行分块标记
        ti_list = self.__tagger.tag(tags)
        # 取出IOB标记
        iob_tags = [iob_tag for (tag, iob_tag) in ti_list]
        # 组合成conll标记
        conlltags = [(word, pos, iob_tag) for ((word, pos), iob_tag) in zip(tokens, iob_tags)]
        return nltk.chunk.conlltags2tree(conlltags)
test_sents = conll2000.chunked_sents("test.txt", chunk_types=["NP"])
train_sents = conll2000.chunked_sents("train.txt", chunk_types=["NP"])
unigram_chunker = UnigramChunker(train_sents)
print(unigram_chunker.evaluate(test_sents))
命名实体识别和信息提取
命名实体:确切的名词短语,指特定类型的个体,如日期、人、组织等 。如果自己去许梿分类器肯定头大(ˉ▽ ̄~)~~。NLTK提供了一个训练好的分类器--nltk.ne_chunk(tagged_sent[,binary=False]) 。如果binary被设置为True,那么命名实体就只被标注为NE;否则标签会有点复杂。
sent = nltk.corpus.treebank.tagged_sents()[22]
print(nltk.ne_chunk(sent,binary=True))
如果命名实体被确定后,就可以实现关系抽取来提取信息。一种方法是:寻找所有的三元组(X,a,Y)。其中X和Y是命名实体,a是表示两者关系的字符串,示例如下:
#请在Python2下运行
import re
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.show_raw_rtuple(rel)
欢迎进一步交流本博文相关内容:
博客园地址 : http://www.cnblogs.com/AsuraDong/
CSDN地址 : http://blog.csdn.net/asuradong
也可以致信进行交流 : xiaochiyijiu@163.com
欢迎转载 , 但请指明出处 : )
NLTK学习笔记(七):文本信息提取的更多相关文章
- NLTK学习笔记(二):文本、语料资源和WordNet汇总
		
目录 语料库基本函数表 文本语料库分类 常见语料库及其用法 载入自定义语料库 词典资源 停用词语料库 WordNet面向语义的英语字典 语义相似度 语料库基本函数表 示例 描述 fileids() 语 ...
 - (转)Qt Model/View 学习笔记 (七)——Delegate类
		
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
 - Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live
		
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
 - Typescript 学习笔记七:泛型
		
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
 - python3.4学习笔记(七) 学习网站博客推荐
		
python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...
 - Go语言学习笔记七: 函数
		
Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...
 - iOS 学习笔记七 【博爱手把手教你使用2016年gitHub Mac客户端】
		
iOS 学习笔记七 [博爱手把手教你使用gitHub客户端] 第一步:首先下载git客户端 链接:https://desktop.github.com 第二步:fork 大神的代码[这里以我的代码为例 ...
 - 【opencv学习笔记七】访问图像中的像素与图像亮度对比度调整
		
今天我们来看一下如何访问图像的像素,以及如何改变图像的亮度与对比度. 在之前我们先来看一下图像矩阵数据的排列方式.我们以一个简单的矩阵来说明: 对单通道图像排列如下: 对于双通道图像排列如下: 那么对 ...
 - Linux学习笔记(七) 查询系统
		
1.查看命令 (1)man 可以使用 man 命令名称 命令查看某个命令的详细用法,其显示的内容如下: NAME:命令名称 SYNOPSIS:语法 DESCRIPTION:说明 OPTIONS:选项 ...
 
随机推荐
- 阿里大数据比赛sesson2_RF&GBRT(下)
			
-----------__-----------接上文---------__---------- 2.Xlab RF上手 2.1.训练特征表准备 训练的特征表gbrt_offline_section_ ...
 - Timus 1009. K-based Numbers
			
1009. K-based Numbers Time limit: 0.5 secondMemory limit: 64 MB Let’s consider K-based numbers, cont ...
 - android TextView不用ScrollViewe也可以滚动的方法
			
TextView textview = (TextView) findViewById(R.id.text); /** * * 只有调用了该方法,TextView才能不依赖于ScrollView而实现 ...
 - P3959 宝藏 状压dp
			
之前写了一份此题关于模拟退火的方法,现在来补充一下状压dp的方法. 其实直接在dfs中状压比较好想,而且实现也很简单,但是网上有人说这种方法是错的...并不知道哪错了,但是就不写了,找了一个正解. 正 ...
 - PKUACM2018 A Wife——DP
			
题目:http://poj.openjudge.cn/practice/C18A/ 据说正解是差分约束,转化的过程还要用到标准型.对偶型什么的知识,暂时还不太懂... 但也有贪心DP做法,有个结论:一 ...
 - Gold Coins
			
http://poj.org/problem?id=2000 #include<stdio.h> ; int main() { int coin[N]; ,j,k; j = ; k = ; ...
 - selenium3 + python - action_chains源码分析
			
ActionChains简介 actionchains是selenium里面专门处理鼠标相关的操作如:鼠标移动,鼠标按钮操作,按键和上下文菜单(鼠标右键)交互.这对于做更复杂的动作非常有用,比如悬停和 ...
 - JVM-垃圾回收器
			
目录 垃圾收集器 Serial收集器 Serial Old 收集器 ParNew 收集器 Parallel Scavenge 收集器 (并行清除) /'pærəlɛl/ /'skævɪndʒ/ Par ...
 - OpenResty / Nginx模块,Lua库和相关资源的列表
			
OpenResty / Nginx模块,Lua库和相关资源的列表 什么是OpenResty OpenResty是一个成熟的网络平台,它集成了标准的Nginx核心,LuaJIT,许多精心编写的Lua库, ...
 - RabbitMQ~消费者实时与消息服务器保持通话
			
这个文章主要介绍简单的消费者的实现,rabbitMQ实现的消费者可以对消息服务器进行实时监听,当有消息(生产者把消息推到服务器上之后),消费者可以自动去消费它,这通常是开启一个进程去维护这个对话,它与 ...