所有这些例子都有一个共同的模式:`[w for w in text if *condition* ]`,其中 *condition* 是 Python 中的一个“测试”,得到真或者假。在前面的代码例子所示的情况中,条件始终是数值比较。然而,我们也可以使用表[4.2](http://www.nltk.org/book/ch01.html#tab-word-tests) 中列出的函数测试词汇的各种属性。
所有这些例子都有一个共同的模式:`[w for w in text if *condition* ]`,其中 *condition* 是 Python 中的一个“测试”,得到真或者假。在前面的代码例子所示的情况中,条件始终是数值比较。然而,我们也可以使用表 4.2 中列出的函数测试词汇的各种属性。
你可能已经注意到,我们的一元谓词(即`boy`,`girl`,`dog`)也是以单个元组的集合而不是个体的集合出现的。这使我们能够方便的统一处理任何元数的关系。一个形式为 P(τ[1], ... τ<sub>n</sub>)的谓词,其中 P 是 n 元的,为真的条件是对应于(τ[1], ... τ<sub>n</sub>) 的值的元组属于 P 的值的元组的集合。
不是集中在一种共同的格式,我们认为更有希望开发一种共同的接口(参见`nltk.corpus`)。思考 NLP 中的一个重要的语料类型 treebanks 的情况。将短语结构树存储在一个文件中的方法很多。我们可以使用嵌套的括号、或嵌套的 XML 元素、或每行带有一个(child-id,parent-id)对的依赖符号、或一个 XML 版本的依赖符号等。然而,每种情况中的逻辑结构几乎是相同的。很容易设计一种共同的接口,使应用程序员编写代码使用如`children()`、`leaves()`、`depth()`等方法来访问树数据。注意这种做法来自计算机科学中已经接受的做法,即即抽象数据类型、面向对象设计、三层结构([3.2](./ch11.html#fig-three-layer-arch))。其中的最后一个——来自关系数据库领域——允许终端用户应用程序使用通用的模型(“关系模型”)和通用的语言(SQL)抽象出文件存储的特质,并允许新的文件系统技术的出现,而不会干扰到终端用户的应用。以同样的方式,一个通用的语料库接口将应用程序从数据格式隔离。
不是集中在一种共同的格式,我们认为更有希望开发一种共同的接口(参见`nltk.corpus`)。思考 NLP 中的一个重要的语料类型 treebanks 的情况。将短语结构树存储在一个文件中的方法很多。我们可以使用嵌套的括号、或嵌套的 XML 元素、或每行带有一个(child-id,parent-id)对的依赖符号、或一个 XML 版本的依赖符号等。然而,每种情况中的逻辑结构几乎是相同的。很容易设计一种共同的接口,使应用程序员编写代码使用如`children()`、`leaves()`、`depth()`等方法来访问树数据。注意这种做法来自计算机科学中已经接受的做法,即即抽象数据类型、面向对象设计、三层结构(3.2)。其中的最后一个——来自关系数据库领域——允许终端用户应用程序使用通用的模型(“关系模型”)和通用的语言(SQL)抽象出文件存储的特质,并允许新的文件系统技术的出现,而不会干扰到终端用户的应用。以同样的方式,一个通用的语料库接口将应用程序从数据格式隔离。
函数提供了程序代码打包和重用的有效途径,已经在[3](./ch02.html#sec-reusing-code)中解释过。例如,假设我们发现我们经常要从 HTML 文件读取文本。这包括以下几个步骤,打开文件,将它读入,规范化空白符号,剥离 HTML 标记。我们可以将这些步骤收集到一个函数中,并给它一个名字,如`get_text()`,如[4.2](./ch04.html#code-get-text)所示。
函数提供了程序代码打包和重用的有效途径,已经在[3](./ch02.html#sec-reusing-code)中解释过。例如,假设我们发现我们经常要从 HTML 文件读取文本。这包括以下几个步骤,打开文件,将它读入,规范化空白符号,剥离 HTML 标记。我们可以将这些步骤收集到一个函数中,并给它一个名字,如`get_text()`,如 4.2 所示。
作为递归的最后一个例子,让我们用它来构建一个深嵌套的对象。一个字母查找树是一种可以用来索引词汇的数据结构,一次一个字母。(这个名字来自于单词 retrieval)。例如,如果`trie`包含一个字母的查找树,那么`trie['c']`是一个较小的查找树,包含所有以 c 开头的词。[4.9](./ch04.html#code-trie)演示了使用 Python 字典([3](./ch05.html#sec-dictionaries))构建查找树的递归过程。若要插入词 chien(dog 的法语),我们将 c 分类,递归的掺入 hien 到`trie['c']`子查找树中。递归继续直到词中没有剩余的字母,于是我们存储的了预期值(本例中是词 dog)。
作为递归的最后一个例子,让我们用它来构建一个深嵌套的对象。一个字母查找树是一种可以用来索引词汇的数据结构,一次一个字母。(这个名字来自于单词 retrieval)。例如,如果`trie`包含一个字母的查找树,那么`trie['c']`是一个较小的查找树,包含所有以 c 开头的词。4.9 演示了使用 Python 字典([3](./ch05.html#sec-dictionaries))构建查找树的递归过程。若要插入词 chien(dog 的法语),我们将 c 分类,递归的掺入 hien 到`trie['c']`子查找树中。递归继续直到词中没有剩余的字母,于是我们存储的了预期值(本例中是词 dog)。
在电话簿中,我们用名字查找一个条目得到一个数字。当我们在浏览器中输入一个域名,计算机查找它得到一个 IP 地址。一个词频表允许我们查一个词找出它在一个文本集合中的频率。在所有这些情况中,我们都是从名称映射到数字,而不是其他如列表那样的方式。总之,我们希望能够在任意类型的信息之间映射。[3.1](./ch05.html#tab-linguistic-objects)列出了各种语言学对象以及它们的映射。
在电话簿中,我们用名字查找一个条目得到一个数字。当我们在浏览器中输入一个域名,计算机查找它得到一个 IP 地址。一个词频表允许我们查一个词找出它在一个文本集合中的频率。在所有这些情况中,我们都是从名称映射到数字,而不是其他如列表那样的方式。总之,我们希望能够在任意类型的信息之间映射。3.1 列出了各种语言学对象以及它们的映射。
[3.3](./ch05.html#code-dictionary)中的列表演示了一个重要的按值排序一个字典的习惯用法,来按频率递减顺序显示词汇。`sorted()`的第一个参数是要排序的项目,它是由一个词性标记和一个频率组成的元组的列表。第二个参数使用函数`itemgetter()`指定排序的键。在一般情况下,`itemgetter(n)`返回一个函数,这个函数可以在一些其他序列对象上被调用获得这个序列的第 n 个元素,例如:
3.3 中的列表演示了一个重要的按值排序一个字典的习惯用法,来按频率递减顺序显示词汇。`sorted()`的第一个参数是要排序的项目,它是由一个词性标记和一个频率组成的元组的列表。第二个参数使用函数`itemgetter()`指定排序的键。在一般情况下,`itemgetter(n)`返回一个函数,这个函数可以在一些其他序列对象上被调用获得这个序列的第 n 个元素,例如:
```py
>>>pair=('NP',8336)
...
...
@@ -622,7 +622,7 @@ TypeError: list objects are unhashable
在基于一元处理一个语言处理任务时,我们使用上下文中的一个项目。标注的时候,我们只考虑当前的词符,与更大的上下文隔离。给定一个模型,我们能做的最好的是为每个词标注其*先验的*最可能的标记。这意味着我们将使用相同的标记标注一个词,如 wind,不论它出现的上下文是 the wind 还是 to wind。
在本章开头,我们简要介绍了命名实体(NE)。命名实体是确切的名词短语,指示特定类型的个体,如组织、人、日期等。[5.1](./ch07.html#tab-ne-types)列出了一些较常用的 NE 类型。这些应该是不言自明的,除了“FACILITY”:建筑和土木工程领域的人造产品;以及“GPE”:地缘政治实体,如城市、州/省、国家。
在本章开头,我们简要介绍了命名实体(NE)。命名实体是确切的名词短语,指示特定类型的个体,如组织、人、日期等。5.1 列出了一些较常用的 NE 类型。这些应该是不言自明的,除了“FACILITY”:建筑和土木工程领域的人造产品;以及“GPE”:地缘政治实体,如城市、州/省、国家。
我们可以利用这些数据来帮助开发一个语法。例如,[6.1](./ch08.html#code-sentential-complement)中的程序使用一个简单的过滤器找出带句子补语的动词。假设我们已经有一个形如`VP -> Vs S`的产生式,这个信息使我们能够识别那些包括在`Vs`的扩张中的特别的动词。
我们可以利用这些数据来帮助开发一个语法。例如,6.1 中的程序使用一个简单的过滤器找出带句子补语的动词。假设我们已经有一个形如`VP -> Vs S`的产生式,这个信息使我们能够识别那些包括在`Vs`的扩张中的特别的动词。
[3.1](./ch09.html#code-slashcfg)中的语法包含一个“缺口引进”产生式,即`S[-INV] -> NP S/NP`。为了正确的预填充斜线特征,我们需要为扩展`S`,`VP`和`NP`的产生式中箭头两侧的斜线添加变量值。例如,`VP/?x -> V SBar/?x`是`VP -> V SBar`的斜线版本,也就是说,可以为一个成分的父母`VP`指定斜线值,只要也为孩子`SBar`指定同样的值。最后,`NP/NP ->`允许`NP`上的斜线信息为空字符串。使用[3.1](./ch09.html#code-slashcfg)中的语法,我们可以分析序列 who do you claim that you like
3.1 中的语法包含一个“缺口引进”产生式,即`S[-INV] -> NP S/NP`。为了正确的预填充斜线特征,我们需要为扩展`S`,`VP`和`NP`的产生式中箭头两侧的斜线添加变量值。例如,`VP/?x -> V SBar/?x`是`VP -> V SBar`的斜线版本,也就是说,可以为一个成分的父母`VP`指定斜线值,只要也为孩子`SBar`指定同样的值。最后,`NP/NP ->`允许`NP`上的斜线信息为空字符串。使用 3.1 中的语法,我们可以分析序列 who do you claim that you like
```py
>>>tokens='who do you claim that you like'.split()
@@ -653,7 +653,7 @@ In the case of complex values, we say that feature structures are themselves typ
1. ☼ 需要什么样的限制才能正确分析词序列,如 I am happy 和 she is happy 而不是*you is happy 或*they am happy?实现英语中动词 be 的现在时态范例的两个解决方案,首先以语法[(6)](./ch09.html#ex-agcfg1)作为起点,然后以语法 [(18)](./ch09.html#ex-agr2)为起点。