提交 36c5a124 编写于 作者: W wizardforcel

2020-11-21 11:09:25

上级 f0a35a04
......@@ -6,7 +6,7 @@
这本书提供自然语言处理领域非常方便的入门指南。它可以用来自学,也可以作为自然语言处理或计算语言学课程的教科书,或是人工智能、文本挖掘、语料库语言学课程的补充读物。本书的实践性很强,包括几百个实际可用的例子和分级练习。
本书基于 Python 编程语言及其上的一个名为 _ 自然语言工具包 _(Natural Language Toolkit ,简称 NLTK)的开源库。NLTK 包含大量的软件、数据和文档,所有这些都可以从`http://nltk.org/` 免费下载。NLTK 的发行版本支持 Windows、Macintosh 和 Unix 平台。我们强烈建议你下载 Python 和 NLTk,与我们一起尝试书中的例子和练习。
本书基于 Python 编程语言及其上的一个名为*自然语言工具包*(Natural Language Toolkit ,简称 NLTK)的开源库。NLTK 包含大量的软件、数据和文档,所有这些都可以从`http://nltk.org/` 免费下载。NLTK 的发行版本支持 Windows、Macintosh 和 Unix 平台。我们强烈建议你下载 Python 和 NLTk,与我们一起尝试书中的例子和练习。
## 读者
......@@ -21,7 +21,7 @@ NLP 是科学、经济、社会和文化的一个重要因素。NLP 正在迅速
... print(word)
```
这段程序演示了 Python 的一些主要特征。首先,使用空格 _ 缩进 _ 代码,从而使`if`后面的代码都在前面一行`for`语句的范围之内;这保证了检查单词是否以`ing` 结尾的测试对所有单词都进行。第二,Python 是 _ 面向对象 _ 语言;每一个变量都是包含特定属性和方法的对象。例如,变量`line` 的值不仅仅是一个字符串序列。它是一个 string 对象,包含一个用来把字符串分割成词的`split()` 方法(或叫操作)。我们在对象名称后面写上一个点再写上方法名称就可以调用对象的一个方法,例如`line.split()`。第三,方法的 _ 参数 _ 写在括号内。例如,上面的例子中的`word.endswith('ing')`具有一个参数`'ing'` 表示我们需要找的是 ing 结尾的词而不是别的结尾的词。最后也是最重要的,Python 的可读性如此之强以至于可以相当容易的猜出程序的功能,即使你以前从未写过一行代码。
这段程序演示了 Python 的一些主要特征。首先,使用空格*缩进*代码,从而使`if`后面的代码都在前面一行`for`语句的范围之内;这保证了检查单词是否以`ing` 结尾的测试对所有单词都进行。第二,Python 是*面向对象*语言;每一个变量都是包含特定属性和方法的对象。例如,变量`line` 的值不仅仅是一个字符串序列。它是一个 string 对象,包含一个用来把字符串分割成词的`split()` 方法(或叫操作)。我们在对象名称后面写上一个点再写上方法名称就可以调用对象的一个方法,例如`line.split()`。第三,方法的*参数*写在括号内。例如,上面的例子中的`word.endswith('ing')`具有一个参数`'ing'` 表示我们需要找的是 ing 结尾的词而不是别的结尾的词。最后也是最重要的,Python 的可读性如此之强以至于可以相当容易的猜出程序的功能,即使你以前从未写过一行代码。
我们选择 Python 是因为它的学习曲线比较平缓,文法和语义都很清晰,具有良好的处理字符串的功能。作为解释性语言,Python 便于交互式编程。作为面向对象语言,Python 允许数据和方法被方便的封装和重用。作为动态语言,Python 允许属性等到程序运行时才被添加到对象,允许变量自动类型转换,提高开发效率。Python 自带强大的标准库,包括图形编程、数值处理和网络连接等组件。
......@@ -137,9 +137,9 @@ NLTK 设计中的四个主要目标:
本书使用以下印刷约定:
粗体 -- 表示新的术语。
**粗体** -- 表示新的术语。
_ 斜体 _ -- 用在段落中表示语言学例子、文本的名称和 URL,文件名和后缀名也用斜体。
*斜体* -- 用在段落中表示语言学例子、文本的名称和 URL,文件名和后缀名也用斜体。
`等宽字体` -- 用来表示程序清单,用在段落中表示变量、函数名、语句或关键字等程序元素;也用来表示程序名。
......@@ -191,6 +191,6 @@ _ 斜体 _ -- 用在段落中表示语言学例子、文本的名称和 URL,
关于本文档...
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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
\ No newline at end of file
......@@ -15,7 +15,7 @@
## 1.1 Python 入门
Python 对用户友好的一个方式是你可以交互式地直接打字给解释器 —— 将要运行你的 Python 代码的程序。你可以通过一个简单的叫做交互式开发环境(Interactive DeveLopment Environment,简称 IDLE)的图形接口来访问 Python 解释器。在 Mac 上,你可以在 _ 应用程序 _→_MacPython_ 中找到;在 Windows 中,你可以在 _ 程序 _→_Python_ 中找到。在 Unix 下,你可以在 shell 输入`idle`来运行 Python(如果没有安装,尝试输入`python`)。解释器将会输出关于你的 Python 的版本简介,请检查你运行的是否是 Python 3.2 更高的版本(这里是 3.4.2):
Python 对用户友好的一个方式是你可以交互式地直接打字给解释器 —— 将要运行你的 Python 代码的程序。你可以通过一个简单的叫做交互式开发环境(Interactive DeveLopment Environment,简称 IDLE)的图形接口来访问 Python 解释器。在 Mac 上,你可以在*应用程序 → MacPython* 中找到;在 Windows 中,你可以在*程序 → Python* 中找到。在 Unix 下,你可以在 shell 输入`idle`来运行 Python(如果没有安装,尝试输入`python`)。解释器将会输出关于你的 Python 的版本简介,请检查你运行的是否是 Python 3.2 更高的版本(这里是 3.4.2):
```py
Python 3.4.2 (default, Oct 15 2014, 22:01:37)
......@@ -160,7 +160,7 @@ a_pretty is_pretty am_glad be_glad a_lucky
**轮到你来:** 挑选另一对词,使用`similar()``common_contexts()` 函数比较它们在两个不同文本中的用法。
自动检测出现在文本中的特定的词,并显示同样上下文中出现的一些词,这只是一个方面。我们也可以判断词在文本中的 _ 位置 _:从文本开头算起在它前面有多少词。这个位置信息可以用离散图表示。每一个竖线代表一个单词,每一行代表整个文本。在[1.2](http://www.nltk.org/book/ch01.html#fig-inaugural) 中,我们看到在过去 220 年中的一些显著的词语用法模式(在一个由就职演说语料首尾相连的人为组合的文本中)。可以用下面的方法画出这幅图。你也许会想尝试更多的词(如,liberty,constitution)和不同的文本。你能在看到这幅图之前预测一个词的分布吗?跟以前一样,请保证引号、逗号、中括号及小括号的使用完全正确。
自动检测出现在文本中的特定的词,并显示同样上下文中出现的一些词,这只是一个方面。我们也可以判断词在文本中的*位置*:从文本开头算起在它前面有多少词。这个位置信息可以用离散图表示。每一个竖线代表一个单词,每一行代表整个文本。在[1.2](http://www.nltk.org/book/ch01.html#fig-inaugural) 中,我们看到在过去 220 年中的一些显著的词语用法模式(在一个由就职演说语料首尾相连的人为组合的文本中)。可以用下面的方法画出这幅图。你也许会想尝试更多的词(如,liberty,constitution)和不同的文本。你能在看到这幅图之前预测一个词的分布吗?跟以前一样,请保证引号、逗号、中括号及小括号的使用完全正确。
```py
>>> text4.dispersion_plot(["citizens", "democracy", "freedom", "duties", "America"])
......@@ -208,7 +208,7 @@ Note
>>>
```
《创世纪》有 44764 个词和标点符号或者叫“词符”。词符 表示一个我们想要整体对待的字符序列 —— 例如`hairy``his``:)`。当我们计数文本如 to be or not to be 这个短语中词符的个数时,我们计数这些序列出现的次数。因此,我们的例句中出现了 to 和 be 各两次,or 和 not 各一次。然而在例句中只有 4 个不同的词。《创世纪》中有多少不同的词?要用 Python 来回答这个问题,我们处理问题的方法将稍有改变。一个文本词汇表只是它用到的词符的 _ 集合 _,因为在集合中所有重复的元素都只算一个。Python 中我们可以使用命令:`set(text3)` 获得`text3` 的词汇表。当你这样做时,屏幕上的很多词会掠过。现在尝试以下操作:
《创世纪》有 44764 个词和标点符号或者叫“词符”。词符 表示一个我们想要整体对待的字符序列 —— 例如`hairy``his``:)`。当我们计数文本如 to be or not to be 这个短语中词符的个数时,我们计数这些序列出现的次数。因此,我们的例句中出现了 to 和 be 各两次,or 和 not 各一次。然而在例句中只有 4 个不同的词。《创世纪》中有多少不同的词?要用 Python 来回答这个问题,我们处理问题的方法将稍有改变。一个文本词汇表只是它用到的词符的*集合*,因为在集合中所有重复的元素都只算一个。Python 中我们可以使用命令:`set(text3)` 获得`text3` 的词汇表。当你这样做时,屏幕上的很多词会掠过。现在尝试以下操作:
```py
>>> sorted(set(text3))
......@@ -283,7 +283,7 @@ Note
表 1.1:
_Brown 语料库 _ 中各种文体的词汇多样性
*Brown 语料库*中各种文体的词汇多样性
```py
>>> sent1 = ['Call', 'me', 'Ishmael', '.']
......@@ -615,7 +615,7 @@ what output do you expect here?
## 3.2 细粒度的选择词
接下来,让我们看看文本中的 _ 长 _ 词,也许它们有更多的特征和信息量。为此我们采用集合论的一些符号。我们想要找出文本词汇表长度中超过 15 个字符的词。我们定义这个性质为 P,则 P(w) 为真当且仅当词 w 的长度大余 15 个字符。现在我们可以用[(1a)](http://www.nltk.org/book/ch01.html#ex-set-comprehension-math) 中的数学集合符号表示我们感兴趣的词汇。它的含义是:此集合中所有 w 都满足 w 是集合 V V(词汇表)的一个元素且 w 有性质 P。
接下来,让我们看看文本中的*长*词,也许它们有更多的特征和信息量。为此我们采用集合论的一些符号。我们想要找出文本词汇表长度中超过 15 个字符的词。我们定义这个性质为 P,则 P(w) 为真当且仅当词 w 的长度大余 15 个字符。现在我们可以用[(1a)](http://www.nltk.org/book/ch01.html#ex-set-comprehension-math) 中的数学集合符号表示我们感兴趣的词汇。它的含义是:此集合中所有 w 都满足 w 是集合 V V(词汇表)的一个元素且 w 有性质 P。
```py
>>> V = set(text1)
......@@ -636,7 +636,7 @@ what output do you expect here?
**轮到你来:** 在 Python 解释器中尝试上面的表达式,改变文本和长度条件做一些实验。如果改变变量名,你的结果会产生什么变化吗,如使用`[word for word in vocab if ...]`
让我们回到寻找文本特征词汇的任务上来。请注意,`text4` 中的长词反映国家主题 — constitutionally, transcontinental — 而`text5` 中的长词反映的不是真正的内容 boooooooooooglyyyyyy 和 yuuuuuuuuuuuummmmmmmmmmmm。我们是否已经成功的自动提取出文本的特征词汇呢?好的,这些很长的词通常是 hapaxes(即唯一的),也许找出 _ 频繁出现的 _ 长词会更好。这样看起来更有前途,因为这样忽略了短高频词(如 the)和长低频词(如 antiphilosophists)。以下是聊天语料库中所有长度超过 7 个字符,且出现次数超过 7 次的词:
让我们回到寻找文本特征词汇的任务上来。请注意,`text4` 中的长词反映国家主题 — constitutionally, transcontinental — 而`text5` 中的长词反映的不是真正的内容 boooooooooooglyyyyyy 和 yuuuuuuuuuuuummmmmmmmmmmm。我们是否已经成功的自动提取出文本的特征词汇呢?好的,这些很长的词通常是 hapaxes(即唯一的),也许找出*频繁出现的*长词会更好。这样看起来更有前途,因为这样忽略了短高频词(如 the)和长低频词(如 antiphilosophists)。以下是聊天语料库中所有长度超过 7 个字符,且出现次数超过 7 次的词:
```py
>>> fdist5 = FreqDist(text5)
......@@ -955,7 +955,7 @@ conscientious conscientiously deceitful deceive ...
关于本文档...
针对 NLTK 3.0 进行更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 进行更新。本章来自于 _Natural Language Processing with 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
......
......@@ -379,7 +379,7 @@ True
## 3.7 量词范围歧义
当我们给一个句子的形式化表示 _ 两 _ 个量词时,会发生什么?
当我们给一个句子的形式化表示*两*个量词时,会发生什么?
```py
>>> v2 = """
......@@ -443,7 +443,7 @@ True
False
```
我们也可以使用模型建立器作为定理证明器的辅助。假设我们正试图证明`S``g`,即`g`是假设`S = [s1, s2, ..., sn]`的逻辑派生。我们可以同样的输入提供给 Mace4,模型建立器将尝试找出一个反例,就是要表明`g`_ 不 _ 遵循从`S`。因此,给定此输入,Mace4 将尝试为假设`S`连同`g`的否定找到一个模型,即列表`S' = [s1, s2, ..., sn, -g]`。如果`g``S`不能证明出来,那么 Mace4 会返回一个反例,比 Prover9 更快的得出结论:无法找到所需的证明。相反,如果`g``S`是可以证明出来,Mace4 可能要花很长时间不能成功地找到一个反例模型,最终会放弃。
我们也可以使用模型建立器作为定理证明器的辅助。假设我们正试图证明`S``g`,即`g`是假设`S = [s1, s2, ..., sn]`的逻辑派生。我们可以同样的输入提供给 Mace4,模型建立器将尝试找出一个反例,就是要表明`g`*不*遵循从`S`。因此,给定此输入,Mace4 将尝试为假设`S`连同`g`的否定找到一个模型,即列表`S' = [s1, s2, ..., sn, -g]`。如果`g``S`不能证明出来,那么 Mace4 会返回一个反例,比 Prover9 更快的得出结论:无法找到所需的证明。相反,如果`g``S`是可以证明出来,Mace4 可能要花很长时间不能成功地找到一个反例模型,最终会放弃。
让我们思考一个具体的方案。我们的假设是列表[There is a woman that every man loves, Adam is a man, Eve is a woman]。我们的结论是 Adam loves Eve。Mace4 能找到使假设为真而结论为假的模型吗?在下面的代码中,我们使用`MaceCommand()`检查已建立的模型。
......@@ -816,7 +816,7 @@ d1: ['s0-r1', 's1-r0'] : ([z6,z10],[boy(z6), (([x],[dog(x)]) ->
([],[chases(x,z6)])), (z10 = z6), runs(z10)])
```
当我们检查段落线`d0``d1`时,我们看到读法`s0-r0`,其中 every dog 超出了`a boy`的范围,被认为是不可接受的,因为第二句的代词不能得到解释。相比之下,段落线`d1`中的代词(重写为`z24`_ 通过 _ 等式`(z24 = z20)`绑定。
当我们检查段落线`d0``d1`时,我们看到读法`s0-r0`,其中 every dog 超出了`a boy`的范围,被认为是不可接受的,因为第二句的代词不能得到解释。相比之下,段落线`d1`中的代词(重写为`z24`*通过*等式`(z24 = z20)`绑定。
不可接受的读法可以通过传递参数`filter=True`过滤掉。
......@@ -994,6 +994,6 @@ d1: ['s0-r1', 's1-r0'] : ([z12,z15],[boy(z12), (([x],[dog(x)]) ->
关于本文档...
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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
\ No newline at end of file
......@@ -84,7 +84,7 @@ TIMIT 的第四个特点是语料库的层次结构。每个句子 4 个文件
另一种语料库创建方案是典型的实验研究,其中一些精心设计的材料被从一定范围的人类受试者中收集,然后进行分析来评估一个假设或开发一种技术。此类数据库在实验室或公司内被共享和重用已很常见,经常被更广泛的发布。这种类型的语料库是“共同任务”的科研管理方法的基础,这在过去的二十年已成为政府资助的语言技术研究项目。在前面的章节中,我们已经遇到很多这样的语料库;我们将看到如何编写 Python 程序实践这些语料库发布前必要的一些任务。
最后,还有努力为一个特定的语言收集“参考语料”,如 _ 美国国家语料库 _(ANC)和 _ 英国国家语料库 _(BNC)。这里的目标已经成为产生各种形式、风格和语言的使用的一个全面的记录。除了规模庞大的挑战,还严重依赖自动标注工具和后期编辑共同修复错误。然而,我们可以编写程序来查找和修复错误,还可以分析语料库是否平衡。
最后,还有努力为一个特定的语言收集“参考语料”,如*美国国家语料库*(ANC)和*英国国家语料库*(BNC)。这里的目标已经成为产生各种形式、风格和语言的使用的一个全面的记录。除了规模庞大的挑战,还严重依赖自动标注工具和后期编辑共同修复错误。然而,我们可以编写程序来查找和修复错误,还可以分析语料库是否平衡。
## 2.2 质量控制
......@@ -174,7 +174,7 @@ Kappa 系数 K 测量两个人判断类别和修正预期的期望一致性的
```
这个简单的程序只是冰山一角。我们可以开发复杂的工具来检查字处理器文件的一致性,并报告错误,使字典的维护者可以 _ 使用原来的文字处理器 _ 纠正的原始文件。
这个简单的程序只是冰山一角。我们可以开发复杂的工具来检查字处理器文件的一致性,并报告错误,使字典的维护者可以*使用原来的文字处理器*纠正的原始文件。
只要我们知道数据的正确格式,就可以编写其他程序将数据转换成不同格式。[3.1](./ch11.html#code-html2csv)中的程序使用`nltk.clean_html()`剥离 HTML 标记,提取词和它们的发音,以“逗号分隔值”(CSV)格式生成输出。
......@@ -204,7 +204,7 @@ f_out.write(bytes(s, 'UTF-8'))
电子表格通常用于获取词表或范式。例如,一个比较词表可以用电子表格创建,用一排表示每个同源组,每种语言一列(见`nltk.corpus.swadesh``www.rosettaproject.org`)。大多数电子表格软件可以将数据导出为 CSV 格式。正如我们将在下面看到的,使用`csv`模块 Python 程序可以很容易的访问它们。
有时词典存储在一个完全成熟的关系数据库。经过适当的标准化,这些数据库可以确保数据的有效性。例如,我们可以要求所有词性都来自指定的词汇,通过声明词性字段为 _ 枚举类型 _ 或用一个外键引用一个单独的词性表。然而,关系模型需要提前定义好的数据(模式)结构,这与高度探索性的构造语言数据的主导方法相违背。被认为是强制性的和独特的字段往往需要是可选的、可重复。只有当数据类型提前全都知道时关系数据库才是适用的,如果不是,或者几乎所有的属性都是可选的或重复的,关系的做法就行不通了。
有时词典存储在一个完全成熟的关系数据库。经过适当的标准化,这些数据库可以确保数据的有效性。例如,我们可以要求所有词性都来自指定的词汇,通过声明词性字段为*枚举类型*或用一个外键引用一个单独的词性表。然而,关系模型需要提前定义好的数据(模式)结构,这与高度探索性的构造语言数据的主导方法相违背。被认为是强制性的和独特的字段往往需要是可选的、可重复。只有当数据类型提前全都知道时关系数据库才是适用的,如果不是,或者几乎所有的属性都是可选的或重复的,关系的做法就行不通了。
然而,当我们的目标只是简单的从数据库中提取内容时,完全可以将表格(或 SQL 查询结果)转换成 CSV 格式,并加载到我们的程序中。我们的程序可能会执行不太容易用 SQL 表示的语言学目的的查询,如 _select all words that appear in example sentences for which no dictionary entry is provided_。对于这个任务,我们需要从记录中提取足够的信息,使它连同词条和例句能被唯一的识别。让我们假设现在这个信息是在一个 CSV 文件`dict.csv`中:
......@@ -734,7 +734,7 @@ OLAC 元数据是描述语言资源的标准。通过限制某些元数据元素
本章的附加材料发布在`http://nltk.org/`,包括网络上免费提供的资源的链接。
语言学语料库的首要来源是 _ 语言数据联盟 _ 和 _ 欧洲语言资源局 _,两者都有广泛的在线目录。本书中提到的主要语料库的细节也有介绍:美国国家语料库[(Reppen, Ide, & Suderman, 2005)](./bibliography.html#reppen2005anc)、英国国家语料库[({BNC}, 1999)](./bibliography.html#bnc1999),Thesaurus Linguae Graecae[({TLG}, 1999)](./bibliography.html#tlg1999)、儿童语言数据交换系统 (CHILDES) [(MacWhinney, 1995)](./bibliography.html#macwhinney1995childes)和 TIMIT[(S., Lamel, & William, 1986)](./bibliography.html#garofolo1986timit)
语言学语料库的首要来源是*语言数据联盟**欧洲语言资源局*,两者都有广泛的在线目录。本书中提到的主要语料库的细节也有介绍:美国国家语料库[(Reppen, Ide, & Suderman, 2005)](./bibliography.html#reppen2005anc)、英国国家语料库[({BNC}, 1999)](./bibliography.html#bnc1999),Thesaurus Linguae Graecae[({TLG}, 1999)](./bibliography.html#tlg1999)、儿童语言数据交换系统 (CHILDES) [(MacWhinney, 1995)](./bibliography.html#macwhinney1995childes)和 TIMIT[(S., Lamel, & William, 1986)](./bibliography.html#garofolo1986timit)
计算语言学协会定期组织研讨会发布论文集,它的两个特别兴趣组:SIGWAC 和 SIGANN;前者推动使用网络作为语料,发起去除 HTML 标记的 CLEANEVAL 任务;后者鼓励对语言注解的互操作性的努力。
......@@ -742,7 +742,7 @@ OLAC 元数据是描述语言资源的标准。通过限制某些元数据元素
有很多优秀的 XML 资源(如`http://zvon.org/`)和编写 Python 程序处理 XML 的资源。许多编辑器都有 XML 模式。XML 格式的词汇信息包括 OLIF`http://www.olif.net/`和 LIFT`http://code.google.com/p/lift-standard/`
对于语言标注软件的调查,见`http://www.ldc.upenn.edu/annotation/` _ 语言标注页 _。对峙注解最初的提出是[(Thompson & McKelvie, 1997)](./bibliography.html#thompson1997standoff)。语言标注的一个抽象的数据模型称为“标注图”在[(Bird & Liberman, 2001)](./bibliography.html#bird2001annotation)提出。语言描述的一个通用本体(GOLD)记录在`http://www.linguistics-ontology.org/`中。
对于语言标注软件的调查,见`http://www.ldc.upenn.edu/annotation/`*语言标注页*。对峙注解最初的提出是[(Thompson & McKelvie, 1997)](./bibliography.html#thompson1997standoff)。语言标注的一个抽象的数据模型称为“标注图”在[(Bird & Liberman, 2001)](./bibliography.html#bird2001annotation)提出。语言描述的一个通用本体(GOLD)记录在`http://www.linguistics-ontology.org/`中。
有关规划和建设语料库的指导,请参阅[(Meyer, 2002)](./bibliography.html#meyer2002)[(Farghaly, 2003)](./bibliography.html#farghaly2003) 。关于标注者之间一致性得分的方法的更多细节,见[(Artstein & Poesio, 2008)](./bibliography.html#artsteinpoesio2008)[(Pevzner & Hearst, 2002)](./bibliography.html#pevzner2002windowdiff)
......@@ -756,7 +756,7 @@ Rotokas 数据由 Stuart Robinson 提供,勉方言数据由 Greg Aumann 提供
2. ◑ 编写一个函数,从一个词汇条目删除指定的字段。(我们可以在把数据给别人之前用它做些清洁,如删除包含无关或不确定的内容的字段。)
3. ◑ 写一个程序,扫描一个 HTML 字典文件,找出具有非法词性字段的条目,并报告每个条目的 _ 核心词 _
3. ◑ 写一个程序,扫描一个 HTML 字典文件,找出具有非法词性字段的条目,并报告每个条目的*核心词*
4. ◑ 写一个程序,找出所有出现少于 10 次的词性(`ps`字段)。或许有打字错误?
......
......@@ -42,7 +42,7 @@ g. There are two ways to do this, AFAIK :smile: (internet discussion archive)
在上一节中描述的自然语言处理的两种方法的对比与在西方哲学的启蒙时期出现的关于理性主义与经验主义和现实主义与理想主义的早期形而上学的辩论有关。这些辩论出现在反对一切知识的来源被认为是神的启示的地方的正统思想的背景下。在十七和十八世纪期间,哲学家认为人类理性或感官经验优先了启示。笛卡尔和莱布尼兹以及其他人采取了理性的立场,声称所有的真理来源于人类思想,从出生起在我们的脑海中就植入的“天赋观念”的存在。例如,他们认为欧几里德几何原理是使用人的理性制定的,而不是超自然的启示或感官体验的结果。相比之下,洛克和其他人采取了经验主义的观点,认为我们的知识的主要来源是我们的感官经验,人类理性在翻译这些经验上起次要作用。这一立场经常引用的证据是伽利略的发现——基于对行星运动的仔细观察——太阳系是以太阳为中心,而不是地球为中心。在语言学的背景下,本次辩论导致以下问题:人类语言经验与我们先天的“语言能力”各自多大程度上作为我们的语言知识的基础?在 NLP 中这个问题表现为在计算模型构建中语料库数据与语言学反省之间的优先级。
还有一个问题,在现实主义和理想主义之间的辩论中被奉若神明的是理论结构的形而上学的地位。康德主张现象与我们可以体验的表现以及不能直接被认识的“事情本身”之间的相互区别。语言现实主义者会认为如名词短语这样的理论建构是一个现实世界的实体,是人类看法和理由的独立存在,它实际 _ 导致 _ 观测到的语言现象。另一方面,语言理想主义者会说名词短语以及如语义表示这样更抽象的结构本质上无法观察到,只是担任有用的虚构的角色。语言学家写理论的方式往往与现实主义的立场相违背,而 NLP 从业人员占据中立地位,不然就倾向于理想主义立场。因此,在 NLP 中,如果一个理论的抽象导致一个有用的结果往往就足够了;不管这个结果是否揭示了任何人类语言处理。
还有一个问题,在现实主义和理想主义之间的辩论中被奉若神明的是理论结构的形而上学的地位。康德主张现象与我们可以体验的表现以及不能直接被认识的“事情本身”之间的相互区别。语言现实主义者会认为如名词短语这样的理论建构是一个现实世界的实体,是人类看法和理由的独立存在,它实际*导致*观测到的语言现象。另一方面,语言理想主义者会说名词短语以及如语义表示这样更抽象的结构本质上无法观察到,只是担任有用的虚构的角色。语言学家写理论的方式往往与现实主义的立场相违背,而 NLP 从业人员占据中立地位,不然就倾向于理想主义立场。因此,在 NLP 中,如果一个理论的抽象导致一个有用的结果往往就足够了;不管这个结果是否揭示了任何人类语言处理。
这些问题今天仍然存在,表现为符号与统计方法、深层与浅层处理、二元与梯度分类以及科学与工程目标之间的区别。然而,这样的反差现在已经非常细微,辩论不再像从前那样是两极化。事实上,大多数的讨论——大部分的进展——都包含一个“平衡协调”。例如,一种中间立场是假设人类天生被赋予基于类比和记忆的学习方法(弱理性主义),并使用这些方法确定他们的感官语言经验(经验主义)的有意义的模式。
......@@ -73,6 +73,6 @@ _ 但是目前为止,happy hacking!_
关于本文档...
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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
\ No newline at end of file
......@@ -85,7 +85,7 @@ NLTK 包含古腾堡项目(Project Gutenberg)电子文本档案的经过挑
这个程序显示每个文本的三个统计量:平均词长、平均句子长度和本文中每个词出现的平均次数(我们的词汇多样性得分)。请看,平均词长似乎是英语的一个一般属性,因为它的值总是`4`。(事实上,平均词长是`3`而不是`4`,因为`num_chars`变量计数了空白字符。)相比之下,平均句子长度和词汇多样性看上去是作者个人的特点。
前面的例子也表明我们怎样才能获取“原始”文本[](./ch02.html#raw-access)而不用把它分割成词符。`raw()`函数给我们没有进行过任何语言学处理的文件的内容。因此,例如`len(gutenberg.raw('blake-poems.txt'))`告诉我们文本中出现的 _ 字符 _ 个数,包括词之间的空格。`sents()`函数把文本划分成句子,其中每一个句子是一个单词列表:
前面的例子也表明我们怎样才能获取“原始”文本[](./ch02.html#raw-access)而不用把它分割成词符。`raw()`函数给我们没有进行过任何语言学处理的文件的内容。因此,例如`len(gutenberg.raw('blake-poems.txt'))`告诉我们文本中出现的*字符*个数,包括词之间的空格。`sents()`函数把文本划分成句子,其中每一个句子是一个单词列表:
```py
>>> macbeth_sentences = gutenberg.sents('shakespeare-macbeth.txt')
......@@ -108,7 +108,7 @@ NLTK 包含古腾堡项目(Project Gutenberg)电子文本档案的经过挑
## 1.2 网络和聊天文本
虽然古腾堡项目包含成千上万的书籍,它代表既定的文学。考虑较不正式的语言也是很重要的。NLTK 的网络文本小集合的内容包括 Firefox 交流论坛,在纽约无意听到的对话, _ 加勒比海盗 _ 的电影剧本,个人广告和葡萄酒的评论:
虽然古腾堡项目包含成千上万的书籍,它代表既定的文学。考虑较不正式的语言也是很重要的。NLTK 的网络文本小集合的内容包括 Firefox 交流论坛,在纽约无意听到的对话,*加勒比海盗*的电影剧本,个人广告和葡萄酒的评论:
```py
>>> from nltk.corpus import webtext
......@@ -135,7 +135,7 @@ wine.txt Lovely delicate, fragrant Rhone wine. Polished leather and strawb...
## 1.3 布朗语料库
布朗语料库是第一个百万词级的英语电子语料库的,由布朗大学于 1961 年创建。这个语料库包含 500 个不同来源的文本,按照文体分类,如:_ 新闻 _、_ 社论 _ 等。表[1.1](./ch02.html#tab-brown-sources)给出了各个文体的例子(完整列表,请参阅`http://icame.uib.no/brown/bcm-los.html`)。
布朗语料库是第一个百万词级的英语电子语料库的,由布朗大学于 1961 年创建。这个语料库包含 500 个不同来源的文本,按照文体分类,如:*新闻**社论*等。表[1.1](./ch02.html#tab-brown-sources)给出了各个文体的例子(完整列表,请参阅`http://icame.uib.no/brown/bcm-los.html`)。
表 1.1:
......@@ -609,7 +609,7 @@ fen
小心!
如果你正在创建一个包含一些你自己的 Python 代码的文件,一定 _ 不 _ 要将文件命名为`nltk.py`:这可能会在导入时占据“真正的”NLTK 包。当 Python 导入模块时,它先查找当前目录(文件夹)。
如果你正在创建一个包含一些你自己的 Python 代码的文件,一定*不*要将文件命名为`nltk.py`:这可能会在导入时占据“真正的”NLTK 包。当 Python 导入模块时,它先查找当前目录(文件夹)。
## 4 词汇资源
......@@ -661,7 +661,7 @@ def unusual_words(text):
'than', 'too', 'very', 's', 't', 'can', 'will', 'just', 'don', 'should', 'now']
```
让我们定义一个函数来计算文本中 _ 没有 _ 在停用词列表中的词的比例:
让我们定义一个函数来计算文本中*没有*在停用词列表中的词的比例:
```py
>>> def content_fraction(text):
......@@ -679,7 +679,7 @@ def unusual_words(text):
图 4.3:一个字母拼词谜题::在由随机选择的字母组成的网格中,选择里面的字母组成词;这个谜题叫做“目标”。
一个词汇列表对解决如图[4.3](./ch02.html#fig-target)中这样的词的谜题很有用。我们的程序遍历每一个词,对于每一个词检查是否符合条件。检查必须出现的字母[](./ch02.html#obligatory-letter)和长度限制[](./ch02.html#length-constraint)是很容易的(这里我们只查找 6 个或 6 个以上字母的词)。只使用指定的字母组合作为候选方案,尤其是一些指定的字母出现了两次(这里如字母 v)这样的检查是很棘手的。`FreqDist`比较法[](./ch02.html#freqdist-compare)允许我们检查每个 _ 字母 _ 在候选词中的频率是否小于或等于相应的字母在拼词谜题中的频率。
一个词汇列表对解决如图[4.3](./ch02.html#fig-target)中这样的词的谜题很有用。我们的程序遍历每一个词,对于每一个词检查是否符合条件。检查必须出现的字母[](./ch02.html#obligatory-letter)和长度限制[](./ch02.html#length-constraint)是很容易的(这里我们只查找 6 个或 6 个以上字母的词)。只使用指定的字母组合作为候选方案,尤其是一些指定的字母出现了两次(这里如字母 v)这样的检查是很棘手的。`FreqDist`比较法[](./ch02.html#freqdist-compare)允许我们检查每个*字母*在候选词中的频率是否小于或等于相应的字母在拼词谜题中的频率。
```py
>>> puzzle_letters = nltk.FreqDist('egivrvonl')
......@@ -744,7 +744,7 @@ def unusual_words(text):
对每一个词,这个词典资源提供语音的代码——不同的声音不同的标签——叫做 phones。请看 fire 有两个发音(美国英语中):单音节`F AY1 R`和双音节`F AY1 ER0`。CMU 发音词典中的符号是从 _Arpabet_ 来的,更多的细节请参考`http://en.wikipedia.org/wiki/Arpabet`
每个条目由两部分组成,我们可以用一个复杂的`for`语句来一个一个的处理这些。我们没有写`for entry in entries:`,而是用 _ 两个 _ 变量名`word, pron`替换`entry`[](./ch02.html#word-pron)。现在,每次通过循环时,`word`被分配条目的第一部分,`pron`被分配条目的第二部分:
每个条目由两部分组成,我们可以用一个复杂的`for`语句来一个一个的处理这些。我们没有写`for entry in entries:`,而是用*两个*变量名`word, pron`替换`entry`[](./ch02.html#word-pron)。现在,每次通过循环时,`word`被分配条目的第一部分,`pron`被分配条目的第二部分:
```py
>>> for word, pron in entries:
......@@ -876,7 +876,7 @@ KeyError: 'blog'
'throw'
```
通过添加其他源语言,我们可以让我们这个简单的翻译器更为有用。让我们使用`dict()`函数把德语-英语和西班牙语-英语对相互转换成一个词典,然后用这些添加的映射 _ 更新 _ 我们原来的`翻译`词典:
通过添加其他源语言,我们可以让我们这个简单的翻译器更为有用。让我们使用`dict()`函数把德语-英语和西班牙语-英语对相互转换成一个词典,然后用这些添加的映射*更新*我们原来的`翻译`词典:
```py
>>> de2en = swadesh.entries(['de', 'en']) # German-English
......@@ -1002,7 +1002,7 @@ Lemma('car.n.04.car'), Lemma('cable_car.n.01.car')]
## 5.2 WordNet 的层次结构
WordNet 的同义词集对应于抽象的概念,它们并不总是有对应的英语词汇。这些概念在层次结构中相互联系在一起。一些概念也很一般,如 _ 实体 _、_ 状态 _、_ 事件 _;这些被称为唯一前缀或者根同义词集。其他的,如 _ 油老虎 _ 和 _ 有仓门式后背的汽车 _ 等就比较具体的多。[5.1](./ch02.html#fig-wn-hierarchy)展示了一个概念层次的一小部分。
WordNet 的同义词集对应于抽象的概念,它们并不总是有对应的英语词汇。这些概念在层次结构中相互联系在一起。一些概念也很一般,如*实体**状态**事件*;这些被称为唯一前缀或者根同义词集。其他的,如*油老虎**有仓门式后背的汽车*等就比较具体的多。[5.1](./ch02.html#fig-wn-hierarchy)展示了一个概念层次的一小部分。
![Images/74248e04835acdba414fd407bb4f3241.jpg](Images/74248e04835acdba414fd407bb4f3241.jpg)
......@@ -1061,7 +1061,7 @@ Synset('ambulance.n.01')
## 5.3 更多的词汇关系
上位词和下位词被称为词汇关系,因为它们是同义集之间的关系。这个关系定位上下为“是一个”层次。WordNet 网络另一个重要的漫游方式是从元素到它们的部件(部分)或到它们被包含其中的东西(整体)。例如,一棵树的部分是它的树干,树冠等;这些都是`part_meronyms()`。一棵树的 _ 实质 _ 是包括心材和边材组成的,即`substance_meronyms()`。树木的集合形成了一个森林,即`member_holonyms()`
上位词和下位词被称为词汇关系,因为它们是同义集之间的关系。这个关系定位上下为“是一个”层次。WordNet 网络另一个重要的漫游方式是从元素到它们的部件(部分)或到它们被包含其中的东西(整体)。例如,一棵树的部分是它的树干,树冠等;这些都是`part_meronyms()`。一棵树的*实质*是包括心材和边材组成的,即`substance_meronyms()`。树木的集合形成了一个森林,即`member_holonyms()`
```py
>>> wn.synset('tree.n.01').part_meronyms()
......@@ -1207,7 +1207,7 @@ WordNet 原始描述是[(Fellbaum, 1998)](./bibliography.html#fellbaum1998)。
5. ☼ 考查一些名词的整体部分关系。请记住,有 3 种整体部分关系,所以你需要使用:`member_meronyms()`, `part_meronyms()`, `substance_meronyms()`, `member_holonyms()`, `part_holonyms()``substance_holonyms()`
6. ☼ 在比较词表的讨论中,我们创建了一个对象叫做`translate`,通过它你可以使用德语和意大利语词汇查找对应的英语词汇。这种方法可能会出现什么问题?你能提出一个办法来避免这个问题吗?
7. ☼ 根据 Strunk 和 White 的 _《Elements of Style》_,词 however 在句子开头使用是“in whatever way”或“to whatever extent”的意思,而没有“nevertheless”的意思。他们给出了正确用法的例子:However you advise him, he will probably do as he thinks best.(`http://www.bartleby.com/141/strunk3.html`) 使用词汇索引工具在我们一直在思考的各种文本中研究这个词的实际用法。也可以看 _LanguageLog_ 发布在`http://itre.cis.upenn.edu/~myl/languagelog/archives/001913.html`上的“Fossilized prejudices abou‘t however’”。
8. ◑ 在名字语料库上定义一个条件频率分布,显示哪个 _ 首 _ 字母在男性名字中比在女性名字中更常用(参见[4.4](./ch02.html#fig-cfd-gender))。
8. ◑ 在名字语料库上定义一个条件频率分布,显示哪个*首*字母在男性名字中比在女性名字中更常用(参见[4.4](./ch02.html#fig-cfd-gender))。
9. ◑ 挑选两个文本,研究它们之间在词汇、词汇丰富性、文体等方面的差异。你能找出几个在这两个文本中词意相当不同的词吗,例如在 _《白鲸记》_ 与 _《理智与情感》_ 中的 monstrous?
10. ◑ 阅读 BBC 新闻文章:_UK's Vicky Pollards 'left behind'_ `http://news.bbc.co.uk/1/hi/education/6173441.stm`。文章给出了有关青少年语言的以下统计:“使用最多的 20 个词,包括 yeah, no, but 和 like,占所有词的大约三分之一”。对于大量文本源来说,所有词标识符的三分之一有多少词类型?你从这个统计中得出什么结论?更多相关信息请阅读`http://itre.cis.upenn.edu/~myl/languagelog/archives/003993.html`上的 _LanguageLog_。
11. ◑ 调查模式分布表,寻找其他模式。试着用你自己对不同文体的印象理解来解释它们。你能找到其他封闭的词汇归类,展现不同文体的显著差异吗?
......@@ -1236,6 +1236,6 @@ WordNet 原始描述是[(Fellbaum, 1998)](./bibliography.html#fellbaum1998)。
关于本文档...
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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
\ No newline at end of file
......@@ -543,7 +543,7 @@ TypeError: can only concatenate list (not "str") to list
['John Lennon', 'Paul', 'George']
```
另一方面,如果我们尝试在一个 _ 字符串 _ 上这么做——将`query`的第 0 个字符修改为`'F'`——我们得到:
另一方面,如果我们尝试在一个*字符串*上这么做——将`query`的第 0 个字符修改为`'F'`——我们得到:
```py
>>> query[0] = 'F'
......@@ -1040,7 +1040,7 @@ NLTK 中包括几个现成的词干提取器,如果你需要一个词干提取
'from', 'som', 'farc', 'aqu', 'ceremony', '.']
```
词干提取过程没有明确定义,我们通常选择心目中最适合我们的应用的词干提取器。如果你要索引一些文本和使搜索支持不同词汇形式的话,Porter 词干提取器是一个很好的选择([3.6](./ch03.html#code-stemmer-indexing) 所示,它采用 _ 面向对象 _ 编程技术,这超出了本书的范围,字符串格式化技术将在[3.9](./ch03.html#sec-formatting)讲述,`enumerate()`函数将在[4.2](./ch04.html#sec-sequences)解释)。
词干提取过程没有明确定义,我们通常选择心目中最适合我们的应用的词干提取器。如果你要索引一些文本和使搜索支持不同词汇形式的话,Porter 词干提取器是一个很好的选择([3.6](./ch03.html#code-stemmer-indexing) 所示,它采用*面向对象*编程技术,这超出了本书的范围,字符串格式化技术将在[3.9](./ch03.html#sec-formatting)讲述,`enumerate()`函数将在[4.2](./ch04.html#sec-sequences)解释)。
```py
class IndexedText(object):
......@@ -1120,7 +1120,7 @@ WordNet 词形归并器只在产生的词在它的词典中时才删除词缀。
**要点:** 记住在正则表达式前加字母`r`(表示"原始的"),它告诉 Python 解释器按照字面表示对待字符串,而不去处理正则表达式中包含的反斜杠字符。
在空格符处分割文本给我们如`'(not'``'herself,'`这样的词符。另一种方法是使用 Python 提供给我们的字符类`\w`匹配词中的字符,相当于`[a-zA-Z0-9_]`。它还定义了这个类的补集`\W`,即所有字母、数字和下划线以外的字符。我们可以在一个简单的正则表达式中用`\W`来分割所有单词字符 _ 以外 _ 的输入:
在空格符处分割文本给我们如`'(not'``'herself,'`这样的词符。另一种方法是使用 Python 提供给我们的字符类`\w`匹配词中的字符,相当于`[a-zA-Z0-9_]`。它还定义了这个类的补集`\W`,即所有字母、数字和下划线以外的字符。我们可以在一个简单的正则表达式中用`\W`来分割所有单词字符*以外*的输入:
```py
>>> re.split(r'\W+', raw)
......@@ -1131,7 +1131,7 @@ WordNet 词形归并器只在产生的词在它的词典中时才删除词缀。
'']
```
可以看到,在开始和结尾都给了我们一个空字符串(要了解原因请尝试`'xx'.split('x')`)。通过`re.findall(r'\w+', raw)`使用模式匹配词汇而不是空白符号,我们得到相同的标识符,但没有空字符串。现在,我们正在匹配词汇,我们处在扩展正则表达式覆盖更广泛的情况的位置。正则表达式«`\w+|\S\w*`»将首先尝试匹配词中字符的所有序列。如果没有找到匹配的,它会尝试匹配后面跟着词中字符的任何 _ 非 _ 空白字符(`\S``\s`的补)。这意味着标点会与跟在后面的字母(如's)在一起,但两个或两个以上的标点字符序列会被分割。
可以看到,在开始和结尾都给了我们一个空字符串(要了解原因请尝试`'xx'.split('x')`)。通过`re.findall(r'\w+', raw)`使用模式匹配词汇而不是空白符号,我们得到相同的标识符,但没有空字符串。现在,我们正在匹配词汇,我们处在扩展正则表达式覆盖更广泛的情况的位置。正则表达式«`\w+|\S\w*`»将首先尝试匹配词中字符的所有序列。如果没有找到匹配的,它会尝试匹配后面跟着词中字符的任何*非*空白字符(`\S``\s`的补)。这意味着标点会与跟在后面的字母(如's)在一起,但两个或两个以上的标点字符序列会被分割。
```py
>>> re.findall(r'\w+|\S\w*', raw)
......@@ -1691,7 +1691,7 @@ SIGHAN,ACL 中文语言处理特别兴趣小组`http://sighan.org/`,重点
27. ◑ Python 的`random`模块包括函数`choice()`,它从一个序列中随机选择一个项目,例如`choice("aehh ")`会产生四种可能的字符中的一个,字母`h`的几率是其它字母的两倍。写一个表达式产生器,从字符串`"aehh "`产生 500 个随机选择的字母的序列,并将这个表达式写入函数`''.join()`调用中,将它们连接成一个长字符串。你得到的结果应该看起来像失去控制的喷嚏或狂笑:`he haha ee heheeh eha`。使用`split()`和`join()`再次规范化这个字符串中的空格。
28. ◑ 考虑下面的摘自 MedLine 语料库的句子中的数字表达式:The corresponding free cortisol fractions in these sera were 4.53 +/- 0.15% and 8.16 +/- 0.23%, respectively.我们应该说数字表达式 4.53 +/- 0.15%是三个词吗?或者我们应该说它是一个单独的复合词?或者我们应该说它实际上是 _ 九 _ 个词,因为它读作“four point five three,plus or minus fifteen percent”?或者我们应该说这不是一个“真正的”词,因为它不会出现在任何词典中?讨论这些不同的可能性。你能想出产生这些答案中至少两个以上可能性的应用领域吗?
28. ◑ 考虑下面的摘自 MedLine 语料库的句子中的数字表达式:The corresponding free cortisol fractions in these sera were 4.53 +/- 0.15% and 8.16 +/- 0.23%, respectively.我们应该说数字表达式 4.53 +/- 0.15%是三个词吗?或者我们应该说它是一个单独的复合词?或者我们应该说它实际上是*九*个词,因为它读作“four point five three,plus or minus fifteen percent”?或者我们应该说这不是一个“真正的”词,因为它不会出现在任何词典中?讨论这些不同的可能性。你能想出产生这些答案中至少两个以上可能性的应用领域吗?
29. ◑ 可读性测量用于为一个文本的阅读难度打分,给语言学习者挑选适当难度的文本。在一个给定的文本中,让我们定义μ<sub>w</sub>为每个词的平均字母数,μ<sub>s</sub>为每个句子的平均词数。文本自动可读性指数(ARI)被定义为: `4.71` μ<sub>w</sub> `+ 0.5` μ<sub>s</sub> `- 21.43`。计算布朗语料库各部分的 ARI 得分,包括 `f`(lore)和`j`(learned)部分。利用`nltk.corpus.brown.words()`产生一个词汇序列,`nltk.corpus.brown.sents()`产生一个句子的序列的事实。
......@@ -1753,6 +1753,6 @@ SIGHAN,ACL 中文语言处理特别兴趣小组`http://sighan.org/`,重点
关于本文档...
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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
\ No newline at end of file
......@@ -70,7 +70,7 @@
[['Python'], ['Monty'], ['Python']]
```
我们一开始用含有 3 个引用的列表,每个引用指向一个空列表对象。然后,我们通过给它追加`'Python'`修改这个对象,结果变成包含 3 个到一个列表对象`['Python']`的引用的列表。下一步,我们使用到一个新对象`['Monty']`的引用来 _ 覆盖 _ 三个元素中的一个。这最后一步修改嵌套列表内的 3 个对象引用中的 1 个。然而,`['Python']`对象并没有改变,仍然是在我们的嵌套列表的列表中的两个位置被引用。关键是要明白通过一个对象引用修改一个对象与通过覆盖一个对象引用之间的区别。
我们一开始用含有 3 个引用的列表,每个引用指向一个空列表对象。然后,我们通过给它追加`'Python'`修改这个对象,结果变成包含 3 个到一个列表对象`['Python']`的引用的列表。下一步,我们使用到一个新对象`['Monty']`的引用来*覆盖*三个元素中的一个。这最后一步修改嵌套列表内的 3 个对象引用中的 1 个。然而,`['Python']`对象并没有改变,仍然是在我们的嵌套列表的列表中的两个位置被引用。关键是要明白通过一个对象引用修改一个对象与通过覆盖一个对象引用之间的区别。
注意
......@@ -129,7 +129,7 @@ cat
['dog']
```
也就是说,我们 _ 不必 _ 在条件中写`if len(element) > 0:`
也就是说,我们*不必*在条件中写`if len(element) > 0:`
使用`if...elif`而不是在一行中使用两个`if`语句有什么区别?嗯,考虑以下情况:
......@@ -143,7 +143,7 @@ cat
1
```
因为表达式中`if`子句条件满足,Python 就不会求值`elif`子句,所以我们永远不会得到输出`2`。相反,如果我们用一个`if`替换`elif`,那么我们将会输出`1``2`。所以`elif`子句比单独的`if`子句潜在地给我们更多信息;当它被判定为真时,告诉我们不仅条件满足而且前面的`if`子句条件 _ 不 _ 满足。
因为表达式中`if`子句条件满足,Python 就不会求值`elif`子句,所以我们永远不会得到输出`2`。相反,如果我们用一个`if`替换`elif`,那么我们将会输出`1``2`。所以`elif`子句比单独的`if`子句潜在地给我们更多信息;当它被判定为真时,告诉我们不仅条件满足而且前面的`if`子句条件*不*满足。
`all()`函数和`any()`函数可以应用到一个列表(或其他序列),来检查是否全部或任一项目满足某个条件:
......@@ -349,7 +349,7 @@ True
### 过程风格与声明风格
我们刚才已经看到可以不同的方式执行相同的任务,其中蕴含着对执行效率的影响。另一个影响程序开发的因素是 _ 编程风格 _。思考下面的计算布朗语料库中词的平均长度的程序:
我们刚才已经看到可以不同的方式执行相同的任务,其中蕴含着对执行效率的影响。另一个影响程序开发的因素是*编程风格*。思考下面的计算布朗语料库中词的平均长度的程序:
```py
>>> tokens = nltk.corpus.brown.words(categories='news')
......@@ -362,7 +362,7 @@ True
4.401545438271973
```
在这段程序中,我们使用变量`count`跟踪遇到的词符的数量,`total`储存所有词的长度的总和。这是一个低级别的风格,与机器代码,即计算机的 CPU 所执行的基本操作,相差不远。两个变量就像 CPU 的两个寄存器,积累许多中间环节产生的值,和直到最才有意义的值。我们说,这段程序是以 _ 过程 _ 风格编写,一步一步口授机器操作。现在,考虑下面的程序,计算同样的事情:
在这段程序中,我们使用变量`count`跟踪遇到的词符的数量,`total`储存所有词的长度的总和。这是一个低级别的风格,与机器代码,即计算机的 CPU 所执行的基本操作,相差不远。两个变量就像 CPU 的两个寄存器,积累许多中间环节产生的值,和直到最才有意义的值。我们说,这段程序是以*过程*风格编写,一步一步口授机器操作。现在,考虑下面的程序,计算同样的事情:
```py
>>> total = sum(len(t) for t in tokens)
......@@ -433,7 +433,7 @@ True
['unextinguishable', 'transubstantiate', 'inextinguishable', 'incomprehensible']
```
请注意,我们的第一个解决方案找到第一个长度最长的词,而第二种方案找到 _ 所有 _ 最长的词(通常是我们想要的)。虽然有两个解决方案之间的理论效率的差异,主要的开销是到内存中读取数据;一旦数据准备好,第二阶段处理数据可以瞬间高效完成。我们还需要平衡我们对程序的效率与程序员的效率的关注。一种快速但神秘的解决方案将是更难理解和维护的。
请注意,我们的第一个解决方案找到第一个长度最长的词,而第二种方案找到*所有*最长的词(通常是我们想要的)。虽然有两个解决方案之间的理论效率的差异,主要的开销是到内存中读取数据;一旦数据准备好,第二阶段处理数据可以瞬间高效完成。我们还需要平衡我们对程序的效率与程序员的效率的关注。一种快速但神秘的解决方案将是更难理解和维护的。
### 计数器的一些合理用途
......@@ -494,7 +494,7 @@ def get_text(file):
现在,任何时候我们想从一个 HTML 文件得到干净的文字,都可以用文件的名字作为唯一的参数调用`get_text()`。它会返回一个字符串,我们可以将它指定给一个变量,例如:`contents = get_text("test.html")`。每次我们要使用这一系列的步骤,只需要调用这个函数。
使用函数可以为我们的程序节约空间。更重要的是,我们为函数选择名称可以提高程序 _ 可读性 _。在上面的例子中,只要我们的程序需要从文件读取干净的文本,我们不必弄乱这四行代码的程序,只需要调用`get_text()`。这种命名方式有助于提供一些“语义解释”——它可以帮助我们的程序的读者理解程序的“意思”。
使用函数可以为我们的程序节约空间。更重要的是,我们为函数选择名称可以提高程序*可读性*。在上面的例子中,只要我们的程序需要从文件读取干净的文本,我们不必弄乱这四行代码的程序,只需要调用`get_text()`。这种命名方式有助于提供一些“语义解释”——它可以帮助我们的程序的读者理解程序的“意思”。
请注意,上面的函数定义包含一个字符串。函数定义内的第一个字符串被称为文档字符串。它不仅为阅读代码的人记录函数的功能,从文件加载这段代码的程序员也能够访问:
......@@ -928,7 +928,7 @@ Python 提供一些具有函数式编程语言如 Haskell 标准特征的高阶
## 4.6 程序开发
编程是一种技能,需要获得几年的各种编程语言和任务的经验。关键的高层次能力是 _ 算法设计 _ 及其在 _ 结构化编程 _ 中的实现。关键的低层次的能力包括熟悉语言的语法结构,以及排除故障的程序(不能表现预期的行为的程序)的各种诊断方法的知识。
编程是一种技能,需要获得几年的各种编程语言和任务的经验。关键的高层次能力是*算法设计*及其在*结构化编程*中的实现。关键的低层次的能力包括熟悉语言的语法结构,以及排除故障的程序(不能表现预期的行为的程序)的各种诊断方法的知识。
本节描述一个程序模块的内部结构,以及如何组织一个多模块的程序。然后描述程序开发过程中出现的各种错误,你可以做些什么来解决这些问题,更好的是,从一开始就避免它们。
......
......@@ -680,7 +680,7 @@ TypeError: list objects are unhashable
defaultdict(<class 'int'>, {'ADJ': 11, 'NOUN': 5})
```
这个例子使用一个字典,它的条目的默认值也是一个字典(其默认值是`int()`,即 0)。请注意我们如何遍历已标注语料库的双连词,每次遍历处理一个词-标记对[](./ch05.html#processing-pairs)。每次通过循环时,我们更新字典`pos`中的条目`(t1, w2)`,一个标记和它 _ 后面 _ 的词[](./ch05.html#tag-word-update)。当我们在`pos`中查找一个项目时,我们必须指定一个复合键[](./ch05.html#compound-key),然后得到一个字典对象。一个词性标注器可以使用这些信息来决定词 right,前面是一个限定词时,应标注为`ADJ`
这个例子使用一个字典,它的条目的默认值也是一个字典(其默认值是`int()`,即 0)。请注意我们如何遍历已标注语料库的双连词,每次遍历处理一个词-标记对[](./ch05.html#processing-pairs)。每次通过循环时,我们更新字典`pos`中的条目`(t1, w2)`,一个标记和它*后面*的词[](./ch05.html#tag-word-update)。当我们在`pos`中查找一个项目时,我们必须指定一个复合键[](./ch05.html#compound-key),然后得到一个字典对象。一个词性标注器可以使用这些信息来决定词 right,前面是一个限定词时,应标注为`ADJ`
## 3.7 反转字典
......@@ -924,7 +924,7 @@ def display():
## 5.3 一般的 N-gram 标注
在基于一元处理一个语言处理任务时,我们使用上下文中的一个项目。标注的时候,我们只考虑当前的词符,与更大的上下文隔离。给定一个模型,我们能做的最好的是为每个词标注其 _ 先验的 _ 最可能的标记。这意味着我们将使用相同的标记标注一个词,如 wind,不论它出现的上下文是 the wind 还是 to wind。
在基于一元处理一个语言处理任务时,我们使用上下文中的一个项目。标注的时候,我们只考虑当前的词符,与更大的上下文隔离。给定一个模型,我们能做的最好的是为每个词标注其*先验的*最可能的标记。这意味着我们将使用相同的标记标注一个词,如 wind,不论它出现的上下文是 the wind 还是 to wind。
一个 n-gram tagger 标注器是一个一元标注器的一般化,它的上下文是当前词和它前面 _n_-1 个标识符的词性标记,如图[5.1](./ch05.html#fig-tag-context)所示。要选择的标记是圆圈里的 _t_&lt;sub&gt;n&lt;/sub&gt;,灰色阴影的是上下文。在[5.1](./ch05.html#fig-tag-context)所示的 n-gram 标注器的例子中,我们让 _n_=3;也就是说,我们考虑当前词的前两个词的标记。一个 n-gram 标注器挑选在给定的上下文中最有可能的标记。
......@@ -934,7 +934,7 @@ def display():
注意
1-gram 标注器是一元标注器另一个名称:即用于标注一个词符的上下文的只是词符本身。2-gram 标注器也称为 _ 二元标注器 _,3-gram 标注器也称为 _ 三元标注器 _
1-gram 标注器是一元标注器另一个名称:即用于标注一个词符的上下文的只是词符本身。2-gram 标注器也称为*二元标注器*,3-gram 标注器也称为*三元标注器*
`NgramTagger`类使用一个已标注的训练语料库来确定对每个上下文哪个词性标记最有可能。这里我们看 n-gram 标注器的一个特殊情况,二元标注器。首先,我们训练它,然后用它来标注未标注的句子:
......@@ -963,7 +963,7 @@ def display():
0.102063...
```
当 _n_ 越大,上下文的特异性就会增加,我们要标注的数据中包含训练数据中不存在的上下文的几率也增大。这被称为 _ 数据稀疏 _ 问题,在 NLP 中是相当普遍的。因此,我们的研究结果的精度和覆盖范围之间需要有一个权衡(这与信息检索中的精度/召回权衡有关)。
当 _n_ 越大,上下文的特异性就会增加,我们要标注的数据中包含训练数据中不存在的上下文的几率也增大。这被称为*数据稀疏*问题,在 NLP 中是相当普遍的。因此,我们的研究结果的精度和覆盖范围之间需要有一个权衡(这与信息检索中的精度/召回权衡有关)。
小心!
......@@ -1071,7 +1071,7 @@ n-gram 标注器的一个潜在的问题是它们的 n-gram 表(或语言模
第二个问题是关于上下文。n-gram 标注器从前面的上下文中获得的唯一的信息是标记,虽然词本身可能是一个有用的信息源。n-gram 模型使用上下文中的词的其他特征为条件是不切实际的。在本节中,我们考察 Brill 标注,一种归纳标注方法,它的性能很好,使用的模型只有 n-gram 标注器的很小一部分。
Brill 标注是一种 _ 基于转换的学习 _,以它的发明者命名。一般的想法很简单:猜每个词的标记,然后返回和修复错误。在这种方式中,Brill 标注器陆续将一个不良标注的文本转换成一个更好的。与 n-gram 标注一样,这是有 _ 监督的学习 _ 方法,因为我们需要已标注的训练数据来评估标注器的猜测是否是一个错误。然而,不像 n-gram 标注,它不计数观察结果,只编制一个转换修正规则列表。
Brill 标注是一种*基于转换的学习*,以它的发明者命名。一般的想法很简单:猜每个词的标记,然后返回和修复错误。在这种方式中,Brill 标注器陆续将一个不良标注的文本转换成一个更好的。与 n-gram 标注一样,这是有*监督的学习*方法,因为我们需要已标注的训练数据来评估标注器的猜测是否是一个错误。然而,不像 n-gram 标注,它不计数观察结果,只编制一个转换修正规则列表。
Brill 标注的的过程通常是与绘画类比来解释的。假设我们要画一棵树,包括大树枝、树枝、小枝、叶子和一个统一的天蓝色背景的所有细节。不是先画树然后尝试在空白处画蓝色,而是简单的将整个画布画成蓝色,然后通过在蓝色背景上上色“修正”树的部分。以同样的方式,我们可能会画一个统一的褐色的树干再回过头来用更精细的刷子画进一步的细节。Brill 标注使用了同样的想法:以大笔画开始,然后修复细节,一点点的细致的改变。让我们看看下面的例子:
......@@ -1166,7 +1166,7 @@ Statement User121 18/m pm me if u tryin to chat
18. ◑ 生成已标注数据的一些统计数据,回答下列问题:
1. 总是被分配相同词性的词类的比例是多少?
2. 多少词是有歧义的,从某种意义上说,它们至少和两个标记一起出现?
3. 布朗语料库中这些有歧义的词的 _ 词符 _ 的百分比是多少?
3. 布朗语料库中这些有歧义的词的*词符*的百分比是多少?
19.`evaluate()`方法算出一个文本上运行的标注器的精度。例如,如果提供的已标注文本是`[('the', 'DT'), ('dog', 'NN')]`,标注器产生的输出是`[('the', 'NN'), ('dog', 'NN')]`,那么得分为`0.5`。让我们尝试找出评价方法是如何工作的:
1. 一个标注器`t`将一个词汇列表作为输入,产生一个已标注词列表作为输出。然而,`t.evaluate()`只以一个正确标注的文本作为唯一的参数。执行标注之前必须对输入做些什么?
2. 一旦标注器创建了新标注的文本,`evaluate()` 方法可能如何比较它与原来标注的文本,计算准确性得分?
......@@ -1209,6 +1209,6 @@ Statement User121 18/m pm me if u tryin to chat
关于本文档...
UPDATED FOR NLTK 3.0\. 本章来自于 _Natural Language Processing with 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 版一起发行。
UPDATED FOR NLTK 3.0\. 本章来自于 _Natural Language Processing with 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
\ No newline at end of file
......@@ -329,7 +329,7 @@ if endswith(,) == False:
## 1.5 探索上下文语境
通过增加特征提取函数,我们可以修改这个词性标注器来利用各种词内部的其他特征,例如词长、它所包含的音节数或者它的前缀。然而,只要特征提取器仅仅看着目标词,我们就没法添加依赖词出现的 _ 上下文语境 _ 特征。然而上下文语境特征往往提供关于正确标记的强大线索——例如,标注词"fly",如果知道它前面的词是“a”将使我们能够确定它是一个名词,而不是一个动词。
通过增加特征提取函数,我们可以修改这个词性标注器来利用各种词内部的其他特征,例如词长、它所包含的音节数或者它的前缀。然而,只要特征提取器仅仅看着目标词,我们就没法添加依赖词出现的*上下文语境*特征。然而上下文语境特征往往提供关于正确标记的强大线索——例如,标注词"fly",如果知道它前面的词是“a”将使我们能够确定它是一个名词,而不是一个动词。
为了采取基于词的上下文的特征,我们必须修改以前为我们的特征提取器定义的模式。不是只传递已标注的词,我们将传递整个(未标注的)句子,以及目标词的索引。[1.6](./ch06.html#code-suffix-pos-tag)演示了这种方法,使用依赖上下文的特征提取器定义一个词性标记分类器。
......@@ -462,7 +462,7 @@ def segment_sentences(words):
## 2.2 识别对话行为类型
处理对话时,将对话看作说话者执行的 _ 行为 _ 是很有用的。对于表述行为的陈述句这种解释是最直白的,例如"I forgive you"或"I bet you can't climb that hill"。但是问候、问题、回答、断言和说明都可以被认为是基于语言的行为类型。识别对话中言语下的对话行为是理解谈话的重要的第一步。
处理对话时,将对话看作说话者执行的*行为*是很有用的。对于表述行为的陈述句这种解释是最直白的,例如"I forgive you"或"I bet you can't climb that hill"。但是问候、问题、回答、断言和说明都可以被认为是基于语言的行为类型。识别对话中言语下的对话行为是理解谈话的重要的第一步。
NPS 聊天语料库,在[1](./ch02.html#sec-extracting-text-from-corpora)中的展示过,包括超过 10,000 个来自即时消息会话的帖子。这些帖子都已经被贴上 15 种对话行为类型中的一种标签,例如“陈述”,“情感”,“yn 问题”和“Continuer”。因此,我们可以利用这些数据建立一个分类器,识别新的即时消息帖子的对话行为类型。第一步是提取基本的消息数据。我们将调用`xml_posts()`来得到一个数据结构,表示每个帖子的 XML 注释:
......@@ -574,7 +574,7 @@ Python 提供了一个良好的环境进行基本的文本处理和特征提取
>>> train_set, test_set = tagged_sents[size:], tagged_sents[:size]
```
在这种情况下,我们的测试集和训练集将是 _ 非常 _ 相似的。训练集和测试集均取自同一文体,所以我们不能相信评估结果可以推广到其他文体。更糟糕的是,因为调用`random.shuffle()`,测试集中包含来自训练使用过的相同的文档的句子。如果文档中有相容的模式(也就是说,如果一个给定的词与特定词性标记一起出现特别频繁),那么这种差异将体现在开发集和测试集。一个稍好的做法是确保训练集和测试集来自不同的文件:
在这种情况下,我们的测试集和训练集将是*非常*相似的。训练集和测试集均取自同一文体,所以我们不能相信评估结果可以推广到其他文体。更糟糕的是,因为调用`random.shuffle()`,测试集中包含来自训练使用过的相同的文档的句子。如果文档中有相容的模式(也就是说,如果一个给定的词与特定词性标记一起出现特别频繁),那么这种差异将体现在开发集和测试集。一个稍好的做法是确保训练集和测试集来自不同的文件:
```py
>>> file_ids = brown.fileids(categories='news')
......@@ -660,7 +660,7 @@ NNS | 1.5% . . . . <3.2%> . . 0.0% |
为了评估我们的模型,我们必须为测试集保留一部分已标注的数据。正如我们已经提到,如果测试集是太小了,我们的评价可能不准确。然而,测试集设置较大通常意味着训练集设置较小,如果已标注数据的数量有限,这样设置对性能会产生重大影响。
这个问题的解决方案之一是在不同的测试集上执行多个评估,然后组合这些评估的得分,这种技术被称为交叉验证。特别是,我们将原始语料细分为 N 个子集称为折叠。对于每一个这些的折叠,我们使用 _ 除 _ 这个折叠中的数据外其他所有数据训练模型,然后在这个折叠上测试模型。即使个别的折叠可能是太小了而不能在其上给出准确的评价分数,综合评估得分是基于大量的数据,因此是相当可靠的。
这个问题的解决方案之一是在不同的测试集上执行多个评估,然后组合这些评估的得分,这种技术被称为交叉验证。特别是,我们将原始语料细分为 N 个子集称为折叠。对于每一个这些的折叠,我们使用*除*这个折叠中的数据外其他所有数据训练模型,然后在这个折叠上测试模型。即使个别的折叠可能是太小了而不能在其上给出准确的评价分数,综合评估得分是基于大量的数据,因此是相当可靠的。
第二,同样重要的,采用交叉验证的优势是,它可以让我们研究不同的训练集上性能变化有多大。如果我们从所有 N 个训练集得到非常相似的分数,然后我们可以相当有信心,得分是准确的。另一方面,如果 N 个训练集上分数很大不同,那么,我们应该对评估得分的准确性持怀疑态度。
......@@ -730,7 +730,7 @@ def entropy(labels):
基于这个假设,我们可以计算表达式 P(label|features),给定一个特别的特征集一个输入具有特定标签的概率。要为一个新的输入选择标签,我们可以简单地选择使 P(l|features)最大的标签 l。
一开始,我们注意到 P(label|features)等于具有特定标签 _ 和 _ 特定特征集的输入的概率除以具有特定特征集的输入的概率:
一开始,我们注意到 P(label|features)等于具有特定标签*和*特定特征集的输入的概率除以具有特定特征集的输入的概率:
```py
>>> from nltk.corpus import senseval
......@@ -791,7 +791,7 @@ d. in Macbeth _versus_ on Letterman
关于本文档...
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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
......
......@@ -255,7 +255,7 @@ ChunkParse score:
F-Measure: 0.0%
```
IOB 标记准确性表明超过三分之一的词被标注为`O`,即没有在`NP`词块中。然而,由于我们的标注器没有找到 _ 任何 _ 词块,其精度、召回率和 F-度量均为零。现在让我们尝试一个初级的正则表达式词块划分器,查找以名词短语标记的特征字母开头的标记(如`CD`, `DT`和`JJ`)。
IOB 标记准确性表明超过三分之一的词被标注为`O`,即没有在`NP`词块中。然而,由于我们的标注器没有找到*任何*词块,其精度、召回率和 F-度量均为零。现在让我们尝试一个初级的正则表达式词块划分器,查找以名词短语标记的特征字母开头的标记(如`CD`, `DT`和`JJ`)。
```py
>>> grammar = r"NP: {<[CDJNP].*>+}"
......@@ -268,7 +268,7 @@ ChunkParse score:
F-Measure: 69.2%
```
正如你看到的,这种方法达到相当好的结果。但是,我们可以采用更多数据驱动的方法改善它,在这里我们使用训练语料找到对每个词性标记最有可能的块标记(`I`, `O`或`B`)。换句话说,我们可以使用 _ 一元标注器 _([4](./ch05.html#sec-automatic-tagging))建立一个词块划分器。但不是尝试确定每个词的正确的词性标记,而是根据每个词的词性标记,尝试确定正确的词块标记。
正如你看到的,这种方法达到相当好的结果。但是,我们可以采用更多数据驱动的方法改善它,在这里我们使用训练语料找到对每个词性标记最有可能的块标记(`I`, `O`或`B`)。换句话说,我们可以使用*一元标注器*([4](./ch05.html#sec-automatic-tagging))建立一个词块划分器。但不是尝试确定每个词的正确的词性标记,而是根据每个词的词性标记,尝试确定正确的词块标记。
在[3.1](./ch07.html#code-unigram-chunker)中,我们定义了`UnigramChunker`类,使用一元标注器给句子加词块标记。这个类的大部分代码只是用来在 NLTK 的`ChunkParserI`接口使用的词块树表示和嵌入式标注器使用的 IOB 表示之间镜像转换。类定义了两个方法:一个构造函数[❶](./ch07.html#code-unigram-chunker-constructor),当我们建立一个新的 UnigramChunker 时调用;以及`parse`方法[❸](./ch07.html#code-unigram-chunker-parse),用来给新句子划分词块。
......@@ -732,7 +732,7 @@ IOB 格式(有时也称为 BIO 格式)由[(Ramshaw & Marcus, 1995)](./biblio
1. ☼ IOB 格式分类标注标识符为`I`、`O`和`B`。三个标签为什么是必要的?如果我们只使用`I`和`O`标记会造成什么问题?
2. ☼ 写一个标记模式匹配包含复数中心名词在内的名词短语,如"many/JJ researchers/NNS", "two/CD weeks/NNS", "both/DT new/JJ positions/NNS"。通过泛化处理单数名词短语的标记模式,尝试做这个。
3. ☼ 选择 CoNLL 语料库中三种词块类型之一。研究 CoNLL 语料库,并尝试观察组成这种类型词块的词性标记序列的任何模式。使用正则表达式词块划分器`nltk.RegexpParser`开发一个简单的词块划分器。讨论任何难以可靠划分词块的标记序列。
4. ☼ _ 词块 _ 的早期定义是出现在词缝之间的内容。开发一个词块划分器以将完整的句子作为一个单独的词块开始,然后其余的工作完全加塞词缝完成。在你自己的应用程序的帮助下,确定哪些标记(或标记序列)最有可能组成词缝。相对于完全基于词块规则的词块划分器,比较这种方法的表现和易用性。
4. ☼ *词块*的早期定义是出现在词缝之间的内容。开发一个词块划分器以将完整的句子作为一个单独的词块开始,然后其余的工作完全加塞词缝完成。在你自己的应用程序的帮助下,确定哪些标记(或标记序列)最有可能组成词缝。相对于完全基于词块规则的词块划分器,比较这种方法的表现和易用性。
5. ◑ 写一个标记模式,涵盖包含动名词在内的名词短语,如"the/DT receiving/VBG end/NN", "assistant/NN managing/VBG editor/NN"。将这些模式加入到语法,每行一个。用自己设计的一些已标注的句子,测试你的工作。
6. ◑ 写一个或多个标记模式处理有连接词的名词短语,如"July/NNP and/CC August/NNP", "all/DT your/PRP$ managers/NNS and/CC supervisors/NNS", "company/NN courts/NNS and/CC adjudicators/NNS"。
7. ◑ 用任何你之前已经开发的词块划分器执行下列评估任务。(请注意,大多数词块划分语料库包含一些内部的不一致,以至于任何合理的基于规则的方法都将产生错误。)
......@@ -758,6 +758,6 @@ IOB 格式(有时也称为 BIO 格式)由[(Ramshaw & Marcus, 1995)](./biblio
关于本文档...
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 作出更新。本章来自于 _Natural Language Processing with 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
\ No newline at end of file
......@@ -122,11 +122,11 @@ grammar2 = nltk.CFG.fromstring("""
递归下降分析有三个主要的缺点。首先,左递归产生式,如`NP -&gt; NP PP`会进入死循环。第二,分析器浪费了很多时间处理不符合输入句子的词和结构。第三,回溯过程中可能会丢弃分析过的成分,它们将需要在之后再次重建。例如,从`VP -&gt; V NP`上回溯将放弃为`NP`创建的子树。如果分析器之后处理`VP -&gt; V NP PP`,那么`NP`子树必须重新创建。
递归下降分析是一种自上而下分析。自上而下分析器在检查输入之前先使用文法 _ 预测 _ 输入将是什么!然而,由于输入对分析器一直是可用的,从一开始就考虑输入的句子会是更明智的做法。这种方法被称为自下而上分析,在下一节中我们将看到一个例子。
递归下降分析是一种自上而下分析。自上而下分析器在检查输入之前先使用文法*预测*输入将是什么!然而,由于输入对分析器一直是可用的,从一开始就考虑输入的句子会是更明智的做法。这种方法被称为自下而上分析,在下一节中我们将看到一个例子。
## 4.2 移进-归约分析
一种简单的自下而上分析器是移进-归约分析器。与所有自下而上的分析器一样,移进-归约分析器尝试找到对应文法生产式 _ 右侧 _ 的词和短语的序列,用左侧的替换它们,直到整个句子归约为一个`S`
一种简单的自下而上分析器是移进-归约分析器。与所有自下而上的分析器一样,移进-归约分析器尝试找到对应文法生产式*右侧*的词和短语的序列,用左侧的替换它们,直到整个句子归约为一个`S`
移位-规约分析器反复将下一个输入词推到堆栈([4.1](./ch04.html#sec-back-to-the-basics));这是移位操作。如果堆栈上的前 _n_ 项,匹配一些产生式的右侧的 _n_ 个项目,那么就把它们弹出栈,并把产生式左边的项目压入栈。这种替换前 _n_ 项为一项的操作就是规约操作。此操作只适用于堆栈的顶部;规约栈中的项目必须在后面的项目被压入栈之前做。当所有的输入都使用过,堆栈中只剩余一个项目,也就是一颗分析树作为它的根的`S`节点时,分析器完成。移位-规约分析器通过上述过程建立一颗分析树。每次弹出堆栈 _n_ 个项目,它就将它们组合成部分的分析树,然后将这压回推栈。我们可以使用图形化示范`nltk.app.srparser()`看到移位-规约分析算法步骤。执行此分析器的六个阶段,如[4.2](./ch08.html#fig-srparser1-6)所示。
......@@ -375,7 +375,7 @@ PP 附着语料库`nltk.corpus.ppattach`是另一个有关特别动词配价的
NLTK 语料库收集了来自 PE08 跨框架跨领域分析器评估共享任务的数据。一个更大的文法集合已准备好用于比较不同的分析器,它可以通过下载`large_grammars`包获得(如`python -m nltk.downloader large_grammars`)。
NLTK 语料库也收集了 _ 中央研究院树库语料 _,包括 10,000 句已分析的句子,来自 _ 现代汉语中央研究院平衡语料库 _。让我们加载并显示这个语料库中的一棵树。
NLTK 语料库也收集了*中央研究院树库语料*,包括 10,000 句已分析的句子,来自*现代汉语中央研究院平衡语料库*。让我们加载并显示这个语料库中的一棵树。
```py
>>> nltk.corpus.sinica_treebank.parsed_sents()[3450].draw()
......@@ -553,7 +553,7 @@ grammar = nltk.PCFG.fromstring("""
28. ◑ 处理宾州树库语料库样本`nltk.corpus.treebank`中的每棵树,在`Tree.productions()`的帮助下提取产生式。丢弃只出现一次的产生式。具有相同的左侧和类似的右侧的产生式可以被折叠,产生一个等价的却更紧凑的规则集。编写代码输出一个紧凑的语法。
29. ★ 英语中定义句子`S`的主语的一种常见的方法是作为`S` _ 的名词短语孩子 _ 和`VP`的 _ 兄弟 _。写一个函数,以一句话的树为参数,返回句子主语对应的子树。如果传递给这个函数的树的根节点不是`S`或它缺少一个主语,应该怎么做?
29. ★ 英语中定义句子`S`的主语的一种常见的方法是作为`S`*的名词短语孩子*和`VP`的*兄弟*。写一个函数,以一句话的树为参数,返回句子主语对应的子树。如果传递给这个函数的树的根节点不是`S`或它缺少一个主语,应该怎么做?
30. ★ 写一个函数,以一个语法(如[3.1](./ch08.html#code-cfg1)定义的语法)为参数,返回由这个语法随机产生的一个句子。(使用`grammar.start()`找出语法的开始符号;`grammar.productions(lhs)`得到具有指定左侧的语法的产生式的列表;`production.rhs()`得到一个产生式的右侧。)
......
......@@ -12,7 +12,7 @@
## 1 语法特征
[chap-data-intensive](./ch06.html#chap-data-intensive)中,我们描述了如何建立基于检测文本特征的分类器。那些特征可能非常简单,如提取一个单词的最后一个字母,或者更复杂一点儿,如分类器自己预测的词性标签。在本章中,我们将探讨特征在建立基于规则的语法中的作用。对比特征提取,记录已经自动检测到的特征,我们现在要 _ 声明 _ 词和短语的特征。我们以一个很简单的例子开始,使用字典存储特征和它们的值。
[chap-data-intensive](./ch06.html#chap-data-intensive)中,我们描述了如何建立基于检测文本特征的分类器。那些特征可能非常简单,如提取一个单词的最后一个字母,或者更复杂一点儿,如分类器自己预测的词性标签。在本章中,我们将探讨特征在建立基于规则的语法中的作用。对比特征提取,记录已经自动检测到的特征,我们现在要*声明*词和短语的特征。我们以一个很简单的例子开始,使用字典存储特征和它们的值。
```py
>>> kim = {'CAT': 'NP', 'ORTH': 'Kim', 'REF': 'k'}
......@@ -77,7 +77,7 @@ V -> 'runs'
## 1.2 使用属性和约束
我们说过非正式的语言类别具有 _ 属性 _;例如,名词具有复数的属性。让我们把这个弄的更明确:
我们说过非正式的语言类别具有*属性*;例如,名词具有复数的属性。让我们把这个弄的更明确:
```py
N[NUM=pl]
......@@ -159,7 +159,7 @@ V[TENSE=pres, -AUX] -> 'likes'
在传递中,我们应该指出有显示 AVM 的替代方法;[1.3](./ch09.html#fig-avm1)显示了一个例子。虽然特征结构呈现的[(16)](./ch09.html#ex-agr0)中的风格不太悦目,我们将坚持用这种格式,因为它对应我们将会从 NLTK 得到的输出。
关于表示,我们也注意到特征结构,像字典,对特征的 _ 顺序 _ 没有指定特别的意义。所以[(16)](./ch09.html#ex-agr0)等同于︰
关于表示,我们也注意到特征结构,像字典,对特征的*顺序*没有指定特别的意义。所以[(16)](./ch09.html#ex-agr0)等同于︰
```py
[AGR = [NUM = pl ]]
......@@ -183,7 +183,7 @@ NLTK 中的特征结构使用构造函数`FeatStruct()`声明。原子特征值
[ TENSE = 'past' ]
```
一个特征结构实际上只是一种字典,所以我们可以平常的方式通过索引访问它的值。我们可以用我们熟悉的方式 _ 赋 _ 值给特征:
一个特征结构实际上只是一种字典,所以我们可以平常的方式通过索引访问它的值。我们可以用我们熟悉的方式*赋*值给特征:
```py
>>> fs1 = nltk.FeatStruct(PER=3, NUM='pl', GND='fem')
......@@ -720,6 +720,6 @@ In the case of complex values, we say that feature structures are themselves typ
关于本文档...
针对 NLTK 3.0 进行更新。本章来自于 _Natural Language Processing with 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 版一起发行。
针对 NLTK 3.0 进行更新。本章来自于 _Natural Language Processing with 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
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册