# 前言

这是一本关于自然语言处理的书。所谓“自然语言”，是指人们日常交流使用的语言，如英语，印地语，葡萄牙语等。相对于编程语言和数学符号这样的人工语言，自然语言随着一代人传给另一代人而不断演化，因而很难用明确的规则来刻画。从广义上讲，“自然语言处理”（Natural Language Processing 简称 NLP）包含所有用计算机对自然语言进行的操作。举个极端的例子，它可以是简单的通过计数词出现的频率来比较不同的写作风格。另外一个极端的例子，NLP 包括完全“理解”人所说的话，至少要能达到对人的话语作出有效反应的程度。

基于 NLP 的技术应用日益广泛。例如：手机和手持电脑支持输入法联想提示和手写识别；网络搜索引擎能搜到非结构化文本中的信息；机器翻译能把中文文本翻译成西班牙文；文本分析让我们能够检测推文和博客中的情感。通过提供更自然的人机界面和更复杂的存储信息获取手段，语言处理正在这个多语种的信息社会中扮演更核心的角色。

这本书提供自然语言处理领域非常方便的入门指南。它可以用来自学，也可以作为自然语言处理或计算语言学课程的教科书，或是人工智能、文本挖掘、语料库语言学课程的补充读物。本书的实践性很强，包括几百个实际可用的例子和分级练习。

本书基于 Python 编程语言及其上的一个名为*自然语言工具包*（Natural Language Toolkit ，简称 NLTK）的开源库。NLTK 包含大量的软件、数据和文档，所有这些都可以从`http://nltk.org/`免费下载。NLTK 的发行版本支持 Windows、Macintosh 和 Unix 平台。我们强烈建议你下载 Python 和 NLTk，与我们一起尝试书中的例子和练习。

## 读者

NLP 是科学、经济、社会和文化的一个重要因素。NLP 正在迅速成长，它的很多理论和方法在大量新的语言技术中得到应用。所以对很多行业的人来说掌握 NLP 知识十分重要。在应用领域包括从事人机交互、商业信息分析、web 软件开发的人。在学术界包括从人文计算学、语料库语言学到计算机科学和人工智能领域的人。（学术界的很多人把 NLP 叫称为“计算语言学”。）

本书旨在帮助所有想要学习如何编写程序分析书面语言的人，不管他们以前的编程经验如何：

```py
>>> for line in open("file.txt"):
...     for word in line.split():
...         if word.endswith('ing'):
...             print(word)
```

这段程序演示了 Python 的一些主要特征。首先，使用空格*缩进*代码，从而使`if`后面的代码都在前面一行`for`语句的范围之内；这保证了检查单词是否以`ing`结尾的测试对所有单词都进行。第二，Python 是*面向对象*语言；每一个变量都是包含特定属性和方法的对象。例如，变量`line`的值不仅仅是一个字符串序列。它是一个`string`对象，包含一个用来把字符串分割成词的`split()`方法（或叫操作）。我们在对象名称后面写上一个点再写上方法名称就可以调用对象的一个方法，例如`line.split()`。第三，方法的*参数*写在括号内。例如，上面的例子中的`word.endswith('ing')`具有一个参数`'ing'`表示我们需要找的是`ing`结尾的词而不是别的结尾的词。最后也是最重要的，Python 的可读性如此之强以至于可以相当容易的猜出程序的功能，即使你以前从未写过一行代码。

我们选择 Python 是因为它的学习曲线比较平缓，文法和语义都很清晰，具有良好的处理字符串的功能。作为解释性语言，Python 便于交互式编程。作为面向对象语言，Python 允许数据和方法被方便的封装和重用。作为动态语言，Python 允许属性等到程序运行时才被添加到对象，允许变量自动类型转换，提高开发效率。Python 自带强大的标准库，包括图形编程、数值处理和网络连接等组件。

Python 在世界各地的工业、科研、教育领域应用广泛。它因为提高了软件的生产效率、质量和可维护性而备受称赞。`http://python.org/about/success/`中列举了许多成功使用 Python 的故事。

NLTK 定义了一个使用 Python 进行 NLP 编程的基础工具。它提供重新表示自然语言处理相关数据的基本类，词性标注、文法分析、文本分类等任务的标准接口以及这些任务的标准实现，可以组合起来解决复杂的问题。

NLTK 自带大量文档。作为本书的补充，`http://nltk.org/`网站提供的 API 文档涵盖工具包中每一个模块、类和函数，详细说明了各种参数，还给出了用法示例。

## Python 3 和 NLTK 3

本书的这个版本已更新并支持 Python 3 和 NLTK 3。Python 3 包括一些重大的变化：

*   `print`语句现在是函数，因此需要括号；
*   许多函数现在返回迭代器而不是列表 （以节省内存使用）;
*   整数除法返回一个浮点数
*   所有文本现在都是 Unicode 编码
*   字符串的格式化使用`format`方法

这些变化的更多细节请参见`https://docs.python.org/dev/whatsnew/3.0.html`.。有一个`2to3.py`工具可以将 Python 2 代码转换为 Python 3；关详细信息请参阅`https://docs.python.org/2/library/2to3.html`。

NLTK 同样很多地方都有更改：

*   许多类型使用`fromstring()`方法从字符串初始化
*   许多函数现在返回迭代器而不是列表
*   `ContextFreeGrammar`现在叫做`CFG`，`WeightedGrammar`现在叫做`PCFG`
*   `batch_tokenize()`现在叫做`tokenize_sents()`；对应的标记器, 解析器和分类器都有变化
*   有些实现已删除以支持外部包，或因为不能充分维护

更详细的变更列表请参见`https://github.com/nltk/nltk/wiki/Porting-your-code-to-NLTK-3.0`。

## 软件安装需求

为了充分利用好本书，你应该安装一些免费的软件包。`http://nltk.org/`上有这些软件包当前的下载链接和安装说明。

| Python: | 本书中例子假定你正在使用 Python 3.2 或更高版本。（注，NLTK 3.0 也适用于 Python 2.6 和 2.7）。 |
| --- | --- |
| NLTK: | 这本书中的代码示例使用 NLTK 3.0 版。NLTK 的后续版本将会向后兼容 NLTK 3.0。 |
| NLTK-Data: | 包含本书中分析和处理的语言语料库。 |
| NumPy: | （推荐）这是一个科学计算库，支持多维数组和线性代数，在某些计算概率、标记、聚类和分类任务中用到。 |
| Matplotlib: | （推荐）这是一个用于数据可视化的 2D 绘图库，本书在产生线图和条形图的程序例子中用到。 |
| 斯坦福大学 NLP 工具： | （推荐）NLTK 包括斯坦福大学 NLP 工具的接口，可用于大型语言处理（见`http://nlp.stanford.edu/software/`）。 |
| NetworkX: | （可选）这是一个用于存储和操作由节点和边组成的网络结构的函数库。可视化语义网络还需要安装 *Graphviz* 库。 |
| Prover9: | （可选）这是一个使用一阶等式逻辑定理的自动证明器，用于支持语言处理中的推理。 |

## 自然语言工具包 (NLTK)

NLTK 创建于 2001 年，最初是宾州大学计算机与信息科学系计算语言学课程的一部分。从那以后，在数十名贡献者的帮助下不断发展壮大。如今，它已被几十所大学的课程所采纳，并作为许多研究项目的基础。[VIII.1](http://www.nltk.org/book/ch00.html#tab-modules) 列出了 NLTK 的一些最重要的模块。

表 VIII.1：

语言处理任务与相应 NLTK 模块以及功能描述

| 语言处理任务 | NLTK 模块 | 功能 |
| --- | --- | --- |
| 访问语料库 | `corpus` | 语料库与词典的标准化接口 |
| 字符串处理 | `tokenize, stem` | 分词，分句，提取主干 |
| 搭配的发现 | `collocations` | t-检验，卡方，点互信息 PMI |
| 词性标注 | `tag` | n-gram, backoff, Brill, HMM, TnT |
| 机器学习 | `classify, cluster, tbl` | 决策树，最大熵，贝叶斯，EM，k-means |
| 分块 | `chunk` | 正则表达式，n-gram，命名实体 |
| 解析 | `parse, ccg` | 图表，基于特征，一致性，概率，依赖 |
| 语义解释 | `sem, inference` | λ演算，一阶逻辑，模型检验 |
| 指标评测 | `metrics` | 精度，召回率，协议系数 |
| 概率和估计 | `probability` | 频率分布，平滑概率分布 |
| 应用 | `app, chat` | 图形化的语料库检索工具，分析器，WordNet 查看器，聊天机器人 |
| 语言学领域的工作 | `toolbox` | 处理 SIL 工具箱格式的数据 |

NLTK 设计中的四个主要目标：

| 简单： | 提供一个直观的框架和大量构建模块，使用户获取 NLP 知识而不必陷入像标注语言数据那样繁琐的事务中 |
| --- | --- |
| 一致： | 提供一个具有一致的接口和数据结构的，并且方法名称容易被猜到的统一的框架 |
| 可扩展： | 提供一种结构，新的软件模块包括同一个任务中的不同的实现和相互冲突的方法都可以方便添加进来 |
| 模块化： | 提供的组件可以独立使用而无需理解工具包的其他部分 |

对比上述目标，我们有意回避了工具包三个非需求行的但可能有用的特征。首先，虽然工具包提供了广泛的工具，但它不是面面俱全的；它是一个工具包而不是一个系统，它将会随着 NLP 领域一起演化。第二，虽然这个工具包的效率足以支持实际的任务，但它运行时的性能还没有高度优化；这种优化往往涉及更复杂的算法或使用 C 或 C++ 等较低一级的编程语言来实现。这将影响工具包的可读性且更难以安装。第三，我们试图避开巧妙的编程技巧，因为我们相信清楚直白的实现比巧妙却可读性差的方法好。

## 教师请看

自然语言处理一般是在高年级本科生或研究生层次开设的为期一个学期的课程。很多教师都发现，在如此短的时间里涵盖理论和实践两个方面是十分困难的。有些课程注重理论而排挤实践练习，剥夺了学生编写程序自动处理语言带来的挑战和兴奋感。另一些课程仅仅教授语言学编程而不包含任何重要的 NLP 内容。最初开发 NLTK 就是为了解决这个问题，使在一个学期里同时教授大量理论和实践成为可能，无论学生事先有没有编程经验。

算法和数据结构在所有 NLP 教学大纲中都十分重要。它们本身可能非常枯燥，而 NLTK 提供的交互式图形用户界面能一步一步看到算法过程，使它们变得鲜活。大多数 NLTK 组件都有一个无需用户输入任何数据就能执行有趣的任务的示范性例子。学习本书的一个有效的方法就是交互式重现书中的例子，把它们输入到 Python 会话控制台，观察它们做了些什么，修改它们去探索试验或理论问题。

本书包含了数百个练习，可作为学生作业的基础。最简单的练习涉及用指定的方式修改已有的程序片段来回答一个具体的问题。另一个极端，NLTK 为研究生水平的研究项目提供了一个灵活的框架，包括所有的基本数据结构和算法的标准实现，几十个广泛使用的数据集（语料库）的接口，以及一个灵活可扩展的体系结构。NLTK 网站上还有其他资源支持教学中使用 NLTK。

我们相信本书是唯一为学生提供在学习编程的环境中学习 NLP 的综合性框架。各个章节和练习通过 NLTK 紧密耦合，并将各章材料分割开，为学生（即使是那些以前没有编程经验的学生）提供一个实用的 NLP 的入门指南。学完这些材料后，学生将准备好尝试一本更加深层次的教科书，例如《语音和语言处理》，作者是 Jurafsky 和 Martin (Prentice Hall 出版社，2008 年)。

本书介绍编程概念的顺序与众不同，以一个重要的数据类型字符串列表开始，然后介绍重要的控制结构如推导和条件式等。这些概念允许我们在一开始就做一些有用的语言处理。有了这样做的冲动，我们回过头来系统的介绍一些基础概念，如字符串，循环，文件等。这样的方法同更传统的方法达到了同样的效果而不必要求读者自己已经对编程感兴趣。

[IX.1](http://www.nltk.org/book/ch00.html#tab-course-plans) 列出了两个课程计划表。第一个适用于文科，第二个适用于理工科。其他的课程计划应该涵盖前 5 章，然后把剩余的时间投入单独的领域，例如：文本分类（第 6、7 章）、文法（第 8、9 章）、语义（第 10 章）或者语言数据管理（第 11 章）。

表 IX.1：

课程计划建议；每一章近似的课时数

| 章节 | 文科 | 理工科 |
| --- | --- | --- |
| 第 1 章 语言处理与 Python | 2-4 | 2 |
| 第 2 章 获得文本语料和词汇资源 | 2-4 | 2 |
| 第 3 章 处理原始文本 | 2-4 | 2 |
| 第 4 章 编写结构化程序 | 2-4 | 1-2 |
| 第 5 章 分类和标注单词 | 2-4 | 2-4 |
| 第 6 章 学习本文分类 | 0-2 | 2-4 |
| 第 7 章 从文本提取信息 | 2 | 2-4 |
| 第 8 章 分析句子结构 | 2-4 | 2-4 |
| 第 9 章 构建基于特征的文法 | 2-4 | 1-4 |
| 第 10 章 分析句子的含义 | 1-2 | 1-4 |
| 第 11 章 语言学数据管理 | 1-2 | 1-4 |
| 总计 | 18-36 | 18-36 |

## 本书使用的约定

本书使用以下印刷约定：

**粗体** -- 表示新的术语。

*斜体* -- 用在段落中表示语言学例子、文本的名称和 URL，文件名和后缀名也用斜体。

`等宽字体` -- 用来表示程序清单，用在段落中表示变量、函数名、语句或关键字等程序元素；也用来表示程序名。

`等宽粗体` -- 表示应该由用户输入的命令或其他文本。

`等宽斜体` -- 表示应由用户提供的值或上下文决定的值来代替文本中的值；也在程序代码例子中表示元变量。

注

此图标表示提示、建议或一般性注意事项。

警告！

此图标表示警告或重要提醒。

## 使用例子代码

本书是为了帮你完成你的工作的。。一般情况下，你都可以在你的程序或文档中使用本书中的代码。不需要得到我们获得允许，除非你要大量的复制代码。例如，编写的程序用到书中几段代码不需要许可。销售和分发 O'Reilly 书籍中包含的例子的 CD-ROM 需要获得许可。援引本书和书中的例子来回答问题不需要许可。大量的将本书中的例子纳入你的产品文档将需要获得许可。

我们希望但不是一定要求被参考文献引用。一个引用通常包括标题，作者，出版者和 ISBN。例如：Python 自然语言处理，Steven Bird，Ewan Klein 和 Edward Loper。O'Reilly Media, 978-0-596-51649-9\. 如果你觉得你使用本书的例子代码超出了上面列举的一般用途或许可，随时通过 *permissions@oreilly.com* 联系我们。

## 致谢

作者感激为本书早期手稿提供反馈意见的人，他们是：Doug Arnold, Michaela Atterer, Greg Aumann, Kenneth Beesley, Steven Bethard, Ondrej Bojar, Chris Cieri, Robin Cooper, Grev Corbett, James Curran, Dan Garrette, Jean Mark Gawron, Doug Hellmann, Nitin Indurkhya, Mark Liberman, Peter Ljunglöf, Stefan Müller, Robin Munn, Joel Nothman, Adam Przepiorkowski, Brandon Rhodes, Stuart Robinson, Jussi Salmela, Kyle Schlansker, Rob Speer 和 Richard Sproat。感谢许许多多的学生和同事，他们关于课堂材料的意见演化成本书的这些章节，其中包括巴西，印度和美国的 NLP 与语言学暑期学校的参加者。没有`nltk-dev`开发社区的成员们的努力这本书也不会存在，他们为建设和壮大 NLTK 无私奉献他们的时间和专业知识，他们的名字都记录在 NLTK 网站上。

非常感谢美国国家科学基金会、语言数据联盟、Edward Clarence Dyason 奖学金、宾州大学、爱丁堡大学和墨尔本大学对我们在本书相关的工作上的支持。

感谢 Julie Steele、Abby Fox、Loranah Dimant 以及其他 O'Reilly 团队成员，他们组织大量 NLP 和 Python 社区成员全面审阅我们的手稿，很高兴的为满足我们的需要定制 O'Reilly 的生成工具。感谢他们一丝不苟的审稿工作。

在准备 Python 3 修订版的过程中，感谢 Michael Korobov 领导将 NLTK 移植到 Python 3，以及 Antoine Trux 对第一版细致的反馈意见。

最后，我们对我们的合作伙伴欠了巨额的感情债，他们是 Mimo 和 Jee。我们希望我们的孩子 —— Andrew, Alison、Kirsten、Leonie 和 Maaike —— 能从这些页面中感受到我们对语言和计算的热情。

## 关于作者

**Steven Bird** 是在墨尔本大学计算机科学与软件工程系副教授和美国宾夕法尼亚大学的语言数据联盟的高级研究助理。他于 1990 年在爱丁堡大学完成计算音韵学博士学位，由 Ewan Klein 指导。后来到喀麦隆开展夏季语言学研究所主持下的 Grassfields 班图语语言实地调查。最近，他作为语言数据联盟副主任花了几年时间领导研发队伍，创建已标注文本的大型数据库的模型和工具。在墨尔本大学，他建立了一个语言技术研究组，并在各级本科计算机科学课程任教。2009 年，史蒂芬成为计算语言学学会主席。

**Ewan Klein**是英国爱丁堡大学信息学院语言技术教授。于 1978 年在剑桥大学完成形式语义学博士学位。在苏塞克斯和纽卡斯尔大学工作多年后，参加了在爱丁堡的教学岗位。他于 1993 年参与了爱丁堡语言科技集团的建立，并一直与之密切联系。从 2000 到 2002，他离开大学作为圣克拉拉的埃迪法公司的总部在爱丁堡的自然语言的研究小组的研发经理，负责处理口语对话。Ewan 是计算语言学协会欧洲分会（European Chapter of the Association for Computational Linguistics）前任主席，并且是人类语言技术（ELSNET）欧洲卓越网络的创始成员和协调员。

**Edward Loper** 最近完成了宾夕法尼亚大学自然语言处理的机器学习博士学位。Edward 是 Steven 在 2000 年秋季计算语言学研究生课程的学生，也是教师助手和 NLTK 开发的成员。除了 NLTK，他帮助开发了用于文档化和测试 Python 软件的两个包：`epydoc`和`doctest`。

## 版税

出售这本书的版税将被用来支持自然语言工具包的发展。

![Images/authors.png](Images/d87676460c87d0516fb382b929c07302.jpg)

图 XIV.1：Edward Loper, Ewan Klein 和 Steven Bird, 斯坦福大学, 2007 年 7 月 

## 关于本文档...

针对 NLTK 3.0 作出更新。本章来自于《Python 自然语言处理》，[Steven Bird](http://estive.net/), [Ewan Klein](http://homepages.inf.ed.ac.uk/ewan/) 和 [Edward Loper](http://ed.loper.org/)，Copyright © 2014 作者所有。本章依据 *Creative Commons Attribution-Noncommercial-No Derivative Works 3.0 United States License* [[http://creativecommons.org/licenses/by-nc-nd/3.0/us/](http://creativecommons.org/licenses/by-nc-nd/3.0/us/)] 条款，与[*自然语言工具包*](http://nltk.org/) 3.0 版一起发行。

本文档构建于 2015 年 7 月 1 日 星期三 12:30:05 AEST