提交 37f75b0b 编写于 作者: W wizardforcel

2020-11-21 11:21:25

上级 ff575ad5
......@@ -104,7 +104,7 @@ equivalence <->
True
```
这里有另一种方式可以看到结论如何得出。`SnF -&gt; -FnS`在语义上等价于`-SnF | -FnS`,其中 "`|`"是对应于 or 的二元运算符。在一般情况下,φ`|`ψ在条件 _s_ 中为真,要么φ在 _s_ 中为真,要么ψ在 _s_ 中为真。现在,假设`SnF``-SnF | -FnS`都在 _s_ 中为真。如果`SnF`为真,那么`-SnF`不可能也为真;经典逻辑的一个基本假设是:一个句子在一种情况下不能同时为真和为假。因此,`-FnS`必须为真。
这里有另一种方式可以看到结论如何得出。`SnF -&gt; -FnS`在语义上等价于`-SnF | -FnS`,其中 "`|`"是对应于 or 的二元运算符。在一般情况下,φ`|`ψ在条件 *s* 中为真,要么φ在 *s* 中为真,要么ψ在 *s* 中为真。现在,假设`SnF``-SnF | -FnS`都在 *s* 中为真。如果`SnF`为真,那么`-SnF`不可能也为真;经典逻辑的一个基本假设是:一个句子在一种情况下不能同时为真和为假。因此,`-FnS`必须为真。
回想一下,我们解释相对于一个模型的一种逻辑语言的句子,它们是这个世界的一个非常简化的版本。一个命题逻辑的模型需要为每个可能的公式分配值`True``False`。我们一步步的来做这个:首先,为每个命题符号分配一个值,然后确定布尔运算符的含义(即[2.1](./ch10.html#tab-boolean-tcs))和运用它们到这些公式的组件的值,来计算复杂的公式的值。`估值`是从逻辑的基本符号映射到它们的值。下面是一个例子:
......@@ -185,7 +185,7 @@ e
一种二元谓词具有类型〈e, 〈e, t〉〉。虽然这是先组合类型 e 的一个参数成一个一元谓词的类型,我们可以用二元谓词的两个参数直接组合来表示二元谓词。例如,在&lt;cite&gt;Angus sees Cyril&lt;/cite&gt;的翻译中谓词 see 会与它的参数结合得到结果 see(angus, cyril)。
在一阶逻辑中,谓词的参数也可以是独立变量,如 x,y 和 z。在 NLTK 中,我们采用的惯例:_e_ 类型的变量都是小写。独立变量类似于人称代词,如 he,she 和 it ,其中我们为了弄清楚它们的含义需要知道它们使用的上下文。
在一阶逻辑中,谓词的参数也可以是独立变量,如 x,y 和 z。在 NLTK 中,我们采用的惯例:*e* 类型的变量都是小写。独立变量类似于人称代词,如 he,she 和 it ,其中我们为了弄清楚它们的含义需要知道它们使用的上下文。
解释[(14)](./ch10.html#ex-predlog2)中的代名词的方法之一是指向上下文中相关的个体。
......@@ -343,7 +343,7 @@ True
True
```
在这里`evaluate()``True`,因为`dom`中有某些 _u_ 通过绑定`x`到 _u_ 的赋值满足([(25)](./ch10.html#ex-exists2) )。事实上,`o`是这样一个 _u_
在这里`evaluate()``True`,因为`dom`中有某些 *u* 通过绑定`x`*u* 的赋值满足([(25)](./ch10.html#ex-exists2) )。事实上,`o`是这样一个 *u*
```py
>>> m.evaluate('girl(x) & walk(x)', g.add('x', 'o'))
......@@ -371,7 +371,7 @@ NLTK 中提供了一个有用的工具是`satisfiers()`方法。它返回满足
True
```
换句话说,一个全称量化公式∀x.φ关于`g`为真,只有对每一个 _u_,φ关于`g[u/x]`为真。
换句话说,一个全称量化公式∀x.φ关于`g`为真,只有对每一个 *u*,φ关于`g[u/x]`为真。
注意
......@@ -538,7 +538,7 @@ set()
(dog(cyril) & own(angus,cyril))
```
我们所有的λ-抽象到目前为止只涉及熟悉的一阶变量:`x``y`等——类型 _e_ 的变量。但假设我们要处理一个抽象,例如`\x.walk(x)`作为另一个λ-抽象的参数?我们不妨试试这个:
我们所有的λ-抽象到目前为止只涉及熟悉的一阶变量:`x``y`等——类型 *e* 的变量。但假设我们要处理一个抽象,例如`\x.walk(x)`作为另一个λ-抽象的参数?我们不妨试试这个:
```py
\y.y(angus)(\x.walk(x))
......@@ -588,7 +588,7 @@ exists z1.see(z1,x)
all z2.(dog(z2) -> exists z1.(bone(z1) & give(angus,z1,z2)))
```
NLTK 提供一些实用工具使获得和检查的语义解释更容易。函数`interpret_sents()`用于批量解释输入句子的列表。它建立一个字典`d`,其中对每个输入的句子`sent``d[sent]`是包含`sent`的分析树和语义表示的(_synrep_, _semrep_)对的列表。该值是一个列表,因为`sent`可能有句法歧义;在下面的例子中,列表中的每个句子只有一个分析树。
NLTK 提供一些实用工具使获得和检查的语义解释更容易。函数`interpret_sents()`用于批量解释输入句子的列表。它建立一个字典`d`,其中对每个输入的句子`sent``d[sent]`是包含`sent`的分析树和语义表示的(_synrep_, *semrep*)对的列表。该值是一个列表,因为`sent`可能有句法歧义;在下面的例子中,列表中的每个句子只有一个分析树。
```py
>>> sents = ['Irene walks', 'Cyril bites an ankle']
......@@ -612,7 +612,7 @@ NLTK 提供一些实用工具使获得和检查的语义解释更容易。函数
(N[NUM='sg', SEM=<\x.ankle(x)>] ankle)))))
```
现在我们已经看到了英文句子如何转换成逻辑形式,前面我们看到了在模型中如何检查逻辑形式的真假。把这两个映射放在一起,我们可以检查一个给定的模型中的英语句子的真值。让我们看看前面定义的模型`m`。工具`evaluate_sents()`类似于`interpret_sents()`,除了我们需要传递一个模型和一个变量赋值作为参数。输出是三元组(_synrep_, _semrep_, _value_),其中 _synrep_、_semrep_ 和以前一样,_value_ 是真值。为简单起见,下面的例子只处理一个简单的句子。
现在我们已经看到了英文句子如何转换成逻辑形式,前面我们看到了在模型中如何检查逻辑形式的真假。把这两个映射放在一起,我们可以检查一个给定的模型中的英语句子的真值。让我们看看前面定义的模型`m`。工具`evaluate_sents()`类似于`interpret_sents()`,除了我们需要传递一个模型和一个变量赋值作为参数。输出是三元组(_synrep_, *semrep*, *value*),其中 *synrep**semrep* 和以前一样,*value* 是真值。为简单起见,下面的例子只处理一个简单的句子。
```py
>>> v = """
......@@ -834,12 +834,12 @@ d1: ['s0-r1', 's1-r0'] : ([z12,z15],[boy(z12), (([x],[dog(x)]) ->
* 在将自然语言句子翻译成一阶逻辑的同时,我们可以通过检查一阶公式模型表述这些句子的真值条件。
* 为了构建成分组合的意思表示,我们为一阶逻辑补充了λ-演算。
* λ-演算中的β-约简在语义上与函数传递参数对应。句法上,它包括将被函数表达式中的λ绑定的变量替换为函数应用中表达式提供的参数。
* 构建模型的一个关键部分在于建立估值,为非逻辑常量分配解释。这些被解释为 _n_ 元谓词或独立常量。
* 构建模型的一个关键部分在于建立估值,为非逻辑常量分配解释。这些被解释为 *n* 元谓词或独立常量。
* 一个开放表达式是一个包含一个或多个自由变量的表达式。开放表达式只在它的自由变量被赋值时被解释。
* 量词的解释是对于具有变量 x 的公式φ[x],构建个体的集合,赋值 _g_ 分配它们作为 x 的值使φ[x]为真。然后量词对这个集合加以约束。
* 量词的解释是对于具有变量 x 的公式φ[x],构建个体的集合,赋值 *g* 分配它们作为 x 的值使φ[x]为真。然后量词对这个集合加以约束。
* 一个封闭的表达式是一个没有自由变量的表达式;也就是,变量都被绑定。一个封闭的表达式是真是假取决于所有变量赋值。
* 如果两个公式只是由绑定操作符(即λ或量词)绑定的变量的标签不同,那么它们是α-等价。重新标记公式中的绑定变量的结果被称为α-转换。
* 给定有两个嵌套量词 _Q_&lt;sub&gt;1&lt;/sub&gt;和 _Q_&lt;sub&gt;2&lt;/sub&gt;的公式,最外层的量词 _Q_&lt;sub&gt;1&lt;/sub&gt;有较广的范围(或范围超出 _Q_&lt;sub&gt;2&lt;/sub&gt;)。英语句子往往由于它们包含的量词的范围而产生歧义。
* 给定有两个嵌套量词 *Q*&lt;sub&gt;1&lt;/sub&gt;*Q*&lt;sub&gt;2&lt;/sub&gt;的公式,最外层的量词 *Q*&lt;sub&gt;1&lt;/sub&gt;有较广的范围(或范围超出 *Q*&lt;sub&gt;2&lt;/sub&gt;)。英语句子往往由于它们包含的量词的范围而产生歧义。
* 在基于特征的语法中英语句子可以通过将`sem`作为特征与语义表达关联。一个复杂的表达式的`sem`值通常包括成分表达式的`sem`值的函数应用。
## 7 深入阅读
......@@ -980,7 +980,7 @@ d1: ['s0-r1', 's1-r0'] : ([z12,z15],[boy(z12), (([x],[dog(x)]) ->
all x.(dog(x) -&gt; bark(x))
```
8. ◑ 开发一种方法,翻译英语句子为带有二元广义量词的公式。在此方法中,给定广义量词`Q`,量化公式的形式为`Q(A, B)`,其中`A``B`是〈_e_, _t_〉类型的表达式。那么,例如`all(A, B)`为真当且仅当`A`表示的是`B`所表示的一个子集。
8. ◑ 开发一种方法,翻译英语句子为带有二元广义量词的公式。在此方法中,给定广义量词`Q`,量化公式的形式为`Q(A, B)`,其中`A``B`是〈_e_, *t*〉类型的表达式。那么,例如`all(A, B)`为真当且仅当`A`表示的是`B`所表示的一个子集。
9. ◑ 扩展前面练习中的方法,使量词如 most 和 exactly three 的真值条件可以在模型中计算。
......
......@@ -150,7 +150,7 @@ Kappa 系数 K 测量两个人判断类别和修正预期的期望一致性的
最简单的方法是获得出版的网页文本的文集。Web 语料库 ACL 特别兴趣组(SIGWAC)在`http://www.sigwac.org.uk/`维护一个资源列表。使用定义好的 Web 语料库的优点是它们有文档、稳定并允许重复性实验。
如果所需的内容在一个特定的网站,有许多实用程序能捕获网站的所有可访问内容,如 _GNU Wget_ `http://www.gnu.org/software/wget/`。For maximal flexibility and control, a web crawler can be used, such as _Heritrix_ `http://crawler.archive.org/`. 为了最大的灵活性和可控制,可以使用网络爬虫如[(Croft, Metzler, & Strohman, 2009)](./bibliography.html#croft2009)。例如:如果我们要编译双语文本集合,对应两种语言的文档对,爬虫需要检测站点的结构以提取文件之间的对应关系,它需要按照捕获的对应方式组织下载的页面。写你自己的网页爬虫可能使很有诱惑力的,但也有很多陷阱需要克服,如检测 MIME 类型、转换相对地址为绝对 URL、避免被困在循环链接结构、处理网络延迟、避免使站点超载或被禁止访问该网站等。
如果所需的内容在一个特定的网站,有许多实用程序能捕获网站的所有可访问内容,如 _GNU Wget_ `http://www.gnu.org/software/wget/`。For maximal flexibility and control, a web crawler can be used, such as *Heritrix* `http://crawler.archive.org/`. 为了最大的灵活性和可控制,可以使用网络爬虫如[(Croft, Metzler, & Strohman, 2009)](./bibliography.html#croft2009)。例如:如果我们要编译双语文本集合,对应两种语言的文档对,爬虫需要检测站点的结构以提取文件之间的对应关系,它需要按照捕获的对应方式组织下载的页面。写你自己的网页爬虫可能使很有诱惑力的,但也有很多陷阱需要克服,如检测 MIME 类型、转换相对地址为绝对 URL、避免被困在循环链接结构、处理网络延迟、避免使站点超载或被禁止访问该网站等。
## 3.2 从字处理器文件获取数据
......@@ -266,7 +266,7 @@ sleep: wake
* 浅层语义:命名实体和共指标注,语义角色标签。
* 对话与段落:对话行为标记,修辞结构
不幸的是,现有的语料库之间在如何表示标注上并没有多少一致性。然而,两个大类的标注表示应加以区别。内联标注通过插入带有标注信息的特殊符号或控制序列修改原始文档。例如,为文档标注词性时,字符串`"fly"`可能被替换为字符串`"fly/NN"`来表示词 _fly_ 在文中是名词。相比之下,对峙标注不修改原始文档,而是创建一个新的文档,通过使用指针引用原始文档来增加标注信息。例如,这个新的文档可能包含字符串`"&lt;token id=8 pos='NN'/&gt;"`,表示 8 号词符是一个名词。(我们希望可以确保的分词本身不会变化,因为它会导致默默损坏这种引用。)
不幸的是,现有的语料库之间在如何表示标注上并没有多少一致性。然而,两个大类的标注表示应加以区别。内联标注通过插入带有标注信息的特殊符号或控制序列修改原始文档。例如,为文档标注词性时,字符串`"fly"`可能被替换为字符串`"fly/NN"`来表示词 *fly* 在文中是名词。相比之下,对峙标注不修改原始文档,而是创建一个新的文档,通过使用指针引用原始文档来增加标注信息。例如,这个新的文档可能包含字符串`"&lt;token id=8 pos='NN'/&gt;"`,表示 8 号词符是一个名词。(我们希望可以确保的分词本身不会变化,因为它会导致默默损坏这种引用。)
## 3.6 标准和工具
......@@ -778,7 +778,7 @@ Rotokas 数据由 Stuart Robinson 提供,勉方言数据由 Greg Aumann 提供
13. ★ 获取 CSV 格式的比较词表,写一个程序,输出相互之间至少有三个编辑距离的同源词。
14. ★ 建立一个出现在例句的词位的索引。假设对于一个给定条目的词位是 _w_。然后为这个条目添加一个单独的交叉引用字段`xrf`,引用其它有例句包含 _w_ 的条目的中心词。对所有条目做这个,结果保存为 Toolbox 格式文件。
14. ★ 建立一个出现在例句的词位的索引。假设对于一个给定条目的词位是 *w*。然后为这个条目添加一个单独的交叉引用字段`xrf`,引用其它有例句包含 *w* 的条目的中心词。对所有条目做这个,结果保存为 Toolbox 格式文件。
15. ◑ 写一个递归函数将任意树转换为对应的 XML,其中非终结符不能表示成 XML 元素,叶子表示文本内容,如:
......
......@@ -17,7 +17,7 @@ d. Iraqi Head Seeks Arms (spoof news headline)
e. The earnest prayer of a righteous man has great power and wonderful results. (James 5:16b)
f. Twas brillig, and the slithy toves did gyre and gimble in the wabe (Lewis Carroll, _Jabberwocky_, 1872)
f. Twas brillig, and the slithy toves did gyre and gimble in the wabe (Lewis Carroll, *Jabberwocky*, 1872)
g. There are two ways to do this, AFAIK :smile: (internet discussion archive)
```
......
......@@ -904,7 +904,7 @@ KeyError: 'blog'
## 4.4 词汇工具:Shoebox 和 Toolbox
可能最流行的语言学家用来管理数据的工具是 _Toolbox_,以前叫做 _Shoebox_,因为它用满满的档案卡片占据了语言学家的旧鞋盒。Toolbox 可以免费从`http://www.sil.org/computing/toolbox/`下载。
可能最流行的语言学家用来管理数据的工具是 *Toolbox*,以前叫做 *Shoebox*,因为它用满满的档案卡片占据了语言学家的旧鞋盒。Toolbox 可以免费从`http://www.sil.org/computing/toolbox/`下载。
一个 Toolbox 文件由一个大量条目的集合组成,其中每个条目由一个或多个字段组成。大多数字段都是可选的或重复的,这意味着这个词汇资源不能作为一个表格或电子表格来处理。
......@@ -1206,10 +1206,10 @@ WordNet 原始描述是[(Fellbaum, 1998)](./bibliography.html#fellbaum1998)。
4. ☼ 使用`state_union`语料库阅读器,访问《国情咨文报告》的文本。计数每个文档中出现的`men``women``people`。随时间的推移这些词的用法有什么变化?
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’”。
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))。
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_
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. ◑ 调查模式分布表,寻找其他模式。试着用你自己对不同文体的印象理解来解释它们。你能找到其他封闭的词汇归类,展现不同文体的显著差异吗?
12. ◑ CMU 发音词典包含某些词的多个发音。它包含多少种不同的词?具有多个可能的发音的词在这个词典中的比例是多少?
13. ◑ 没有下位词的名词同义词集所占的百分比是多少?你可以使用`wn.all_synsets('n')`得到所有名词同义词集。
......@@ -1222,16 +1222,16 @@ WordNet 原始描述是[(Fellbaum, 1998)](./bibliography.html#fellbaum1998)。
20. ◑ 写一个函数`word_freq()`,用一个词和布朗语料库中的一个部分的名字作为参数,计算这部分语料中词的频率。
21. ◑ 写一个程序,估算一个文本中的音节数,利用 CMU 发音词典。
22. ◑ 定义一个函数`hedge(text)`,处理一个文本和产生一个新的版本在每三个词之间插入一个词`'like'`
23.**齐夫定律**:_f(w)_ 是一个自由文本中的词 _w_ 的频率。假设一个文本中的所有词都按照它们的频率排名,频率最高的在最前面。齐夫定律指出一个词类型的频率与它的排名成反比(即 _f_ × _r = k_,_k_ 是某个常数)。例如:最常见的第 50 个词类型出现的频率应该是最常见的第 150 个词型出现频率的 3 倍。
23.**齐夫定律**:_f(w)_ 是一个自由文本中的词 *w* 的频率。假设一个文本中的所有词都按照它们的频率排名,频率最高的在最前面。齐夫定律指出一个词类型的频率与它的排名成反比(即 *f* × _r = k_,*k* 是某个常数)。例如:最常见的第 50 个词类型出现的频率应该是最常见的第 150 个词型出现频率的 3 倍。
1. 写一个函数来处理一个大文本,使用`pylab.plot`画出相对于词的排名的词的频率。你认可齐夫定律吗?(提示:使用对数刻度会有帮助。)所绘的线的极端情况是怎样的?
2. 随机生成文本,如使用`random.choice("abcdefg ")`,注意要包括空格字符。你需要事先`import random`。使用字符串连接操作将字符累积成一个很长的字符串。然后为这个字符串分词,产生前面的齐夫图,比较这两个图。此时你怎么看齐夫定律?
24. ★ 修改例[2.2](./ch02.html#code-random-text)的文本生成程序,进一步完成下列任务:
1. 在一个列表`words`中存储 _n_ 个最相似的词,使用`random.choice()`从列表中随机选取一个词。(你将需要事先`import random`。)
1. 在一个列表`words`中存储 *n* 个最相似的词,使用`random.choice()`从列表中随机选取一个词。(你将需要事先`import random`。)
2. 选择特定的文体,如布朗语料库中的一部分或者《创世纪》翻译或者古腾堡语料库中的文本或者一个网络文本。在此语料上训练一个模型,产生随机文本。你可能要实验不同的起始字。文本的可理解性如何?讨论这种方法产生随机文本的长处和短处。
3. 现在使用两种不同文体训练你的系统,使用混合文体文本做实验。讨论你的观察结果。
25. ★ 定义一个函数`find_language()`,用一个字符串作为其参数,返回包含这个字符串作为词汇的语言的列表。使用《世界人权宣言》`udhr`的语料,将你的搜索限制在 Latin-1 编码的文件中。
26. ★ 名词上位词层次的分枝因素是什么?也就是说,对于每一个具有下位词——上位词层次中的子女——的名词同义词集,它们平均有几个下位词?你可以使用`wn.all_synsets('n')`获得所有名词同义词集。
27. ★ 一个词的多义性是它所有含义的个数。利用 WordNet,使用`len(wn.synsets('dog', 'n'))`我们可以判断名词 _dog_ 有 7 种含义。计算 WordNet 中名词、动词、形容词和副词的平均多义性。
27. ★ 一个词的多义性是它所有含义的个数。利用 WordNet,使用`len(wn.synsets('dog', 'n'))`我们可以判断名词 *dog* 有 7 种含义。计算 WordNet 中名词、动词、形容词和副词的平均多义性。
28. ★使用预定义的相似性度量之一给下面的每个词对的相似性打分。按相似性减少的顺序排名。你的排名与这里给出的顺序有多接近?[(Miller & Charles, 1998)](./bibliography.html#millercharles1998)实验得出的顺序: car-automobile, gem-jewel, journey-voyage, boy-lad, coast-shore, asylum-madhouse, magician-wizard, midday-noon, furnace-stove, food-fruit, bird-cock, bird-crane, tool-implement, brother-monk, lad-brother, crane-implement, journey-car, monk-oracle, cemetery-woodland, food-rooster, coast-hill, forest-graveyard, shore-woodland, monk-slave, coast-forest, lad-wizard, chord-smile, glass-magician, rooster-voyage, noon-string。
关于本文档...
......
......@@ -110,7 +110,7 @@ Project Gutenberg; Dmitri Prokofitch; Andrey Semyonovitch; Hay Market
你可以输入`print(html)`来查看 HTML 的全部内容,包括 meta 元标签、图像标签、map 标签、JavaScript、表单和表格。
要得到 HTML 的文本,我们将使用一个名为 _BeautifulSoup_ 的 Python 库,可从 `http://www.crummy.com/software/BeautifulSoup/` 访问︰
要得到 HTML 的文本,我们将使用一个名为 *BeautifulSoup* 的 Python 库,可从 `http://www.crummy.com/software/BeautifulSoup/` 访问︰
```py
>>> from bs4 import BeautifulSoup
......@@ -140,7 +140,7 @@ des would disappear is if having the gene was a disadvantage and I do not thin
表 3.1:
搭配的谷歌命中次数:absolutely 或 definitely 后面跟着 adore, love, like 或 prefer 的搭配的命中次数。(Liberman, in _LanguageLog_, 2005)。
搭配的谷歌命中次数:absolutely 或 definitely 后面跟着 adore, love, like 或 prefer 的搭配的命中次数。(Liberman, in *LanguageLog*, 2005)。
```py
>>> import feedparser
......@@ -176,7 +176,7 @@ des would disappear is if having the gene was a disadvantage and I do not thin
注意
**轮到你来:** 使用文本编辑器创建一个名为`document.txt`的文件,然后输入几行文字,保存为纯文本。如果你使用 IDLE,在 _File_ 菜单中选择 _New Window_ 命令,在新窗口中输入所需的文本,然后在 IDLE 提供的弹出式对话框中的文件夹内保存文件为`document.txt`。然后在 Python 解释器中使用`f = open('document.txt')`打开这个文件,并使用`print(f.read())`检查其内容。
**轮到你来:** 使用文本编辑器创建一个名为`document.txt`的文件,然后输入几行文字,保存为纯文本。如果你使用 IDLE,在 *File* 菜单中选择 _New Window_ 命令,在新窗口中输入所需的文本,然后在 IDLE 提供的弹出式对话框中的文件夹内保存文件为`document.txt`。然后在 Python 解释器中使用`f = open('document.txt')`打开这个文件,并使用`print(f.read())`检查其内容。
当你尝试这样做时可能会出各种各样的错误。如果解释器无法找到你的文件,你会看到类似这样的错误:
......@@ -188,7 +188,7 @@ f = open('document.txt')
IOError: [Errno 2] No such file or directory: 'document.txt'
```
要检查你正试图打开的文件是否在正确的目录中,使用 IDLE _File_ 菜单上的 _Open_ 命令;另一种方法是在 Python 中检查当前目录:
要检查你正试图打开的文件是否在正确的目录中,使用 IDLE *File* 菜单上的 *Open* 命令;另一种方法是在 Python 中检查当前目录:
```py
>>> import os
......@@ -204,7 +204,7 @@ IOError: [Errno 2] No such file or directory: 'document.txt'
'Time flies like an arrow.\nFruit flies like a banana.\n'
```
回想一`'\n'`字符是换行符;这相当于按键盘上的 _Enter_ 开始一个新行。
回想一`'\n'`字符是换行符;这相当于按键盘上的 *Enter* 开始一个新行。
我们也可以使用一个`for`循环一次读文件中的一行:
......@@ -564,7 +564,7 @@ TypeError: object does not support item assignment
### 什么是 Unicode?
Unicode 支持超过一百万种字符。每个字符分配一个编号,称为编码点。在 Python 中,编码点写作`\u`_XXXX_ 的形式,其中 _XXXX_ 是四位十六进制形式数。
Unicode 支持超过一百万种字符。每个字符分配一个编号,称为编码点。在 Python 中,编码点写作`\u`*XXXX* 的形式,其中 *XXXX* 是四位十六进制形式数。
在一个程序中,我们可以像普通字符串那样操纵 Unicode 字符串。然而,当 Unicode 字符被存储在文件或在终端上显示,它们必须被编码为字节流。一些编码(如 ASCII 和 Latin-2)中每个编码点使用单字节,所以它们可以只支持 Unicode 的一个小的子集,足够单个语言使用了。其它的编码(如 UTF-8)使用多个字节,可以表示全部的 Unicode 字符。
......@@ -599,7 +599,7 @@ Jagiellońskiej w Krakowie, obejmują ponad 500 tys. zabytkowych
archiwaliów, m.in. manuskrypty Goethego, Mozarta, Beethovena, Bacha.
```
如果这不能在你的终端正确显示,或者我们想要看到字符的底层数值(或"代码点"),那么我们可以将所有的非 ASCII 字符转换成它们两位数`\x`_XX_ 和四位数 `\u`_XXXX_ 表示法︰
如果这不能在你的终端正确显示,或者我们想要看到字符的底层数值(或"代码点"),那么我们可以将所有的非 ASCII 字符转换成它们两位数`\x`*XX* 和四位数 `\u`*XXXX* 表示法︰
```py
>>> f = open(path, encoding='latin2')
......@@ -616,7 +616,7 @@ b'archiwali\\xf3w, m.in. manuskrypty Goethego, Mozarta, Beethovena, Bacha.'
上面输出的第一行有一个以`\u`转义字符串开始的 Unicode 转义字符串,即`\u0144`。相关的 Unicode 字符在屏幕上将显示为字形ń。在前面例子中的第三行中,我们看到`\xf3`,对应字形为ó,在 128-255 的范围内。
在 Python 3 中,源代码默认使用 UTF-8 编码,如果你使用的 IDLE 或另一个支持 Unicode 的程序编辑器,你可以在字符串中包含 Unicode 字符。可以使用`\u`_XXXX_ 转义序列包含任意的 Unicode 字符。我们使用`ord()`找到一个字符的整数序数。例如︰
在 Python 3 中,源代码默认使用 UTF-8 编码,如果你使用的 IDLE 或另一个支持 Unicode 的程序编辑器,你可以在字符串中包含 Unicode 字符。可以使用`\u`*XXXX* 转义序列包含任意的 Unicode 字符。我们使用`ord()`找到一个字符的整数序数。例如︰
```py
>>> ord('ń')
......@@ -867,7 +867,7 @@ t 47 8 0 148 37
v 93 27 105 48 49
```
考查 s 行和 t 行,我们看到它们是部分的“互补分布”,这个证据表明它们不是这种语言中的独特音素。从而我们可以令人信服的从罗托卡特语字母表中去除 s,简单加入一个发音规则:当字母 t 跟在 i 后面时发 s 的音。(注意单独的条目 _su_ 即 _kasuari_,‘cassowary’是从英语中借来的)。
考查 s 行和 t 行,我们看到它们是部分的“互补分布”,这个证据表明它们不是这种语言中的独特音素。从而我们可以令人信服的从罗托卡特语字母表中去除 s,简单加入一个发音规则:当字母 t 跟在 i 后面时发 s 的音。(注意单独的条目 *su* 即 *kasuari*,‘cassowary’是从英语中借来的)。
如果我们想要检查表格中数字背后的词汇,有一个索引允许我们迅速找到包含一个给定的辅音-元音对的单词的列表将会有帮助,例如,`cv_index['su']`应该给我们所有含有 su 的词汇。下面是我们如何能做到这一点:
......@@ -983,7 +983,7 @@ la la; lovely lol lol love; lol lol lol.; la la la; la la la
注意
**轮到你来:**巩固你对正则表达式模式与替换的理解,使用`nltk.re_show(`_p, s_`)`,它能标注字符串 _s_ 中所有匹配模式 _p_ 的地方,以及`nltk.app.nemo()`,它能提供一个探索正则表达式的图形界面。更多的练习,可以尝试本章尾的正则表达式的一些练习。
**轮到你来:**巩固你对正则表达式模式与替换的理解,使用`nltk.re_show(`_p, s_`)`,它能标注字符串 *s* 中所有匹配模式 *p* 的地方,以及`nltk.app.nemo()`,它能提供一个探索正则表达式的图形界面。更多的练习,可以尝试本章尾的正则表达式的一些练习。
当我们研究的语言现象与特定词语相关时建立搜索模式是很容易的。在某些情况下,一个小小的创意可能会花很大功夫。例如,在大型文本语料库中搜索 x and other ys 形式的表达式能让我们发现上位词(见[5](./ch02.html#sec-wordnet)):
......@@ -1680,7 +1680,7 @@ SIGHAN,ACL 中文语言处理特别兴趣小组`http://sighan.org/`,重点
23. ◑ 你能写一个正则表达式以这样的方式来分词吗,将词 don't 分为 do 和 n't?解释为什么这个正则表达式无法正常工作:«`n't|\w+`»。
24. ◑ 尝试编写代码将文本转换成 _hAck3r_,使用正则表达式和替换,其中`e``3`, `i``1`, `o``0`, `l``|`, `s``5`, `.``5w33t!`, `ate``8`。在转换之前将文本规范化为小写。自己添加更多的替换。现在尝试将`s`映射到两个不同的值:词开头的`s`映射为`
24. ◑ 尝试编写代码将文本转换成 *hAck3r*,使用正则表达式和替换,其中`e``3`, `i``1`, `o``0`, `l``|`, `s``5`, `.``5w33t!`, `ate``8`。在转换之前将文本规范化为小写。自己添加更多的替换。现在尝试将`s`映射到两个不同的值:词开头的`s`映射为`
25. ◑ _Pig Latin_ 是英语文本的一个简单的变换。文本中每个词的按如下方式变换:将出现在词首的所有辅音(或辅音群)移到词尾,然后添加 ay,例如 string → ingstray, idle → idleay。`http://en.wikipedia.org/wiki/Pig_Latin`
......@@ -1723,7 +1723,7 @@ SIGHAN,ACL 中文语言处理特别兴趣小组`http://sighan.org/`,重点
1. 写一个正则表达式,识别连字符连结的跨行处的词汇。这个表达式将需要包含`\n`字符。
2. 使用`re.sub()`从这些词中删除`\n`字符。
3. 你如何确定一旦换行符被删除后不应该保留连字符的词汇,如`'encyclo-\npedia'`?
39. ★ 阅读维基百科 _Soundex_ 条目。用 Python 实现这个算法。
39. ★ 阅读维基百科 *Soundex* 条目。用 Python 实现这个算法。
40. ★ 获取两个或多个文体的原始文本,计算它们各自的在前面关于阅读难度的练习中描述的阅读难度得分。例如,比较 ABC 农村新闻和 ABC 科学新闻(`nltk.corpus.abc`)。使用 Punkt 处理句子分割。
......
......@@ -451,7 +451,7 @@ True
确保循环变量范围的正确相当棘手的。因为这是 NLP 中的常见操作,NLTK 提供了支持函数`bigrams(text)``trigrams(text)`和一个更通用的`ngrams(text, n)`
下面是我们如何使用循环变量构建多维结构的一个例子。例如,建立一个 _m_ 行 _n_ 列的数组,其中每个元素是一个集合,我们可以使用一个嵌套的列表推导:
下面是我们如何使用循环变量构建多维结构的一个例子。例如,建立一个 *m**n* 列的数组,其中每个元素是一个集合,我们可以使用一个嵌套的列表推导:
```py
>>> m, n = 3, 7
......@@ -1061,7 +1061,7 @@ result = ['cat']
解决算法问题的一个重要部分是为手头的问题选择或改造一个合适的算法。有时会有几种选择,能否选择最好的一个取决于对每个选择随数据增长如何执行的知识。关于这个话题的书很多,我们只介绍一些关键概念和精心描述在自然语言处理中最普遍的做法。
最有名的策略被称为分而治之。我们解决一个大小为 _n_ 的问题通过将其分成两个大小为 _n/2_ 的问题,解决这些问题,组合它们的结果成为原问题的结果。例如,假设我们有一堆卡片,每张卡片上写了一个词。我们可以排序这一堆卡片,通过将它分成两半分别给另外两个人来排序(他们又可以做同样的事情)。然后,得到两个排好序的卡片堆,将它们并成一个单一的排序堆就是一项容易的任务了。参见[4.8](./ch04.html#fig-mergesort)这个过程的说明。
最有名的策略被称为分而治之。我们解决一个大小为 *n* 的问题通过将其分成两个大小为 _n/2_ 的问题,解决这些问题,组合它们的结果成为原问题的结果。例如,假设我们有一堆卡片,每张卡片上写了一个词。我们可以排序这一堆卡片,通过将它分成两半分别给另外两个人来排序(他们又可以做同样的事情)。然后,得到两个排好序的卡片堆,将它们并成一个单一的排序堆就是一项容易的任务了。参见[4.8](./ch04.html#fig-mergesort)这个过程的说明。
![Images/mergesort.png](Images/1094084b61ac3f0e4416e92869c52ccd.jpg)
......@@ -1209,7 +1209,7 @@ def preprocess(tagged_corpus):
动态规划是一种自然语言处理中被广泛使用的算法设计的一般方法。“programming”一词的用法与你可能想到的感觉不同,是规划或调度的意思。动态规划用于解决包含多个重叠的子问题的问题。不是反复计算这些子问题,而是简单的将它们的计算结果存储在一个查找表中。在本节的余下部分,我们将介绍动态规划,在一个相当不同的背景下来句法分析。
Pingala 是大约生活在公元前 5 世纪的印度作家,作品有被称为《Chandas Shastra》的梵文韵律专著。Virahanka 大约在公元 6 世纪延续了这项工作,研究短音节和长音节组合产生一个长度为 _n_ 的旋律的组合数。短音节,标记为 _S_,占一个长度单位,而长音节,标记为 _L_,占 2 个长度单位。例如,Pingala 发现,有 5 种方式构造一个长度为 4 的旋律:_V_&lt;sub&gt;4&lt;/sub&gt; = _{LL, SSL, SLS, LSS, SSSS}_。请看,我们可以将 _V_&lt;sub&gt;4&lt;/sub&gt;分成两个子集,以 _L_ 开始的子集和以 _S_ 开始的子集,如[(1)](./ch04.html#ex-v4)所示。
Pingala 是大约生活在公元前 5 世纪的印度作家,作品有被称为《Chandas Shastra》的梵文韵律专著。Virahanka 大约在公元 6 世纪延续了这项工作,研究短音节和长音节组合产生一个长度为 *n* 的旋律的组合数。短音节,标记为 *S*,占一个长度单位,而长音节,标记为 *L*,占 2 个长度单位。例如,Pingala 发现,有 5 种方式构造一个长度为 4 的旋律:_V_&lt;sub&gt;4&lt;/sub&gt; = _{LL, SSL, SLS, LSS, SSSS}_。请看,我们可以将 *V*&lt;sub&gt;4&lt;/sub&gt;分成两个子集,以 *L* 开始的子集和以 *S* 开始的子集,如[(1)](./ch04.html#ex-v4)所示。
```py
V4 =
......@@ -1220,7 +1220,7 @@ V4 =
```
有了这个观察结果,我们可以写一个小的递归函数称为`virahanka1()`来计算这些旋律,如[4.12](./ch04.html#code-virahanka)所示。请注意,要计算 _V_&lt;sub&gt;4&lt;/sub&gt;,我们先要计算 _V_&lt;sub&gt;3&lt;/sub&gt;和 _V_&lt;sub&gt;2&lt;/sub&gt;。但要计算 _V_&lt;sub&gt;3&lt;/sub&gt;,我们先要计算 _V_&lt;sub&gt;2&lt;/sub&gt;和 _V_&lt;sub&gt;1&lt;/sub&gt;。在[(2)](./ch04.html#ex-call-structure)中描述了这种调用结构。
有了这个观察结果,我们可以写一个小的递归函数称为`virahanka1()`来计算这些旋律,如[4.12](./ch04.html#code-virahanka)所示。请注意,要计算 *V*&lt;sub&gt;4&lt;/sub&gt;,我们先要计算 *V*&lt;sub&gt;3&lt;/sub&gt;*V*&lt;sub&gt;2&lt;/sub&gt;。但要计算 *V*&lt;sub&gt;3&lt;/sub&gt;,我们先要计算 *V*&lt;sub&gt;2&lt;/sub&gt;*V*&lt;sub&gt;1&lt;/sub&gt;。在[(2)](./ch04.html#ex-call-structure)中描述了这种调用结构。
```py
from numpy import arange
......@@ -1408,7 +1408,7 @@ Python 网站提供大量文档。理解内置的函数和标准类型是很重
1. 现在尝试同样的练习,但使用`sent2 = sent1[:]`赋值。再次修改`sent1`看看`sent2`会发生什么。解释。
2. 现在定义`text1`为一个字符串列表的列表(例如表示由多个句子组成的文本)。现在赋值`text2 = text1[:]`,分配一个新值给其中一个词,例如`text1[1][1] = 'Monty'`。检查这对`text2`做了什么。解释。
3. 导入 Python 的`deepcopy()`函数(即`from copy import deepcopy`),查询其文档,使用它生成任一对象的新副本。
12. ◑ 使用列表乘法初始化 _n_-by-_m_ 的空字符串列表的咧表,例如`word_table = [[''] * n] * m`。当你设置其中一个值时会发生什么事,例如`word_table[1][2] = "hello"`?解释为什么会出现这种情况。现在写一个表达式,使用`range()`构造一个列表,表明它没有这个问题。
12. ◑ 使用列表乘法初始化 *n*-by-*m* 的空字符串列表的咧表,例如`word_table = [[''] * n] * m`。当你设置其中一个值时会发生什么事,例如`word_table[1][2] = "hello"`?解释为什么会出现这种情况。现在写一个表达式,使用`range()`构造一个列表,表明它没有这个问题。
13. ◑ 写代码初始化一个称为`word_vowels`的二维数组的集合,处理一个词列表,添加每个词到`word_vowels[l][v]`,其中`l`是词的长度,`v`是它包含的元音的数量。
......
......@@ -624,7 +624,7 @@ TypeError: list objects are unhashable
[3.3](./ch05.html#code-dictionary)的开头还有第二个有用的习惯用法,那里我们初始化一个`defaultdict`,然后使用`for`循环来更新其值。下面是一个示意版本:
`>>> my_dictionary = defaultdict(`_function to create default value_`)``>>> for` _item_ `in` _sequence_`:``... my_dictionary[`_item_key_`]` _is updated with information about item_
`>>> my_dictionary = defaultdict(`_function to create default value_`)``>>> for` *item* `in` *sequence*`:``... my_dictionary[`_item_key_`]` _is updated with information about item_
下面是这种模式的另一个示例,我们按它们最后两个字母索引词汇:
......@@ -926,7 +926,7 @@ def display():
在基于一元处理一个语言处理任务时,我们使用上下文中的一个项目。标注的时候,我们只考虑当前的词符,与更大的上下文隔离。给定一个模型,我们能做的最好的是为每个词标注其*先验的*最可能的标记。这意味着我们将使用相同的标记标注一个词,如 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 标注器挑选在给定的上下文中最有可能的标记。
一个 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 标注器挑选在给定的上下文中最有可能的标记。
![Images/tag-context.png](Images/12573c3a9015654728fe798e170a3c50.jpg)
......@@ -963,7 +963,7 @@ def display():
0.102063...
```
_n_ 越大,上下文的特异性就会增加,我们要标注的数据中包含训练数据中不存在的上下文的几率也增大。这被称为*数据稀疏*问题,在 NLP 中是相当普遍的。因此,我们的研究结果的精度和覆盖范围之间需要有一个权衡(这与信息检索中的精度/召回权衡有关)。
*n* 越大,上下文的特异性就会增加,我们要标注的数据中包含训练数据中不存在的上下文的几率也增大。这被称为*数据稀疏*问题,在 NLP 中是相当普遍的。因此,我们的研究结果的精度和覆盖范围之间需要有一个权衡(这与信息检索中的精度/召回权衡有关)。
小心!
......@@ -1186,7 +1186,7 @@ Statement User121 18/m pm me if u tryin to chat
28. ◑ 使用简化的标记集测试标注器(或制作一个你自己的,通过丢弃每个标记名中除第一个字母外所有的字母)。这种标注器需要做的区分更少,但由它获得的信息也更少。讨论你的发现。
29. ◑ 回顾一个二元标注器训练过程中遇到生词,标注句子的其余部分为`None`的例子。一个二元标注器可能只处理了句子的一部分就失败了,即使句子中没有包含生词(即使句子在训练过程中使用过)。在什么情况下会出现这种情况呢?你可以写一个程序,找到一些这方面的例子吗?
30. ◑ 预处理布朗新闻数据,替换低频词为 UNK,但留下标记不变。在这些数据上训练和评估一个二元标注器。这样有多少帮助?一元标注器和默认标注器的贡献是什么?
31. ◑ 修改[4.1](./ch05.html#code-baseline-tagger)中的程序,通过将`pylab.plot()`替换为`pylab.semilogx()`,在 _x_ 轴上使用对数刻度。关于结果图形的形状,你注意到了什么?梯度告诉你什么呢?
31. ◑ 修改[4.1](./ch05.html#code-baseline-tagger)中的程序,通过将`pylab.plot()`替换为`pylab.semilogx()`,在 *x* 轴上使用对数刻度。关于结果图形的形状,你注意到了什么?梯度告诉你什么呢?
32. ◑ 使用`help(nltk.tag.brill.demo)`阅读 Brill 标注器演示函数的文档。通过设置不同的参数值试验这个标注器。是否有任何训练时间(语料库大小)和性能之间的权衡?
33. ◑ 写代码构建一个集合的字典的字典。用它来存储一套可以跟在具有给定词性标记的给定词后面的词性标记,例如 word&lt;sub&gt;i&lt;/sub&gt; → tag&lt;sub&gt;i&lt;/sub&gt; → tag&lt;sub&gt;i+1&lt;/sub&gt;
34. ★ 布朗语料库中有 264 个不同的词有 3 种可能的标签。
......@@ -1201,7 +1201,7 @@ Statement User121 18/m pm me if u tryin to chat
2. 将这个标注器加入到回退标注器序列(包括普通的三元和二元标注器),放在常用默认标注器的前面。
3. 评价这个新的一元标注器的贡献。
38. ★ 思考[5](./ch05.html#sec-n-gram-tagging)中的代码,它确定一个三元标注器的准确性上限。回顾 Abney 的关于精确标注的不可能性的讨论[(Church, Young, & Bloothooft, 1996)](./bibliography.html#abney1996pst)。解释为什么正确标注这些例子需要获取词和标记以外的其他种类的信息。你如何估计这个问题的规模?
39. ★ 使用`nltk.probability`中的一些估计技术,例如 _Lidstone_ 或 _Laplace_ 估计,开发一种统计标注器,它在训练中没有遇到而测试中遇到的上下文中表现优于 n-gram 回退标注器。
39. ★ 使用`nltk.probability`中的一些估计技术,例如 *Lidstone* 或 *Laplace* 估计,开发一种统计标注器,它在训练中没有遇到而测试中遇到的上下文中表现优于 n-gram 回退标注器。
40. ★ 检查 Brill 标注器创建的诊断文件`rules.out`和`errors.out`。通过访问源代码(`http://www.nltk.org/code`)获得演示代码,创建你自己版本的 Brill 标注器。并根据你从检查`rules.out`了解到的,删除一些规则模板。增加一些新的规则模板,这些模板使用那些可能有助于纠正你在`errors.out`看到的错误的上下文。
41. ★ 开发一个 n-gram 回退标注器,允许在标注器初始化时指定“anti-n-grams”,如`["the", "the"]`。一个 anti-n-grams 被分配一个数字 0,被用来防止这个 n-gram 回退(如避免估计 P(the | the)而只做 P(the))。
42. ★ 使用布朗语料库开发标注器时,调查三种不同的方式来定义训练和测试数据之间的分割:genre (`category`)、source (`fileid`)和句子。比较它们的相对性能,并讨论哪种方法最合理。(你可能要使用 n-交叉验证,在[3](./ch06.html#sec-evaluation)中讨论的,以提高评估的准确性。)
......
......@@ -494,7 +494,7 @@ NPS 聊天语料库,在[1](./ch02.html#sec-extracting-text-from-corpora)中的
## 2.3 识别文字蕴含
识别文字蕴含(RTE)是判断文本 _T_ 的一个给定片段是否蕴含着另一个叫做“假设”的文本(已经在[5](./ch01.html#sec-automatic-natural-language-understanding)讨论过)。迄今为止,已经有 4 个 RTE 挑战赛,在那里共享的开发和测试数据会提供给参赛队伍。这里是挑战赛 3 开发数据集中的文本/假设对的两个例子。标签 _True_ 表示蕴含成立,_False_ 表示蕴含不成立。
识别文字蕴含(RTE)是判断文本 *T* 的一个给定片段是否蕴含着另一个叫做“假设”的文本(已经在[5](./ch01.html#sec-automatic-natural-language-understanding)讨论过)。迄今为止,已经有 4 个 RTE 挑战赛,在那里共享的开发和测试数据会提供给参赛队伍。这里是挑战赛 3 开发数据集中的文本/假设对的两个例子。标签 *True* 表示蕴含成立,*False* 表示蕴含不成立。
> Challenge 3, Pair 34 (True)
>
......@@ -510,7 +510,7 @@ NPS 聊天语料库,在[1](./ch02.html#sec-extracting-text-from-corpora)中的
应当强调,文字和假设之间的关系并不一定是逻辑蕴涵,而是一个人是否会得出结论:文本提供了合理的证据证明假设是真实的。
我们可以把 RTE 当作一个分类任务,尝试为每一对预测 _True_/_False_ 标签。虽然这项任务的成功做法似乎看上去涉及语法分析、语义和现实世界的知识的组合,RTE 的许多早期的尝试使用粗浅的分析基于文字和假设之间的在词级别的相似性取得了相当不错的结果。在理想情况下,我们希望如果有一个蕴涵那么假设所表示的所有信息也应该在文本中表示。相反,如果假设中有的资料文本中没有,那么就没有蕴涵。
我们可以把 RTE 当作一个分类任务,尝试为每一对预测 *True*/*False* 标签。虽然这项任务的成功做法似乎看上去涉及语法分析、语义和现实世界的知识的组合,RTE 的许多早期的尝试使用粗浅的分析基于文字和假设之间的在词级别的相似性取得了相当不错的结果。在理想情况下,我们希望如果有一个蕴涵那么假设所表示的所有信息也应该在文本中表示。相反,如果假设中有的资料文本中没有,那么就没有蕴涵。
在我们的 RTE 特征探测器([2.2](./ch06.html#code-rte-features))中,我们让词(即词类型)作为信息的代理,我们的特征计数词重叠的程度和假设中有而文本中没有的词的程度(由`hyp_extra()`方法获取)。不是所有的词都是同样重要的——命名实体,如人、组织和地方的名称,可能会更为重要,这促使我们分别为`word`s 和`ne`s(命名实体)提取不同的信息。此外,一些高频虚词作为“停用词”被过滤掉。
......@@ -543,7 +543,7 @@ set()
{'member'}
```
这些特征表明假设中所有重要的词都包含在文本中,因此有一些证据支持标记这个为 _True_
这些特征表明假设中所有重要的词都包含在文本中,因此有一些证据支持标记这个为 *True*
`nltk.classify.rte_classify`模块使用这些方法在合并的 RTE 测试数据上取得了刚刚超过 58%的准确率。这个数字并不是很令人印象深刻的,还需要大量的努力,更多的语言学处理,才能达到更好的结果。
......@@ -621,7 +621,7 @@ Python 提供了一个良好的环境进行基本的文本处理和特征提取
给定这四个数字,我们可以定义以下指标:
* F-度量值(或 F-Score),组合精确度和召回率为一个单独的得分,被定义为精确度和召回率的调和平均数(2 × _Precision_ × _Recall_) / (_Precision_ + _Recall_)。
* F-度量值(或 F-Score),组合精确度和召回率为一个单独的得分,被定义为精确度和召回率的调和平均数(2 × *Precision* × *Recall*) / (*Precision* + *Recall*)。
## 3.4 混淆矩阵
......@@ -780,13 +780,13 @@ def entropy(labels):
```
(13)
a. in the car _versus_ on the train
a. in the car *versus* on the train
b. in town _versus_ on campus
b. in town *versus* on campus
c. in the picture _versus_ on the screen
c. in the picture *versus* on the screen
d. in Macbeth _versus_ on Letterman
d. in Macbeth *versus* on Letterman
```
关于本文档...
......
......@@ -653,7 +653,7 @@ Hogeschool N B-ORG
## 6 关系抽取
一旦文本中的命名实体已被识别,我们就可以提取它们之间存在的关系。如前所述,我们通常会寻找指定类型的命名实体之间的关系。进行这一任务的方法之一是首先寻找所有 _X_, α, _Y_)形式的三元组,其中 _X_ 和 _Y_ 是指定类型的命名实体,α表示 _X_ 和 _Y_ 之间关系的字符串。然后我们可以使用正则表达式从α的实体中抽出我们正在查找的关系。下面的例子搜索包含词 in 的字符串。特殊的正则表达式`(?!\b.+ing\b)`是一个否定预测先行断言,允许我们忽略如 success in supervising the transition of 中的字符串,其中 in 后面跟一个动名词。
一旦文本中的命名实体已被识别,我们就可以提取它们之间存在的关系。如前所述,我们通常会寻找指定类型的命名实体之间的关系。进行这一任务的方法之一是首先寻找所有 *X*, α, *Y*)形式的三元组,其中 *X* 和 *Y* 是指定类型的命名实体,α表示 *X* 和 *Y* 之间关系的字符串。然后我们可以使用正则表达式从α的实体中抽出我们正在查找的关系。下面的例子搜索包含词 in 的字符串。特殊的正则表达式`(?!\b.+ing\b)`是一个否定预测先行断言,允许我们忽略如 success in supervising the transition of 中的字符串,其中 in 后面跟一个动名词。
```py
>>> IN = re.compile(r'.*\bin\b(?!\b.+ing)')
......
......@@ -128,7 +128,7 @@ grammar2 = nltk.CFG.fromstring("""
一种简单的自下而上分析器是移进-归约分析器。与所有自下而上的分析器一样,移进-归约分析器尝试找到对应文法生产式*右侧*的词和短语的序列,用左侧的替换它们,直到整个句子归约为一个`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)所示。
移位-规约分析器反复将下一个输入词推到堆栈([4.1](./ch04.html#sec-back-to-the-basics));这是移位操作。如果堆栈上的前 *n* 项,匹配一些产生式的右侧的 *n* 个项目,那么就把它们弹出栈,并把产生式左边的项目压入栈。这种替换前 *n* 项为一项的操作就是规约操作。此操作只适用于堆栈的顶部;规约栈中的项目必须在后面的项目被压入栈之前做。当所有的输入都使用过,堆栈中只剩余一个项目,也就是一颗分析树作为它的根的`S`节点时,分析器完成。移位-规约分析器通过上述过程建立一颗分析树。每次弹出堆栈 *n* 个项目,它就将它们组合成部分的分析树,然后将这压回推栈。我们可以使用图形化示范`nltk.app.srparser()`看到移位-规约分析算法步骤。执行此分析器的六个阶段,如[4.2](./ch08.html#fig-srparser1-6)所示。
![Images/srparser1-6.png](Images/56cee123595482cf3edaef089cb9a6a7.jpg)
......@@ -222,9 +222,9 @@ WFST 1 2 3 4 5 6 7
6 . . . . . . N
```
回到我们的表格表示,假设对于词 an 我们有`Det`在(2, 3)单元,对以词 elephant 有`N`在(3, 4)单元,对于 an elephant 我们应该在(2, 4)放入什么?我们需要找到一个形如 _A_`Det N`的产生式。查询了文法,我们知道我们可以输入(0, 2)单元的`NP`
回到我们的表格表示,假设对于词 an 我们有`Det`在(2, 3)单元,对以词 elephant 有`N`在(3, 4)单元,对于 an elephant 我们应该在(2, 4)放入什么?我们需要找到一个形如 *A*`Det N`的产生式。查询了文法,我们知道我们可以输入(0, 2)单元的`NP`
更一般的,我们可以在(i, j)输入 _A_,如果有一个产生式 _A_ → _B_ _C_,并且我们在(i, k)中找到非终结符 _B_,在(k, j)中找到非终结符 _C_[4.4](./ch08.html#code-wfst)中的程序使用此规则完成 WFST。通过调用函数`complete_wfst()`时设置 `trace``True`,我们看到了显示 WFST 正在被创建的跟踪输出:
更一般的,我们可以在(i, j)输入 *A*,如果有一个产生式 *A**B* *C*,并且我们在(i, k)中找到非终结符 *B*,在(k, j)中找到非终结符 *C*[4.4](./ch08.html#code-wfst)中的程序使用此规则完成 WFST。通过调用函数`complete_wfst()`时设置 `trace``True`,我们看到了显示 WFST 正在被创建的跟踪输出:
```py
>>> wfst1 = complete_wfst(wfst0, tokens, groucho_grammar, trace=True)
......@@ -431,7 +431,7 @@ def print_node(t, width):
我们可以观察到一种强烈的倾向就是最短的补语最先出现。然而,这并没有解释类似`give NP: federal judges / NP: a raise`的形式,其中有生性起了重要作用。事实上,根据[(Bresnan & Hay, 2006)](./bibliography.html#bresnan2006gg)的调查,存在大量的影响因素。这些偏好可以用加权语法来表示。
概率上下文无关语法(或 _PCFG_)是一种上下文无关语法,它的每一个产生式关联一个概率。它会产生与相应的上下文无关语法相同的文本解析,并给每个解析分配一个概率。PCFG 产生的一个解析的概率仅仅是它用到的产生式的概率的乘积。
概率上下文无关语法(或 *PCFG*)是一种上下文无关语法,它的每一个产生式关联一个概率。它会产生与相应的上下文无关语法相同的文本解析,并给每个解析分配一个概率。PCFG 产生的一个解析的概率仅仅是它用到的产生式的概率的乘积。
最简单的方法定义一个 PCFG 是从一个加权产生式序列组成的特殊格式的字符串加载它,其中权值出现在括号里,如[6.4](./ch08.html#code-pcfg1)所示。
......@@ -465,7 +465,7 @@ grammar = nltk.PCFG.fromstring("""
* 句子都有内部组织结构,可以用一棵树表示。组成结构的显著特点是:递归、中心词、补语和修饰语。
* 语法是一个潜在的无限的句子集合的一个紧凑的特性;我们说,一棵树是符合语法规则的或语法树授权一棵树。
* 语法是用于描述一个给定的短语是否可以被分配一个特定的成分或依赖结构的一种形式化模型。
* 给定一组句法类别,上下文无关文法使用一组生产式表示某类型 _A_ 的短语如何能够被分析成较小的序列α&lt;sub&gt;1&lt;/sub&gt; ... α&lt;sub&gt;n&lt;/sub&gt;
* 给定一组句法类别,上下文无关文法使用一组生产式表示某类型 *A* 的短语如何能够被分析成较小的序列α&lt;sub&gt;1&lt;/sub&gt; ... α&lt;sub&gt;n&lt;/sub&gt;
* 依存语法使用产生式指定给定的中心词的依赖是什么。
* 一个句子有一个以上的句法分析就产生句法歧义(如介词短语附着歧义)。
* 分析器是一个过程,为符合语法规则的句子寻找一个或多个相应的树。
......@@ -503,7 +503,7 @@ grammar = nltk.PCFG.fromstring("""
7. ☼ 分析 A.A. Milne 关于 Piglet 的句子,为它包含的所有句子画下划线,然后用`S`替换这些(如第一句话变为`S` &lt;cite&gt;when&lt;/cite&gt;:lx` `S`)。为这种“压缩”的句子画一个树形结构。用于建立这样一个长句的主要的句法结构是什么?
8. ☼ 在递归下降分析器的演示中,通过选择 _Edit_ 菜单上的 _Edit Text_ 改变实验句子。
8. ☼ 在递归下降分析器的演示中,通过选择 *Edit* 菜单上的 _Edit Text_ 改变实验句子。
9. ☼ `grammar1`中的语法能被用来描述长度超过 20 词的句子吗?
......@@ -515,7 +515,7 @@ grammar = nltk.PCFG.fromstring("""
13. ☼ 思考词序列:Buffalo buffalo Buffalo buffalo buffalo buffalo Buffalo buffalo。如`http://en.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo`解释的,这是一个语法正确的句子。思考此维基百科页面上表示的树形图,写一个合适的语法。正常情况下是小写,模拟听到这句话时听者会遇到的问题。你能为这句话找到其他的解析吗?当句子变长时分析树的数量如何增长?(这些句子的更多的例子可以在`http://en.wikipedia.org/wiki/List_of_homophonous_phrases`找到。)
14. ◑ 你可以通过选择 _Edit_ 菜单上的 _Edit Grammar_ 修改递归下降分析器演示程序。改变第二次扩充产生式,即`NP -&gt; Det N PP`为`NP -&gt; NP PP`。使用 _Step_ 按钮,尝试建立一个分析树。发生了什么?
14. ◑ 你可以通过选择 *Edit* 菜单上的 _Edit Grammar_ 修改递归下降分析器演示程序。改变第二次扩充产生式,即`NP -&gt; Det N PP`为`NP -&gt; NP PP`。使用 *Step* 按钮,尝试建立一个分析树。发生了什么?
15. ◑ 扩展`grammar2`中的语法,将产生式中的介词扩展为不及物的,及物的和需要`PP`补语的。基于这些产生式,使用前面练习中的方法为句子 Lee ran away home 画一棵树。
......@@ -549,7 +549,7 @@ grammar = nltk.PCFG.fromstring("""
26. ◑ 修改函数`init_wfst()`和`complete_wfst()`,使 WFST 中每个单元的内容是一组非终端符而不是一个单独的非终结符。
27. ◑ 思考[4.4](./ch08.html#code-wfst)中的算法。你能解释为什么分析上下文无关语法是与&lt;cite&gt;n&lt;/cite&gt;&lt;sup&gt;3&lt;/sup&gt;成正比的,其中 _n_ 是输入句子的长度。
27. ◑ 思考[4.4](./ch08.html#code-wfst)中的算法。你能解释为什么分析上下文无关语法是与&lt;cite&gt;n&lt;/cite&gt;&lt;sup&gt;3&lt;/sup&gt;成正比的,其中 *n* 是输入句子的长度。
28. ◑ 处理宾州树库语料库样本`nltk.corpus.treebank`中的每棵树,在`Tree.productions()`的帮助下提取产生式。丢弃只出现一次的产生式。具有相同的左侧和类似的右侧的产生式可以被折叠,产生一个等价的却更紧凑的规则集。编写代码输出一个紧凑的语法。
......
......@@ -692,17 +692,17 @@ In the case of complex values, we say that feature structures are themselves typ
| (59) | |
&#124; a. &#124; &#124; The farmer _loaded_ the cart with sand &#124;
&#124; a. &#124; &#124; The farmer *loaded* the cart with sand &#124;
&#124; b. &#124; &#124; The farmer _loaded_ sand into the cart &#124;
&#124; b. &#124; &#124; The farmer *loaded* sand into the cart &#124;
&#124; c. &#124; &#124; The farmer _filled_ the cart with sand &#124;
&#124; c. &#124; &#124; The farmer *filled* the cart with sand &#124;
&#124; d. &#124; &#124; *The farmer _filled_ sand into the cart &#124;
&#124; d. &#124; &#124; *The farmer *filled* sand into the cart &#124;
&#124; e. &#124; &#124; *The farmer _dumped_ the cart with sand &#124;
&#124; e. &#124; &#124; *The farmer *dumped* the cart with sand &#124;
&#124; f. &#124; &#124; The farmer _dumped_ sand into the cart &#124;
&#124; f. &#124; &#124; The farmer *dumped* sand into the cart &#124;
|
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册