9 练习

  1. ☼ 你能想出符合语法的却可能之前从来没有被说出的句子吗?(与伙伴轮流进行。)这告诉你关于人类语言的什么?

  2. ☼ 回想一下 Strunk 和 White 的禁止在句子开头使用 however 表示“although”的意思。在网上搜索句子开头使用的 however。这个成分使用的有多广泛?

  3. ☼ 思考句子<cite>Kim arrived or Dana left and everyone cheered</cite>。用括号的形式表示 and 和 or 的相对范围。产生这两种解释对应的树结构。

  4. Tree类实现了各种其他有用的方法。请看Tree帮助文档查阅更多细节(如导入 Tree 类,然后输入help(Tree))。

  5. ☼ 在本练习中,你将手动构造一些分析树。

    1. 编写代码产生两棵树,对应短语 old men and women 的不同读法
    2. 将本章中表示的任一一颗树编码为加标签的括号括起的形式,使用nltk.Tree()检查它是否符合语法。使用draw()显示树。
    3. 如(a) 中那样,为 The woman saw a man last Thursday 画一棵树。
  6. ☼ 写一个递归函数,遍历一颗树,返回树的深度,一颗只有一个节点的树的深度应为 0。(提示:子树的深度是其子女的最大深度加 1。)

  7. ☼ 分析 A.A. Milne 关于 Piglet 的句子,为它包含的所有句子画下划线,然后用S替换这些(如第一句话变为S <cite>when</cite>:lx`S)。为这种“压缩”的句子画一个树形结构。用于建立这样一个长句的主要的句法结构是什么?

  8. ☼ 在递归下降分析器的演示中,通过选择 Edit 菜单上的 Edit Text 改变实验句子。

  9. grammar1中的语法能被用来描述长度超过 20 词的句子吗?

  10. ☼ 使用图形化图表分析器接口,尝试不同的规则调用策略做实验。拿出你自己的可以使用图形界面手动执行的策略。描述步骤,并报告它的任何效率的提高(例如用结果图表示大小)。这些改进取决于语法结构吗?你觉得一个更聪明的规则调用策略能显著提升性能吗?

  11. ☼ 对于一个你已经见过的或一个你自己设计的 CFG,用笔和纸手动跟踪递归下降分析器和移位-规约分析器的执行。

  12. ☼ 我们已经看到图表分析器增加边而从来不从图表中删除的边。为什么?

  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 PPNP -&gt; NP PP。使用 Step 按钮,尝试建立一个分析树。发生了什么?

  15. ◑ 扩展grammar2中的语法,将产生式中的介词扩展为不及物的,及物的和需要PP补语的。基于这些产生式,使用前面练习中的方法为句子 Lee ran away home 画一棵树。

  16. ◑ 挑选一些常用动词,完成以下任务:

    1. 写一个程序在 PP 附着语料库nltk.corpus.ppattach找到那些动词。找出任何这样的情况,相同的动词有两种不同的附着,其中第一个是名词,或者第二个是名词,或者介词保持不变(正如我们在2句法歧义中讨论过的)。
    2. 制定 CFG 语法产生式涵盖其中一些情况。
  17. ◑ 写一个程序,比较自上而下的图表分析器与递归下降分析器的效率(4)。使用相同的语法和输入的句子。使用timeit模块比较它们的性能(见4.7,如何做到这一点的一个例子)。

  18. 比较自上而下、自下而上和左角落分析器的性能,使用相同的语法和 3 个符合语法的测试句子。使用timeit记录每个分析器在同一个句子上花费的时间。写一个函数,在这三句话上运行这三个分析器,输出 3×3 格的时间,以及行和列的总计。讨论你的发现。

  19. ◑ 阅读“garden path”的句子。一个分析器的计算工作与人类处理这些句子的困难性有什么关系?http://en.wikipedia.org/wiki/Garden_path_sentence

  20. ◑ 若要在一个窗口比较多个树,我们可以使用draw_trees()方法。定义一些树,尝试一下:

    1. &gt;&gt;&gt; from nltk.draw.tree import draw_trees
    2. &gt;&gt;&gt; draw_trees(tree1, tree2, tree3)
  21. ◑ 使用树中的位置,列出宾州树库前 100 个句子的主语;为了使结果更容易查看,限制从高度最高为 2 的子树提取主语。

  22. ◑ 查看 PP 附着语料库,尝试提出一些影响PP附着的因素。

  23. ◑ 在本节中,我们说过简单的用术语 n-grams 不能描述所有语言学规律。思考下面的句子,尤其是短语 in his turn 的位置。这是基于 n-grams 的方法的一个问题吗?

    > <cite>What was more, the in his turn somewhat youngish Nikolay Parfenovich also turned out to be the only person in the entire world to acquire a sincere liking to our “discriminated-against” public procurator.</cite> (Dostoevsky: The Brothers Karamazov)

  24. ◑ 编写一个递归函数产生嵌套的括号括起的形式的一棵树,显示去掉叶节点之后的子树的非终结符。于是上面的关于 Pierre Vinken 的例子会产生:[[[NNP NNP]NP , [ADJP [CD NNS]NP JJ]ADJP ,]NP-SBJ MD [VB [DT NN]NP [IN [DT JJ NN]NP]PP-CLR [NNP CD]NP-TMP]VP .]S。连续的类别应用空格分隔。

  25. ◑ 从古登堡工程下载一些电子图书。写一个程序扫描这些文本中任何极长的句子。你能找到的最长的句子是什么?这么长的句子的句法结构是什么?

  26. ◑ 修改函数init_wfst()complete_wfst(),使 WFST 中每个单元的内容是一组非终端符而不是一个单独的非终结符。

  27. ◑ 思考4.4中的算法。你能解释为什么分析上下文无关语法是与<cite>n</cite><sup>3</sup>成正比的,其中 n 是输入句子的长度。

  28. ◑ 处理宾州树库语料库样本nltk.corpus.treebank中的每棵树,在Tree.productions()的帮助下提取产生式。丢弃只出现一次的产生式。具有相同的左侧和类似的右侧的产生式可以被折叠,产生一个等价的却更紧凑的规则集。编写代码输出一个紧凑的语法。

  29. ★ 英语中定义句子S的主语的一种常见的方法是作为S 的名词短语孩子 VP 兄弟 。写一个函数,以一句话的树为参数,返回句子主语对应的子树。如果传递给这个函数的树的根节点不是S或它缺少一个主语,应该怎么做?

  30. ★ 写一个函数,以一个语法(如3.1定义的语法)为参数,返回由这个语法随机产生的一个句子。(使用grammar.start()找出语法的开始符号;grammar.productions(lhs)得到具有指定左侧的语法的产生式的列表;production.rhs()得到一个产生式的右侧。)

  31. ★ 使用回溯实现移位-规约分析器的一个版本,使它找出一个句子所有可能的解析,它可以被称为“递归上升分析器”。咨询维基百科关于回溯的条目http://en.wikipedia.org/wiki/Backtracking

  32. ★ 正如我们在7.中所看到的,可以将词块表示成它们的词块标签。当我们为包含 gave 的句子做这个的时候,我们发现如以下模式:

    1. gave NP
    2. gave up NP in NP
    3. gave NP up
    4. gave NP NP
    5. gave NP to NP