">

自然语言处理之语料库技术

摘要:大数据发展的基石就是数据量的快速增加,无论是自然语言处理、数据挖掘、文本处理还是机器学习领域,都是在此基础上通过规则或统计方法进行模型构建的。但是不是数据足够大就叫大数据了呢?是不是数据足够多就构成语料库了呢?带着这些疑问,本章将带你走进语料库的世界,对语料知识进行一次全面而深入的了解。(本文原创,转载必须注明出处.)

语料库浅谈

自然语言

自然语言(英语:Natural language)通常是指一种自然地随文化演化的语言(如英语、汉语、法语、日语等)。人类使用的语言都会被视为“自然”语言,以相对于如编程语言等为计算机而设的“人造”语言。这一种用法可见于自然语言处理一词中。自然语言是人类交流和思维的主要工具。

语料和语料库

语料,通常在统计自然语言处理中实际上不可能观测到大规模的语言实例。所以人们简单地用文本作为替代,并把文本中的上下文关系作为现实世界中语言的上下文关系的替代品。

语料库,语料库一词在语言学上意指大量的文本,通常经过整理,具有既定格式与标记。其具备三个显著的特点:

  • 语料库中存放的是在语言的实际使用中真实出现过的语言材料。
  • 语料库是以电子计算机为载体承载语言知识的基础资源,但并不等于语言知识。
  • 真实语料需要经过加工(分析和处理),才能成为有用的资源。

语料库语言学

大多数学者普遍认为: “语言学的研究必须基于语言事实的基础,必须详尽的大量的占有材料,才有可能在理论上得出比较可靠的结论”。
传统语言材料的搜集整理和加工完全以手工进行,费时费力,直到计算机出现并随之计算能力强大之后,原先手工的工作开始转向计算机去做,后来逐渐的方法完善中,提出一些初步的理论,形成了语料学这样一门语言学与计算机科学交叉的学科。

语料库语言学的研究范畴:主要研究机器可读自然语言文本的采集、存储、检索、统计、语法标注、句法语义分析,以及具有上述功能的语料库在语言教学、语言定量分析、词汇研究、词语搭配研究、词典编制、语法研究、语言文化研究、法律语言研究、作品风格分析、自然语言理解、机器翻译等方面的应用。

建立语料库的意义

语料库是为一个或者多个应用目标而专门收集的,有一定结构的、有代表的、可被计算机程序检索的、具有一定规模的语料集合。本质上讲,语料库实际上是通过对自然语言运用的随机抽样,以一定大小的语言样本来代表某一研究中所确定的语言运用的总体。

语料库深入

语料库划分与种类

语料库的划分一直是标准各异,其中冯志伟教授的语料库划分比较有影响力且在学术界认可度较高。其划分类型如下:

  • 按语料选取的时间划分,可分为历时语料库( diachronic corpus)和共时语料库(synchronic corpus)。
  • 按语料的加工深度划分,可分为标注语料库( annotated corpus)和非标注语料库(non-annotated corpus)。
  • 按语料库的结构划分,可分为平衡结构语料库( balance structure corpus)和自然随机结构的语料库(random structure corpus)。
  • 按语料库的用途划分,可分为通用语料库(general corpus)和专用语料库(specialized corpus)。
  • 按语料库的表达形式划分,可分为口语语料库( spoken corpus)和文本语料库(text corpus)。
  • 按语料库中语料的语种划分,可分为单语种语料库(monolingual corpora)和多语种语料库(multilingual corpora)。多语种语料库又可以再分为比较语料库(comparable corpora)和平行语料库( parallel corpora)。比较语料库的目的侧重于特定语言现象的对比,而平行语料库的目的侧重于获取对应的翻译实例。
  • 按语料库的动态更新程度划分,可分为参考语料库( reference corpus)和监控语料库(monitor corpus)。参考语料库原则上不作动态更新,而监控语料库则需要不断地进行动态更新。

语料库构建原则

语料库应该具有代表性、结构性、平衡性、规模需求并制定语料的元数据规范,各个原则具体介绍如下:

  • 代表性:在应用领域中,不是根据量而划分是否是语料库,而是在一定的抽样框架范围内采集而来的,并且能在特定的抽样框架内做到代表性和普遍性。
  • 结构性:有目的地收集语料的集合,必须以电子形式存在,计算机可读的语料集合结构性体现在语料库中语料记录的代码,元数据项、数据类型、数据宽度、取值范围、完整性约束。
  • 平衡性:主要体现在平缓因子:学科、年代、文体、地域、登载语料的媒体、使用者的年龄、性别、文化背景、阅历、预料用途(私信/广告等),根据实际情况选择其中一个或者几个重要的指标作为平衡因子,最常见的平衡因子有学科、年代、文体、地域等。
  • 规模性:大规模的语料对语言研究特别是对自然语言研究处理很有用,但是随着语料库的增大,垃圾语料越来越多,语料达到一定规模以后,语料库功能不能随之增长,语料库规模应根据实际情况而定。
  • 元数据:元数据对于研究语料库有着重要的意义,我们可以通过元数据了解语料的时间、地域、作者、文本信息等;还可以构建不同的子语料库;除此之外,还可以对不同的子语料对比;另外还可以记录语料知识版权、加工信息、管理信息等。
    注意:汉语词与词之间没有空隙,不便于计算机处理,一般需要进行切词和词性标注。
    

语料标注的优缺点

  • 优点: 研究方便。可重用、功能多样、分析清晰。

  • 缺点: 语料不客观(手工标注准确率高而一致性差,自动或者半自动标注一致性高而准确率差)、标注不一致、准确率低。

自然语言处理工具包:NLTK

NLTK简介

NLTK

NLTK(Natural language Toolkit):自然语言工具包,Python编程语言实现的统计自然语言处理工具。它是由宾夕法尼亚大学计算机和信息科学的史蒂芬-伯德和爱德华·洛珀编写的。 NLTK支持NLP研究和教学相关的领域,其收集的大量公开数据集、模型上提供了全面易用的接口,涵盖了分词、词性标注(Part-Of-Speech tag, POS-tag)、命名实体识别(Named Entity Recognition, NER)、句法分析(Syntactic Parse)等各项 NLP 领域的功能。广泛应用在经验语言学,认知科学,人工智能,信息检索和机器学习。 在25个国家中已有 32所大学将NLTK作为教学工具。

NLTK模块及功能如表8-1所示:

表8-1 NLTK模块功能
任务 模块 描述
获取语料库 nltk.corpus 语料库和词典的标准化接口
字符串处理 nltk.tokenize,nltk.stem 分词、句子分解和提取主干(不支持中文)
搭配研究 nltk.collocations t检验、卡方检验和互信息
词性标注 nltk.tag n-gram、backoff和HMM
分类 nltk.classify、nltk.cluster 决策树、最大熵、朴素贝叶斯、EM和K-means
分块 nltk.chunk 正则表达式、n-gram和命名实体
解析 nltk.parse 图标、基于特征、一致性和概率性
语义解释 nltk.sem、nltk.inference 演算、模型检验
指标评测 nltk.metrics 准确率、召回率和协议系数
概率与估计 nltk.probability 频率分布和平滑概率分布
应用 nltk.app、nltk.chat 图形化关键字排序、分析器,wordNet查看器
语言学领域工作 nltk.toolbox 处理SIL工具箱格式的数据
## NLTK安装 > NLTK 安装 (1) 查看python版本,如图8-1所示
![](https://i.imgur.com/2XNlMtE.png) 图8-1 Python版本

(2) windows系统下载NLTK如下文件nltk-3.2.1.win32.exe(https://pan.baidu.com/s/1qYzXFPy),并执行exe文件,会自动匹配到python安装路径,如果没有找到路径说明nltk版本不正确,去官网(https://pypi.python.org/pypi/nltk/3.2.1)选择正确版本号下载。如图8-2所示

![](https://i.imgur.com/xWM8kUV.png) 图8-2 python安装根路径

(3) 安装成功后,打开python编辑器,输入“import nltk”和“nltk.download()”下载NLTK数据包(如图8-3所示)选中book,修改下载路径“D:\Users\Administrator\Anaconda3\nltk_data”。(book包含了数据案例和内置函数)。

>>> import nltk
>>> nltk.download()
![](https://i.imgur.com/0hWOEkk.png) 图8-3 下载NLTK的book数据包

(4) 环境变量配置:计算机->属性->高级系统设置->高级->环境变量-系统变量->path,输入如下路径:

D:\Users\Administrator\Anaconda3\nltk_data

(5) 打开python解释器输入如下代码,出现如图8-4则安装成功。

>>> from nltk.book import *
![](https://i.imgur.com/kJ1DrqR.png) 图8-4 成功安装NLTK数据包
> NLTK 核心包 NLTK核心包主要包括如下,在安装Anaconda时候已经预安装过了。如果读者没有采用Anaconda安装方式,可以点击([http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy](http://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy))下载安装即可。 - NLTK-Data:分析和处理语言的语料库 - NumPy:科学计算库 - Matplotlib:数据可视化2D绘图库 - NetworkX:存储和操作有节点和边组成的网络结构函数库 ## NLTK使用 > NLTK加载book模块
>>> import nltk
>>> from nltk.book import *
>>> text1

Text: Moby Dick by Herman Melville 1851

如上代码,第一句是导入NLTK模块,第二句是导入book模块下的全部文件,第三句是显示text1文本信息,第四句是text1文本书名和字节数。

函数concordance搜索指定内容

我们想要在text1《白鲸记》一文中检索美国(即“American”),输入如下代码,执行结果首先显示总共出现12次,它不仅可以展示全文所有出现“American”出现的地方及其上下文,也可以对齐方式打印出来,便于对比分析。

>>> text1.concordance('America')
Displaying 12 of 12 matches:
 of the brain ." -- ULLOA ' S SOUTH AMERICA . " To fifty chosen sylphs of speci
, in spite of this , nowhere in all America will you find more patrician - like
hree pirate powers did Poland . Let America add Mexico to Texas , and pile Cuba
 , how comes it that we whalemen of America now outnumber all the rest of the b
mocracy in those parts . That great America on the other side of the sphere , A
f age ; though among the Red Men of America the giving of the white belt of wam
 and fifty leagues from the Main of America , our ship felt a terrible shock , 
, in the land - locked heart of our America , had yet been nurtured by all thos
 some Nor ' West Indian long before America was discovered . What other marvels
d universally applicable . What was America in 1492 but a Loose - Fish , in whi
w those noble golden coins of South America are as medals of the sun and tropic
od of the last one must be grown in America ." " Aye , aye ! a strange sight th
>>>

函数similar查找相似上下文

我们想要在text1《白鲸记》中检索与‘very’相似的上下文,输入如下代码即可:

>>> text1.similar('very')
a same so last first pretty the too only other one rather as great
entire next white strange long broad

函数common_contexts共用多个词汇的上下文

那么,当我们不满足在text1《白鲸记》中检索某个单词,而是想搜索共用多个词汇的上下文时,请输入如下代码:

>>> text1.common_contexts(['a','very'])
by_heedful was_good was_clear is_curious had_little of_great was_calm
s_queer

函数dispersion_plot离散图表示词汇分布情况

判断词在文本中的位置,从开头算起有多少词出现,可以离散图表示,每一列代表一个单词,每一行代表有个文本。还是以text1《白鲸记》为例,如下代码:运行结果如图8-5所示:

>>> text1.dispersion_plot(["The","Moby","Dick","America"])
![](https://i.imgur.com/gePEK81.png) 图8-5 词汇分布情况

函数len()计数词汇

>> len(text1)
260819

词汇表排序

>> sorted(set(text1))
词汇表大小
>> len(set(text1))
每个词平均使用次数
>> len(text1)/len(set(text1))
特定词在文本中出现的次数
>> text1.count("smote")
特定词在文本中所占的百分比
>> 100*text1.count('a')/len(text1)

NLTK搜索函数FreqDist()

  • 查询文本text1中词汇分布情况,诸如the使用了13721次
    >>> fdist1=FreqDist(text1)
    >>> fdist1
    FreqDist({',': 18713, 'the': 13721, '.': 6862, 'of': 6536, 'and': 6024, 'a': 4569, 'to': 4542, ';': 4072, 'in': 3916, 'that': 2982, ...})
    
  • 指定查询某个词的使用频率
    >>> fdist1['whale']
    906
    
  • 指定常用词累积频率图

fdist1.plot(50,cumulative=True),text1中50个常用词的累积频率图,这些词占了所有标识的将近一半,如图8-6所示。

![](https://i.imgur.com/yaoku81.png) 图8-6 常用词累积频率图

注意:函数fdist1.hapaxes()低频词出现1次查找

细粒度查询

>> V=set(text1)
>> longwords=[w for w in V if len(w) > 15]
>> sorted(longwords)
['CIRCUMNAVIGATION', 'Physiognomically', 'apprehensiveness', 'cannibalistically', 'characteristically', 'circumnavigating', 'circumnavigation', 'circumnavigations', 'comprehensiveness', 'hermaphroditical', 'indiscriminately', 'indispensableness', 'irresistibleness', 'physiognomically', 'preternaturalness', 'responsibilities', 'simultaneousness', 'subterraneousness', 'supernaturalness', 'superstitiousness', 'uncomfortableness', 'uncompromisedness', 'undiscriminating', 'uninterpenetratingly']
>> 

查询文本中单词长度大于10并且出现次数超过10次的

>>> sorted(w for w in set(text1) if len(w) > 10 and fdist1[w] > 10)
['Nantucketer', 'Nevertheless', 'circumstance', 'circumstances', 'considerable', 'considering', 'continually', 'countenance', 'disappeared', 'encountered', 'exceedingly', 'experienced', 'harpooneers', 'immediately', 'indifferent', 'indispensable', 'involuntarily', 'naturalists', 'nevertheless', 'occasionally', 'peculiarities', 'perpendicular', 'significant', 'simultaneously', 'straightway', 'unaccountable']
>>> 

词语搭配和双连词

搭配:不经常在一起出现的词序列,如red wine是搭配而the wine就不是。另一个特点就是词不能被类似的词置换,如maroon wine(栗色酒)就不行

bigrams():获取搭配,提前文本词汇的双连词

>>> from nltk import bigrams
>>> from collections import Counter
>>> b = bigrams('This is a test')
>>> Counter(b)
Counter({('s', ' '): 2, ('i', 's'): 2, ('s', 't'): 1, (' ', 'i'): 1, (' ', 'a'): 1, (' ', 't'): 1, ('a', ' '): 1, ('h', 'i'): 1, ('e', 's'): 1, ('t', 'e'): 1, ('T', 'h'): 1})
>>> 

NLTK频率分布类中定义的函数

  • fdist=FreqDist(Samples) 创建包含给定样本的频率分布
  • fdist.inc(Sample) 增加样本
  • fdist[‘monstrous’] 计数给定样本出现的次数
  • fdist.freq(‘monstrous’) 给定样本的频率
  • fdist.N() 样本总数
  • fdist.keys() 以频率递减顺序排序样本链表
  • for sample in fdist: 以频率递减顺序遍历样本
  • fdist.max() 数值最大的样本
  • fdist.tabulate() 绘制频率分布表
  • fdist.plot() 绘制频率分布图
  • fdist.plot(cumulative=True)绘制累积频率分布图
  • fdist1<fdist2 测试样本在fdist1中出现的频率是否小于fdist2

词汇比较运算

  • s.startswith(t) 测试是否t开头
  • s.endswith(t) 测试是否t结尾
  • t in s 测试s是否包含t
  • s.islower() 测试s所有字符是否都是小写字母
  • s.isupper() 测试s所有字符是否都是大写字母
  • s.isalpha() 测试s所有字符是否都是字母
  • s.isalnum() 测试s所有字符是否都是字母或数字
  • s.isdigit() 测试s所有字符是否都是数字
  • s.istitle() 测试s所有词首字母都是大写

Python NLTK下使用stanford NLP

NLTK和StandfordNLP简介

  • NLTK:由宾夕法尼亚大学计算机和信息科学系使用python语言实现的一种自然语言工具包,其收集的大量公开数据集、模型上提供了全面易用的接口,涵盖了分词、词性标注(Part-Of-Speech tag, POS-tag)、命名实体识别(Named Entity Recognition, NER)、句法分析(Syntactic Parse)等各项 NLP 领域的功能。

  • Stanford NLP:是由斯坦福大学的 NLP 小组开源的 Java 实现的 NLP 工具包,同样对 NLP 领域的各个问题提供了解决办法。斯坦福大学的 NLP 小组是世界知名的研究小组,能将 NLTK 和 Stanford NLP 这两个工具包结合起来使用,那对于自然语言开发者是再好不过了。2004 年 Steve Bird 在 NLTK 中加上了对 Stanford NLP 工具包的支持,通过调用外部的 jar 文件来使用 Stanford NLP 工具包的功能这样一来就变得更为方便好用。

本文在主要介绍NLTK 中提供 Stanford NLP 中的以下几个功能:

  • 中英文分词: StanfordTokenizer
  • 中英文词性标注: StanfordPOSTagger
  • 中英文命名实体识别: StanfordNERTagger
  • 中英文句法分析: StanfordParser
  • 中英文依存句法分析: StanfordDependencyParser

安装配置过程中注意事项

本文以Python 3.5.2和java version “1.8.0_111”版本进行配置,具体安装需要注意以下几点:

  • Stanford NLP 工具包需要 Java 8 及之后的版本,如果出错请检查 Java 版本
  • 本文的配置都是以 Stanford NLP 3.6.0 为例,如果使用的是其他版本,请注意替换相应的文件名
  • 本文的配置过程以 NLTK 3.2 为例,如果使用 NLTK 3.1,需要注意该旧版本中 StanfordSegmenter 未实现,其余大致相同
  • 下面的配置过程是具体细节可以参照:http://nlp.stanford.edu/software/

    StandfordNLP必要工具包下载

必要包下载:只需要下载以下3个文件就够了,stanfordNLTK文件里面就是StanfordNLP工具包在NLTK中所依赖的jar包和相关文件

以上文件下载后,Jar如果是1.8的版本可以不用下载,另外两个压缩包下载到本地,解压后拷贝文件夹到你的python安装主路径下,然后cmd进入NLTK下通过python setup.py install即可。后面操作讲路径简单修改即可。(如果不能正常分词等操作,查看python是否是3.2以上版本,java是否是8以后版本,jar环境变量是否配置正确)

StanfordNLTK目录结构如下:(从各个压缩文件已经提取好了,如果读者感兴趣,下面有各个功能的源码文件)

![](https://i.imgur.com/eguMwDH.jpg) 图8-7 Stanford NLTK源码解析
  • 分词依赖:stanford-segmenter.jar、 slf4j-api.jar、data文件夹相关子文件
  • 命名实体识别依赖:classifiers、stanford-ner.jar
  • 词性标注依赖:models、stanford-postagger.jar
  • 句法分析依赖:stanford-parser.jar、stanford-parser-3.6.0-models.jar、classifiers
  • 依存语法分析依赖:stanford-parser.jar、stanford-parser-3.6.0-models.jar、classifiers

压缩包下载和源码分析

  • 分词压缩包:StanfordSegmenter和StanfordTokenizer:下载stanford-segmenter-2015-12-09.zip (https://pan.baidu.com/s/1kVc20ib) 解压获取目录中的 stanford-segmenter-3.6.0.jar 拷贝为 stanford-segmenter.jar和 slf4j-api.jar
  • 词性标注压缩包:下载stanford-postagger-full-2015-12-09.zip (https://pan.baidu.com/s/1hrVMSE4) 解压获取stanford-postagger.jar
  • 命名实体识别压缩包:下载stanford-ner-2015-12-09.zip (https://pan.baidu.com/s/1skOJb5r) ,将解压获取stanford-ner.jar和classifiers文件
  • 句法分析、句法依存分析:下载stanford-parser-full-2015-12-09.zip (http://pan.baidu.com/s/1nv6Q2bZ) 解压获取stanford-parser.jar 和 stanford-parser-3.6.0-models.jar

Standford NLP的应用

(1) 分词

StanfordSegmenter 中文分词:下载52nlp改过的NLTK包nltk-develop(https://pan.baidu.com/s/1misFxna),解压后将其拷贝到你的python目录下,进去E:\Python\nltk-develop采用python 编辑器打开setup.py文件,F5运行,输入以下代码:

>>> from nltk.tokenize.stanford_segmenter import StanfordSegmenter
>>> segmenter = StanfordSegmenter(
    path_to_jar=r"E:\tools\stanfordNLTK\jar\stanford-segmenter.jar",
    path_to_slf4j=r"E:\tools\stanfordNLTK\jar\slf4j-api.jar",
    path_to_sihan_corpora_dict=r"E:\tools\stanfordNLTK\jar\data",
    path_to_model=r"E:\tools\stanfordNLTK\jar\data\pku.gz",
    path_to_dict=r"E:\tools\stanfordNLTK\jar\data\dict-chris6.ser.gz"
)
>>> str="我在博客园开了一个博客,我的博客名叫伏草惟存,写了一些自然语言处理的文章。"
>>> result = segmenter.segment(str)
>>> result
执行结果: [我 在 博客 园 开 了 一个 博客 , 我 的 博客 名 叫 伏 草 惟 存 , 写 了 一些 自然 语言 处理 的 文章。] 程序解读:StanfordSegmenter 的初始化参数说明: - path_to_jar: 用来定位jar包,本程序分词依赖stanford-segmenter.jar(注: 其他所有 Stanford NLP 接口都有 path_to_jar 这个参数。) - path_to_slf4j: 用来定位slf4j-api.jar作用于分词 - path_to_sihan_corpora_dict: 设定为 stanford-segmenter-2015-12-09.zip 解压后目录中的 data 目录, data 目录下有两个可用模型 pkg.gz 和 ctb.gz 需要注意的是,使用 StanfordSegmenter 进行中文分词后,其返回结果并不是 list ,而是一个字符串,各个汉语词汇在其中被空格分隔开。 StanfordTokenizer 英文分词
Python 3.5.2 (v3.5.2:4def2a2901a5, Jun 25 2016, 22:01:18) [MSC v.1900 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> from nltk.tokenize import StanfordTokenizer
>>> tokenizer = StanfordTokenizer(path_to_jar=r"E:\tools\stanfordNLTK\jar\stanford-parser.jar")
>>> sent = "Good muffins cost $3.88\nin New York.  Please buy me\ntwo of them.\nThanks."
>>> print(tokenizer.tokenize(sent))

运行结果:
[‘Good’, ‘muffins’, ‘cost’, ‘$’, ‘3.88’, ‘in’, ‘New’, ‘York’, ‘.’, ‘Please’, ‘buy’, ‘me’, ‘two’, ‘of’, ‘them’, ‘.’, ‘Thanks’, ‘.’]

(2) 命名实体识别

StanfordNERTagger 英文命名实体识别

>>> from nltk.tag import StanfordNERTagger
>>> eng_tagger = StanfordNERTagger(model_filename=r'E:\tools\stanfordNLTK\jar\classifiers\english.all.3class.distsim.crf.ser.gz',path_to_jar=r'E:\tools\stanfordNLTK\jar\stanford-ner.jar')
>>> print(eng_tagger.tag('Rami Eid is studying at Stony Brook University in NY'.split()))

运行结果

[('Rami', 'PERSON'), ('Eid', 'PERSON'), ('is', 'O'), ('studying', 'O'), ('at', 'O'), ('Stony', 'ORGANIZATION'), ('Brook', 'ORGANIZATION'), ('University', 'ORGANIZATION'), ('in', 'O'), ('NY', 'O')]

StanfordNERTagger 中文命名实体识别

>>> result
'四川省 成都 信息 工程 大学 我 在 博客 园 开 了 一个 博客 , 我 的 博客 名叫 伏 草 惟 存 , 写 了 一些 自然语言 处理 的 文章 。\r\n'
>>> from nltk.tag import StanfordNERTagger
>>> chi_tagger = StanfordNERTagger(model_filename=r'E:\tools\stanfordNLTK\jar\classifiers\chinese.misc.distsim.crf.ser.gz',path_to_jar=r'E:\tools\stanfordNLTK\jar\stanford-ner.jar')
>>> for word, tag in  chi_tagger.tag(result.split()):
    print(word,tag)

运行结果:

四川省    ORG
成都        ORG
信息        ORG
工程        ORG
大学        ORG
我        O
在        O
博客        O
园        O
开        O
了        O
一个        O
博客        O
,        O
我        O
的        O
博客        O
...        ...

(3) 词性标注

StanfordPOSTagger 英文词性标注

>>> from nltk.tag import StanfordPOSTagger
>>> eng_tagger = StanfordPOSTagger(model_filename=r'E:\tools\stanfordNLTK\jar\models\english-bidirectional-distsim.tagger',path_to_jar=r'E:\tools\stanfordNLTK\jar\stanford-postagger.jar')
>>> print(eng_tagger.tag('What is the airspeed of an unladen swallow ?'.split()))

运行结果:

[('What','WP'),('is','VBZ'),('the','DT'),('airspeed','NN'),('of','IN'),('an','DT'),('unladen','JJ'),('swallow','VB'),('?','.')]

StanfordPOSTagger 中文词性标注

>>> from nltk.tag import StanfordPOSTagger
>>> chi_tagger = StanfordPOSTagger(model_filename=r'E:\tools\stanfordNLTK\jar\models\chinese-distsim.tagger',path_to_jar=r'E:\tools\stanfordNLTK\jar\stanford-postagger.jar')
>>> result
'四川省 成都 信息 工程 大学 我 在 博客 园 开 了 一个 博客 , 我 的 博客 名叫 伏 草 惟 存 , 写 了 一些 自然语言 处理 的 文章 。\r\n'
>>> print(chi_tagger.tag(result.split()))

运行结果

四川省    NR
成都        NR
信息     NN
工程     NN
大学     NN
我         PN
在         P
博客     NN
园         NN
开         VV
了         AS
一个     CD
博客     NN
,         PU
我        PN
的        DEG
博客        NN
...     ...

(4) 句法分析

StanfordParser英文句法分析

>>> from nltk.parse.stanford import StanfordParser
>>> eng_parser = StanfordParser(r"E:\tools\stanfordNLTK\jar\stanford-parser.jar",r"E:\tools\stanfordNLTK\jar\stanford-parser-3.6.0-models.jar",r"E:\tools\stanfordNLTK\jar\classifiers\englishPCFG.ser.gz")
>>> print(list(eng_parser.parse("the quick brown fox jumps over the lazy dog".split())))

运行结果

[Tree('ROOT',[Tree('NP',[Tree('DT',['the']),Tree('JJ',['quick']),Tree('JJ',['brown']),Tree('NN',['for'])]),Tree('NP',[Tree('NP',[Tree('NNS',['jumps'])]),Tree('PP',[Tree('IN',['over']),Tree('NP',[Tree('DT',['the']),Tree('JJ',['lazy']),Tree('NN',['dog'])])])])]]

StanfordParser 中文句法分析

>>> from nltk.parse.stanford import StanfordParser
>>> chi_parser = StanfordParser(r"E:\tools\stanfordNLTK\jar\stanford-parser.jar",r"E:\tools\stanfordNLTK\jar\stanford-parser-3.6.0-models.jar",r"E:\tools\stanfordNLTK\jar\classifiers\chinesePCFG.ser.gz")
>>> sent = u'北海 已 成为 中国 对外开放 中 升起 的 一 颗 明星'
>>> print(list(chi_parser.parse(sent.split())))

运行结果

[Tree('ROOT',[Tree('NP',[Tree('NR',['北海']),Tree('VP',[Tree('ADVP'),[Tree('AD',['已'])]),Tree('VP',Tree('VV',['成为']),Tree('NP',[Tree('NP',[Tree('NR',['中国'])]),Tree('LCP',[Tree('NP'),[Tree('NN',['对外开放'])]),Tree('LC',['中'])]),Tree('CP',Tree('IP')[Tree('VP',[Tree('VV',['升起'])]),Tree('DEC',['的'])]),Tree('QP',[Tree('CD',['一']),Tree('CLR',[Tree('M',['颗'])])]),Tree('NP',[Tree('NN',['明星'])])])])])])])])]

(5) 依存句法分析

StanfordDependencyParser 英文依存句法分析

>>> from nltk.parse.stanford import StanfordDependencyParser
>>> eng_parser = StanfordDependencyParser(r"E:\tools\stanfordNLTK\jar\stanford-parser.jar",r"E:\tools\stanfordNLTK\jar\stanford-parser-3.6.0-models.jar",r"E:\tools\stanfordNLTK\jar\classifiers\englishPCFG.ser.gz")
>>> res = list(eng_parser.parse("the quick brown fox jumps over the lazy dog".split()))
>>> for row in res[0].triples():
    print(row)

运行结果

(('for','NN'),'det',('the','DT'))
(('for','NN'),'amod',('quick','JJ'))
(('for','NN'),'amod',('brown','JJ'))
(('for','NN'),'dep',('jumps','NNS'))
(('jumps','NNS'),'nmod',('dog','NN'))
(('dog','NN'),'case',('over','IN'))
(('dog','NN'),'det',('the','DT'))
(('dog','NN'),'amod',('lazy','JJ'))

StanfordDependencyParser 中文依存句法分析

>>> from nltk.parse.stanford import StanfordDependencyParser
>>> chi_parser = StanfordDependencyParser(r"E:\tools\stanfordNLTK\jar\stanford-parser.jar",r"E:\tools\stanfordNLTK\jar\stanford-parser-3.6.0-models.jar",r"E:\tools\stanfordNLTK\jar\classifiers\chinesePCFG.ser.gz")
>>> res = list(chi_parser.parse(u'四川 已 成为 中国 西部 对外开放 中 升起 的 一 颗 明星'.split()))
>>> for row in res[0].triples():
    print(row)

运行结果

(('成为','VV'),'nsubj',('四川','NR'))
(('成为','VV'),'advmod',('已','AD'))
(('成为','VV'),'dobj',('明星','NN'))
(('明星','NN'),'dep',('对外开放','NN'))
(('对外开放','NN'),'nn',('中国','NR'))
(('对外开放','NN'),'nn',('西部','NN'))
(('对外开放','NN'),'case',('中','LC'))
(('明星','NN'),'relcl',('升起','VV'))
(('升起','VV'),'mark',('的','DEC'))
(('明星','NN'),'clf',('颗','M'))
(('颗','M'),'nummod',('一','CD'))

获取语料库

语料库是语料库语言学研究的基础资源,也是经验主义语言研究的主要资源。应用于词典编纂,语言教学,传统语言研究,自然语言处理中基于统计或实例的研究等方面。关于语料库有三点基本认识:语料库中存放的是在语言的实际使用中真实出现过的语言材料;语料库是以电子计算机为载体承载语言知识的基础资源;真实语料需要经过加工(分析和处理),才能成为有用的资源。

国内外著名语料库

多语料库

英文语料库

中文语料库

  • 搜狗实验室新闻|互联网数据: http://www.sogou.com/labs/

  • 北京大学语言研究中心: http://ccl.pku.edu.cn/term.asp

  • 计算机语言研究所: http://www.icl.pku.edu.cn/icl_res/

  • 数据堂: http://www.datatang.com/

  • 中央研究院平衡语料库(https://www.sinica.edu.tw/SinicaCorpus/):
    专门针对语言分析而设计的,每个文句都依词断开并标示词类。语料的搜集也尽量做到现代汉语分配在不同的主题和语式上,是现代汉语无穷多的语句中一个代表性的样本。现有语料库主要针对语言分析而设计,由中央研究院信息所、语言所词库小组完成,内含有简介、使用说明,现行的语料库是4.0版本。

  • LIVAC汉语共时语料库: http://www.livac.org/index.php?lang=tc

  • 兰开斯特大学汉语平衡语料库: http://www.lancaster.ac.uk/fass/projects/corpus/

  • 兰开斯特-洛杉矶汉语口语语料库: http://www.lancaster.ac.uk/fass/projects/corpus/

  • 语料库语言学在线: http://www.corpus4u.org/

  • 北京森林工作室汉语句义结构标注语料库: http://www.isclab.org.cn/csa/bfs-ctc.htm

  • 国家语委现代汉语语料库(http://www.cncorpus.org/):
    现代汉语通用平衡语料库现在重新开放网络查询了。重开后的在线检索速度更快,功能更强,同时提供检索结果下载。现代汉语语料库在线提供免费检索的语料约2000万字,为分词和词性标注语料。

  • 古代汉语语料库(http://www.cncorpus.org/login.aspx):
    网站现在还增加了一亿字的古代汉语生语料,研究古代汉语的也可以去查询和下载。网站同时还提供了分词、词性标注软件,词频统计、字频统计软件。基于国家语委语料库的字频词频统计结果和发布的词表等进行建库,以供学习研究语言文字的同学老师使用。

  • 《人民日报》标注语料库(http://www.icl.pku.edu.cn/icl_res/):
    《人民日报》标注语料库中一半的语料(1998年上半年)共1300万字,已经通过《人民日报》新闻信息中心公开并提供许可使用权。其中一个月的语料(1998年1月)近200万字在互联网上公布,供自由下载。

  • 古汉语语料库(http://www.sinica.edu.tw/ftms-bin/ftmsw):
    古汉语语料库包含以下五个语料库: 上古汉语、中古汉语(含大藏经)、近代汉语、出土文献、其他。部分数据取自史语所汉籍全文数据库,故两者间内容略有重叠。此语料库之出土文献语料库,全部取自史语所汉简小组所制作的数据库。

  • 近代汉语标记语料库(http://www.sinica.edu.tw/Early_Mandarin/):
    为应对汉语史研究需求而建构的语料库。目前语料库所搜集的语料已涵盖上古汉语(先秦至西汉)、中古汉语(东汉魏晋南北朝)、近代汉语(唐五代以后)大部分的重要语料,并己陆续开放使用;在标记语料库方面,上古汉语及近代汉语都已有部分语料完成标注的工作,并视结果逐步提供上线检索。

  • 树图数据库(http://treebank.sinica.edu.tw/

  • 搜文解字(http://words.sinica.edu.tw/):包含「搜词寻字」、「文学之美」、「游戏解惑」、「古文字的世界」四个单元,可由部件、部首、字、音、词互查,并可查询在四书、老、庄、唐诗中的出处,及直接链接到出处并阅读原文。

  • 文国寻宝记(http://www.sinica.edu.tw/wen/):在搜文解字的基础之上,以华语文学习者为对象,进一步将字、词、音的检索功能与国编、华康、南一等三种版本的国小国语课本结合。与唐诗三百首、宋词三百首、红楼梦、水浒传等文学典籍结合,提供网络上国语文学习的素材。

  • 唐诗三百首(http://cls.admin.yzu.edu.tw/300/):以国中、小学学生为主要使用对象,提供吟唱、绘画、书法等多媒体数据,文字数据包含作者生平、读音标注、翻译、批注、评注、典故出处等资料;检索点包含作 者、诗题、诗句、综合资料、体裁分类等;检索结果可以列出全文,并选择标示相关之文字及多媒体数据。并提供了一套可以自动检查格律、韵脚、批改的「依韵入诗格律自动检测索引教学系统」,协助孩子们依韵作诗,协助教师批改习作。

  • 汉籍电子文献(http://www.sinica.edu.tw/~tdbproj/handy1/):包含整部25史 整部阮刻13经、超过2000万字的台湾史料、1000万字的大正藏以及其他典籍。

  • 红楼梦网络教学研究数据中心(http://cls.hs.yzu.edu.tw/HLM/home.htm):元智大学中国文学网络系统研究室所开发的「网络展书读—中国文学网络系统」,为研究中心负责人罗凤珠老师主持。红楼梦是其中一个子系统,其他还包括善本书、诗经、唐宋诗词、作诗填词等子系统。此网站为国内Internet最大中国文学研究数据库,提供用户最完整的中国文学研究数据。

  • 中国传媒大学文本语料库检索系统(http://ling.cuc.edu.cn/RawPub/

  • 在线分词标注系统(http://ling.cuc.edu.cn/cucseg/

  • 新词语研究资源库(http://ling.cuc.edu.cn/newword/web/index.asp

  • 音视频语料检索系统(http://ling.cuc.edu.cn/mmcpub

  • 哈工大信息检索研究室对外共享语料库资源(http://ir.hit.edu.cn/demo/ltp/Sharing_Plan.htm):该语料库为汉英双语语料库,10万对齐双语句对,文本文件格式,同义词词林扩展版,77,343条词语,秉承《同义词词林》的编撰风格。同时采用五级编码体系,多文档自动文摘语料库,40个主题,文本文件格式,同一主题下是同一事件的不同报道。汉语依存树库,不带关系5万句,带关系1万句;LTML化,分词、词性、句法部分人工标注,可以图形化查看,问答系统问题集,6264句;已标注问题类型,LTML化,分词、词性、句法、词义、浅层语义等程序处理得到,单文档自动文摘语料库共211篇。

  • 清华大学汉语均衡语料库TH-ACorpus(http://www.lits.tsinghua.edu.cn/ainlp/source.htm

  • 中国科学院计算技术研究所,跨语言语料库(http://mtgroup.ict.ac.cn/new/resource/index.php)目前的双语句对数据库中有约180,000对已对齐的中英文句子。 本数据库支持简单的中英文查询服务。 查询结果包括句对编号、中文句子、英文句子、句对来源等。

网络数据获取

从网络和硬盘访问文本(在线获取伤寒杂病论)

>>> from __future__ import division
>>> import nltk,re,pprint
>>> from urllib.request import urlopen
>>> url=r'http://www.gutenberg.org/files/24272/24272-0.txt'
>>> raw=urlopen(url).read()
>>> raw = raw.decode('utf-8')
>>> len(raw)
70306
>>> raw[2000:2500]
运行结果 '。\r\n陽脈浮大而濡,陰脈浮大而濡,陰脈與陽脈同等者,名曰緩也。 脈浮而緊者,名\r\n曰弦也。弦者狀如弓弦,按之不移也。脈緊者,如轉索無常也。\r\n脈弦而大,弦則為減,大則為芤。減則為寒,芤則為虛。寒虛相搏,此名為革。\r\n婦人則半產、漏下,男子則亡血、失精。\r\n問曰:病有戰而汗出,因得解者,何也?答曰:脈浮而緊,按之反芤,此為本虛,\r\n故當戰而汗出也。其人本虛,是以發戰。以脈浮,故當汗出而解也。\r\n若脈浮而數,按之不芤,此人本不虛;若欲自解,但汗出耳,不發戰也。\r\n問曰:病有不戰而汗出解者,何也?答曰:脈大而浮數,故知不戰汗出而解也。\r\n問曰:病有不戰,不汗出而解者,何也?答曰:其脈自微,此以曾經§發汗、若吐、\r\n若下、若亡血,以內無津液,此陰陽自和,必自愈,故不戰、不汗出而解也。\r\n問曰:傷寒三日,脈浮數而微,病人身涼和者,何也?答曰:此為欲解也。解以\r\n夜半。脈浮而解者,濈然汗出也;脈數而解者,必能食也;脈微而解者,必大汗\r\n出也。\r\n問曰:病脈,欲知愈未愈者,何以別之?答曰:寸口、關上、尺中三處,大小、\r\n浮沉、遲數同等,雖有寒熱不解者,此脈陰陽為和平,雖劇當愈。\r\n立夏得洪(一作浮)' > 在线获取处理HTML文本(红楼梦)
>>> import re,nltk
>>> from urllib.request import urlopen
>>> url='http://www.gutenberg.org/cache/epub/24264/pg24264-images.html'
>>> html=urlopen(url).read()
>>> html=html.decode('utf-8')
>>> html[5000:5500]

运行结果

'五次,纂成目錄,分出章回,則題曰《金陵十二釵》.并題一絕云:\r\n\u3000\u3000滿紙荒唐言,一把辛酸淚!\r\n\u3000\u3000都云作者痴,誰解其中味?\r\n\u3000\u3000出則既明,且看石上是何故事.按那石上書云:\r\n\u3000\u3000當日地陷東南,這東南一隅有處曰姑蘇,有城曰閶門者,最是紅塵中一\r\n二等富貴風流之地.這閶門外有個十里街,街內有個仁清巷,巷內有個古廟\r\n,因地方窄狹,人皆呼作葫蘆廟.廟旁住著一家鄉宦,姓甄,名費,字士隱\r\n.嫡妻封氏,情性賢淑,深明禮義.家中雖不甚富貴,然本地便也推他為望\r\n族了.因這甄士隱稟性恬淡,不以功名為念,每日只以觀花修竹,酌酒吟詩\r\n為樂,倒是神仙一流人品.只是一件不足:如今年已半百,膝下無儿,只有\r\n一女,乳名喚作英蓮,年方三歲.\r\n\u3000\u3000一日,炎夏永晝,士隱于書房閒坐,至手倦拋書,伏几少憩,不覺朦朧\r\n睡去.夢至一處,不辨是何地方.忽見那廂來了一僧一道,且行且談.只听\r\n道人問道:“你攜了這蠢物,意欲何往?"那僧笑道:“你放心,如今現有\r\n一段風流公案正該了結,這一干風流冤家,尚未投胎入世.趁此机會,就將\r\n此蠢物夾帶于中,使他去經歷經歷。”那道人道:“原來近日風流冤孽又將\r\n造劫歷世去不成?但'

处理RSS订阅

>>> import feedparser #feedparser需要在python库中下载,或者在cmd中'pip install feedparser'
>>> llog=feedparser.parse(url)

相关正则知识

    • \d 匹配一个数字
    • \w 匹配一个字母或者数字
      • 任意个字符(包括0个)
      • 至少一个字符
    • ? 0个或1个字符
    • {n} n个字符
    • {n,m} n-m个字符
    • \s 匹配一个空格
    • \s+ 至少有一个空格
    • \d{3,8} 表示3-8个数字,例如’1234567’
    • \d{3}\s+\d{3,8}
    • [0-9a-zA-Z_] 匹配一个数字、字母或者下划线
    • [0-9a-zA-Z_]+ 匹配至少由一个数字、字母或者下划线组成的字符串,比如’a100’,’0_Z’,’Py3000’等等
    • [a-zA-Z_][0-9a-zA-Z_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量
    • [a-zA-Z_][0-9a-zA-Z_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)
    • A|B可以匹配A或B,所以(P|p)ython可以匹配’Python’或者’python’
    • ^表示行的开头,^\d表示必须以数字开头
    • 表示行的结束,表示行的结束,\d表示必须以数字结束

NLTK获取语料库

古腾堡语料库

(1) 直接获取语料库的所有文本:nltk.corpus.gutenberg.fileids()

>>> import nltk
>>> nltk.corpus.gutenberg.fileids()

运行效果:

['austen-emma.txt', 'austen-persuasion.txt', 'austen-sense.txt', 'bible-kjv.txt', 'blake-poems.txt', 'bryant-stories.txt', 'burgess-busterbrown.txt', 'carroll-alice.txt', 'chesterton-ball.txt', 'chesterton-brown.txt', 'chesterton-thursday.txt', 'edgeworth-parents.txt', 'melville-moby_dick.txt', 'milton-paradise.txt', 'shakespeare-caesar.txt', 'shakespeare-hamlet.txt', 'shakespeare-macbeth.txt', 'whitman-leaves.txt']

(2) 导入包获取语料库的所有文本

>>> from  nltk.corpus import gutenberg
>>> gutenberg.fileids()
运行效果: ['austen-emma.txt', 'austen-persuasion.txt', 'austen-sense.txt', 'bible-kjv.txt', 'blake-poems.txt', 'bryant-stories.txt', 'burgess-busterbrown.txt', 'carroll-alice.txt', 'chesterton-ball.txt', 'chesterton-brown.txt', 'chesterton-thursday.txt', 'edgeworth-parents.txt', 'melville-moby_dick.txt', 'milton-paradise.txt', 'shakespeare-caesar.txt', 'shakespeare-hamlet.txt', 'shakespeare-macbeth.txt', 'whitman-leaves.txt'] (3) 查找某个文本
>>> persuasion=nltk.corpus.gutenberg.words("austen-persuasion.txt")
>>> len(persuasion)
98171
>>> persuasion[:200]

运行效果:

['[', 'Persuasion', 'by', 'Jane', 'Austen', '1818', ...]

网络和聊天文本

(1) 获取网络聊天文本

>>> from nltk.corpus import webtext
>>> for fileid in webtext.fileids():
    print(fileid,webtext.raw(fileid))

(2) 查看网络聊天文本信息

>>> for fileid in webtext.fileids():
    print(fileid,len(webtext.words(fileid)),len(webtext.raw(fileid)),len(webtext.sents(fileid)),webtext.encoding(fileid))

运行效果:

firefox.txt 102457 564601 1142 ISO-8859-2
grail.txt 16967 65003 1881 ISO-8859-2
overheard.txt 218413 830118 17936 ISO-8859-2
pirates.txt 22679 95368 1469 ISO-8859-2
singles.txt 4867 21302 316 ISO-8859-2
wine.txt 31350 149772 2984 ISO-8859-2

(3) 即时消息聊天会话语料库

>>> from nltk.corpus import nps_chat
>>> chatroom = nps_chat.posts('10-19-20s_706posts.xml')
>>> chatroom[123]

运行效果:

['i', 'do', "n't", 'want', 'hot', 'pics', 'of', 'a', 'female', ',', 'I', 'can', 'look', 'in', 'a', 'mirror', '.']

布朗语料库

(1) 查看语料信息

>>> from nltk.corpus import brown
>>> brown.categories()

运行效果:

['adventure', 'belles_lettres', 'editorial', 'fiction', 'government', 'hobbies', 'humor', 'learned', 'lore', 'mystery', 'news', 'religion', 'reviews', 'romance', 'science_fiction']

(2) 比较文体中情态动词的用法

>>> import nltk
>>> from nltk.corpus import brown
>>> new_texts=brown.words(categories='news')
>>> fdist=nltk.FreqDist([w.lower() for w in new_texts])
>>> modals=['can','could','may','might','must','will']
>>> for m in modals:
    print(m + ':',fdist[m])

运行效果:

can: 94
could: 87
may: 93
might: 38
must: 53
will: 389

(3) NLTK条件概率分布函数

>>> cfd=nltk.ConditionalFreqDist((genre,word) for genre in brown.categories() for word in brown.words(categories=genre))
>>> genres=['news','religion','hobbies','science_fiction','romance','humor']
>>> modals=['can','could','may','might','must','will']
>>> cfd.tabulate(condition=genres,samples=modals)
运行结果 can could may might must will adventure 46 151 5 58 27 50 belles_lettres 246 213 207 113 170 236 editorial 121 56 74 39 53 233 fiction 37 166 8 44 55 52 government 117 38 153 13 102 244 hobbies 268 58 131 22 83 264 humor 16 30 8 8 9 13 learned 365 159 324 128 202 340 lore 170 141 165 49 96 175 mystery 42 141 13 57 30 20 news 93 86 66 38 50 389 religion 82 59 78 12 54 71 reviews 45 40 45 26 19 58 romance 74 193 11 51 45 43 science_fiction 16 49 4 12 8 16 > 路透社语料库 (1) 包括10788个新闻文档,共计130万字,这些文档分90个主题,安装训练集和测试分组,编号‘test/14826’的文档属于测试文档
>>> from nltk.corpus import  reuters
>>> print(reuters.fileids()[:50])

运行结果

['test/14826', 'test/14828', 'test/14829', 'test/14832', 'test/14833', 'test/14839', 'test/14840', 'test/14841', 'test/14842', 'test/14843', 'test/14844', 'test/14849', 'test/14852', 'test/14854', 'test/14858', 'test/14859', 'test/14860', 'test/14861', 'test/14862', 'test/14863', 'test/14865', 'test/14867', 'test/14872', 'test/14873', 'test/14875', 'test/14876', 'test/14877', 'test/14881', 'test/14882', 'test/14885', 'test/14886', 'test/14888', 'test/14890', 'test/14891', 'test/14892', 'test/14899', 'test/14900', 'test/14903', 'test/14904', 'test/14907', 'test/14909', 'test/14911', 'test/14912', 'test/14913', 'test/14918', 'test/14919', 'test/14921', 'test/14922', 'test/14923', 'test/14926']

(2) 查看语料包括的前100个类别:

print(reuters.categories()[:100])

运行结果:

['acq', 'alum', 'barley', 'bop', 'carcass', 'castor-oil', 'cocoa', 'coconut', 'coconut-oil', 'coffee', 'copper', 'copra-cake', 'corn', 'cotton', 'cotton-oil', 'cpi', 'cpu', 'crude', 'dfl', 'dlr', 'dmk', 'earn', 'fuel', 'gas', 'gnp', 'gold', 'grain', 'groundnut', 'groundnut-oil', 'heat', 'hog', 'housing', 'income', 'instal-debt', 'interest', 'ipi', 'iron-steel', 'jet', 'jobs', 'l-cattle', 'lead', 'lei', 'lin-oil', 'livestock', 'lumber', 'meal-feed', 'money-fx', 'money-supply', 'naphtha', 'nat-gas', 'nickel', 'nkr', 'nzdlr', 'oat', 'oilseed', 'orange', 'palladium', 'palm-oil', 'palmkernel', 'pet-chem', 'platinum', 'potato', 'propane', 'rand', 'rape-oil', 'rapeseed', 'reserves', 'retail', 'rice', 'rubber', 'rye', 'ship', 'silver', 'sorghum', 'soy-meal', 'soy-oil', 'soybean', 'strategic-metal', 'sugar', 'sun-meal', 'sun-oil', 'sunseed', 'tea', 'tin', 'trade', 'veg-oil', 'wheat', 'wpi', 'yen', 'zinc']

(3) 查看某个编号的语料下类别尺寸

>>> reuters.categories('training/9865')

运行结果:

['barley', 'corn', 'grain', 'wheat']

(4) 查看某几个联合编号下语料的类别尺寸

>>> reuters.categories(['training/9865','training/9880'])

运行结果:

['barley', 'corn', 'grain', 'money-fx', 'wheat']

(5) 查看哪些编号的文件属于指定的类别

>>> reuters.fileids('barley')

运行结果:

['test/15618', 'test/15649', 'test/15676', 'test/15728', 'test/15871', 'test/15875', 'test/15952', 'test/17767', 'test/17769', 'test/18024', 'test/18263', 'test/18908', 'test/19275', 'test/19668', 'training/10175', 'training/1067', 'training/11208', 'training/11316', 'training/11885', 'training/12428', 'training/13099', 'training/13744', 'training/13795', 'training/13852', 'training/13856', 'training/1652', 'training/1970', 'training/2044', 'training/2171', 'training/2172', 'training/2191', 'training/2217', 'training/2232', 'training/3132', 'training/3324', 'training/395', 'training/4280', 'training/4296', 'training/5', 'training/501', 'training/5467', 'training/5610', 'training/5640', 'training/6626', 'training/7205', 'training/7579', 'training/8213', 'training/8257', 'training/8759', 'training/9865', 'training/9958']

就职演说语料库

(1) 查看语料信息

>>> from nltk.corpus import inaugural
>>> len(inaugural.fileids())
56
>>> inaugural.fileids()

运行结果:

['1789-Washington.txt', '1793-Washington.txt', '1797-Adams.txt', '1801-Jefferson.txt', '1805-Jefferson.txt', '1809-Madison.txt', '1813-Madison.txt', '1817-Monroe.txt', '1821-Monroe.txt', '1825-Adams.txt', '1829-Jackson.txt', '1833-Jackson.txt', '1837-VanBuren.txt', '1841-Harrison.txt', '1845-Polk.txt', '1849-Taylor.txt', '1853-Pierce.txt', '1857-Buchanan.txt', '1861-Lincoln.txt', '1865-Lincoln.txt', '1869-Grant.txt', '1873-Grant.txt', '1877-Hayes.txt', '1881-Garfield.txt', '1885-Cleveland.txt', '1889-Harrison.txt', '1893-Cleveland.txt', '1897-McKinley.txt', '1901-McKinley.txt', '1905-Roosevelt.txt', '1909-Taft.txt', '1913-Wilson.txt', '1917-Wilson.txt', '1921-Harding.txt', '1925-Coolidge.txt', '1929-Hoover.txt', '1933-Roosevelt.txt', '1937-Roosevelt.txt', '1941-Roosevelt.txt', '1945-Roosevelt.txt', '1949-Truman.txt', '1953-Eisenhower.txt', '1957-Eisenhower.txt', '1961-Kennedy.txt', '1965-Johnson.txt', '1969-Nixon.txt', '1973-Nixon.txt', '1977-Carter.txt', '1981-Reagan.txt', '1985-Reagan.txt', '1989-Bush.txt', '1993-Clinton.txt', '1997-Clinton.txt', '2001-Bush.txt', '2005-Bush.txt', '2009-Obama.txt']

(2) 查看演说语料的年份

>>> [fileid[:4] for fileid in inaugural.fileids()]

运行结果:

['1789', '1793', '1797', '1801', '1805', '1809', '1813', '1817', '1821', '1825', '1829', '1833', '1837', '1841', '1845', '1849', '1853', '1857', '1861', '1865', '1869', '1873', '1877', '1881', '1885', '1889', '1893', '1897', '1901', '1905', '1909', '1913', '1917', '1921', '1925', '1929', '1933', '1937', '1941', '1945', '1949', '1953', '1957', '1961', '1965', '1969', '1973', '1977', '1981', '1985', '1989', '1993', '1997', '2001', '2005', '2009']

(3) 条件概率分布

>>> import nltk
>>> cfd=nltk.ConditionalFreqDist((target,fileid[:4]) for fileid in inaugural.fileids() for w in inaugural.words(fileid) for target in ['america','citizen'] if w.lower().startswith(target))
>>> cfd.plot()

运行结果

综合案例:走进大秦帝国

数据采集和预处理

下载孙皓晖先生的《大秦帝国》.zip文件,里面按照语料大小包含5个文件。分别是30852词的p1.txt、70046词的p2.txt、111970词的p3.txt、1182769词的p5.txt、419275词的p10.txt。本书节选了大秦帝国第一部673167字的dqdg.txt。

构建本地语料库

构建自己语料库

>>> from nltk.corpus import PlaintextCorpusReader
>>> corpus_root=r'E:\dict'
>>> wordlists=PlaintextCorpusReader(corpus_root,'.*')
>>> wordlists.fileids()
['dqdg.txt', 'q0.txt', 'q1.txt', 'q10.txt', 'q2.txt', 'q3.txt', 'q5.txt', 'text.txt']
>>> len(wordlists.words('text.txt')) #如果输入错误或者格式不正确,notepad++转换下编码格式即可
152389
语料库信息 ![](https://i.imgur.com/m0Hyyoz.jpg) 构建完成自己语料库之后,利用python NLTK内置函数都可以完成对应操作。换言之,其他语料库的方法,在自己语料库中通用。唯一的问题是,部分方法NLTK是针对英文语料的,中文语料不通用(典型的就是分词)。这个问题的解决方法很多,诸如你通过插件等在NLTK工具包内完成对中文的支持。另外也可以在NLTK中利用StandfordNLP工具包完成对自己语料的操作,这部分知识上节讲解过。 ## 大秦帝国语料操作 打开Python编辑器,导出NLTK,并统计大秦帝国第一部共计多少字。(注:在读取文本的时候,python 3.5 IDLE 执行起来比较卡比较慢,采用pycharm就效率高很多了)
>>> with open(r"E:\dict\dqdg.txt","r+") as f:
    str=f.read()
查看大秦帝国第一部总共有多大的用字量,即不重复词和符合的尺寸:
>>> len(set(str))
4053

>>> len(str)/len(set(str))
166.09104367135456
实验可知用了4053个尺寸的词汇表,平均每个词使用了166次,那么常用词分布如何呢?既然是大秦帝国,那么秦字使用了多少次呢?
>>> str.count("秦")
3538

>>> str.count("大秦")
14

>>> str.count("国")
6536
可以知道,秦用词3538次,大秦用了14次,因为讲的各国之间的事情,国也是高频词6536次。如上所述大秦帝国第一部总词汇表673167,那么整个词汇累积分布如何?
>>> fdist=FreqDist(str)
>>> fdist.plot()

运行结果:

![](https://i.imgur.com/byUr0J2.jpg)

这个图横坐标表示词的序列,纵坐标表示词频。表说明词频大于5000的非常少,说明高频词不多。低频词特别多。后面进一步探究下。

看看整本书的累积分布情况如何?

![](https://i.imgur.com/WsSocrw.jpg)

分析上图我们不难发现,3万以下是低频词大于30%,高频词大于1.4%,中频占68.6%(偏低中频2万左右占29.85%,偏高中频占8.96%)

研究下高频率的1000个词情况?看看都有哪些?

![](https://i.imgur.com/F3iCotU.jpg)

查看1000个高频词分布如何?

![](https://i.imgur.com/FmzWNKb.jpg)

1000个高频的累计分布又如何?

![](https://i.imgur.com/FUFUL68.jpg)

粗略估计下大约占了80%以上。频率最高的前100词的分布如何?

![](https://i.imgur.com/lsymUkF.jpg)

前100个词也就是大约0.02%的词在本书的累积分布情况怎样呢?

>>> fdist=FreqDist(str)
>>> fdist.plot(100,cumulative=True)
![](https://i.imgur.com/FydT69K.jpg)

如图可知,前0.2%词汇占据整本书的50%以上的比例。国、旗、秦、魏、队、阅等跟战争相关词汇使用较多。那么低频词如何呢?有时候低频词也具有其特殊的研究价值。

![](https://i.imgur.com/kNZ9c2l.png)

统计可知大约有4053个词出现一次,占比0.6%.词语内部搭配又是如何?

>>> from collections import Counter
>>> V=Counter(str)
![](https://i.imgur.com/dLFRpkk.png)

查询词频在[0—100]的词有多少?

>>> len([w for w in V.values() if w<100]) 3103="" <="" pre="">
查询词频在[100--1000]的词有多少?
>>> len([w for w in V.values() if w>100 and w<1000]) 819="" <="" pre="">
查询词频在[1000-5000]的词有多少?
>>> len([w for w in V.values() if w>1000 and w<5000]) 113="" <="" pre="">
查询词频在[5000--]的词有多少?
>>> len([w for w in V.values() if w>5000])
14

参考文献

  1. 数据挖掘十大算法:https://wizardforcel.gitbooks.io/dm-algo-top10/content/apriori.html
  2. 中文维基百科:https://zh.wikipedia.org/wiki/%E5%85%88%E9%AA%8C%E7%AE%97%E6%B3%95
  3. GitHub:https://github.com/BaiNingchao/MachineLearning-1
  4. 图书:《机器学习实战》
  5. 图书:《自然语言处理理论与实战》

完整代码下载

源码请进【机器学习和自然语言QQ群:436303759】文件下载:自然语言处理和机器学习技术QQ交流

作者声明

本文版权归作者所有,旨在技术交流使用。未经作者同意禁止转载,转载后需在文章页面明显位置给出原文连接,否则相关责任自行承担。

白宁超 wechat
扫一扫关注微信公众号,机器学习和自然语言处理,订阅号datathinks!