30

一些背景

我是佛罗里达新学院的一名文学专业学生,目前正在从事一个雄心勃勃的创意项目。该项目面向诗歌的算法生成。它是用 Python 编写的。我的 Python 知识和自然语言处理知识仅来自通过互联网自学。我已经用这些东西工作了大约一年,所以我并不无助,但在不同的点上,我在这个项目中前进时遇到了麻烦。目前,我正在进入开发的最后阶段,并且遇到了一些障碍。

我需要实现某种形式的语法规范化,这样输出就不会像未共轭/变形的穴居人说话那样出现。大约一个月前,SO 上的一些友好人士给了我一些建议,告诉我如何通过使用ngram 语言建模器来解决这个问题,基本上——但我正在寻找其他解决方案,因为似乎 NLTK 的 NgramModeler 不适合我的需要。(还提到了 POS 标记的可能性,但考虑到我的业余爱好,我的文字可能过于零碎和奇怪,无法轻松实现。)

也许我需要像 AtD 这样的东西,但希望不那么复杂

我认为需要像After the DeadlineQueequeg这样的东西,但这些似乎都不完全正确。Queequeg 可能不太适合——它是在 2003 年为 Unix 编写的,我一生都无法让它在 Windows 上工作(已经尝试了一切)。但我喜欢它只检查正确的动词变位和数字一致性。

另一方面,AtD 更加严格,提供了比我需要的更多的功能。但我似乎无法让它工作的python 绑定。(我从 AtD 服务器收到 502 错误,我确信这很容易修复,但我的应用程序将在线,我宁愿避免依赖另一台服务器。我负担不起运行 AtD 服务器的费用我自己,因为我的应用程序将需要我的网络主机的“服务”数量已经威胁到在廉价地托管这个应用程序方面造成问题。)

我想避免的事情

自己构建 Ngram 语言模型似乎不适合这项任务。我的应用程序抛出了很多未知的词汇,扭曲了所有的结果。(除非我使用的语料库太大,以至于它对我的应用程序来说运行速度太慢——应用程序需要非常敏捷。)

严格检查语法既不适合这项任务。语法不需要完美,句子不需要比你可以使用 ngrams 生成的类似英语的胡言乱语更明智。即使它是胡言乱语,我只需要强制执行动词变位,数字一致,并做一些事情,比如删除多余的文章。

事实上,我什至不需要任何更正的建议。我认为我所需要的只是计算一组可能的句子中每个句子中似乎出现了多少错误,这样我就可以按他们的分数排序并选择语法问题最少的那个。

一个简单的解决方案?通过检测明显的错误来评分流畅度

如果存在处理所有这些的脚本,我会非常高兴(我还没有找到)。当然,我可以为我找不到的东西编写代码;我正在寻找有关如何优化我的方法的建议。

假设我们已经布置了一小部分文本:

existing_text = "The old river"

现在假设我的脚本需要确定下一个动词“to bear”的变形。我愿意接受有关此例程的建议。但我主要需要步骤 #2 的帮助,通过计算语法错误来评估流畅度:

  1. 使用NodeBox Linguistics中的动词变位方法来提出这个动词的所有变位;['bear', 'bears', 'bearing', 'bore', 'borne'].
  2. 迭代可能性,(浅浅地)检查由existing_text + " " + possibility(“The old river bear”、“The old river bears”等)产生的字符串的语法。计算每个构造的错误计数。在这种情况下,唯一出现错误的结构似乎是“老河熊”。
  3. 总结起来应该很容易......在错误计数最低的可能性中,随机选择。
4

4 回答 4

11

使用链接语法进行语法检查

链接语法简介

Link Grammar 由 Davy Temperley、Daniel Sleator 和 John Lafferty 开发,是一种英语句法解析器:“给定一个句子,系统为其分配一个句法结构,该结构由一组连接成对单词的标记链接组成。 parser 还生成句子的“组成”表示(显示名词短语、动词短语等)。” 您可以在此处阅读有关链接语法的更多信息并与在线解析器进行交互

几年前,AbiWord接管了该项目。他们解释说AbiWord 使用 Link Grammar 来检查语法。我不知道 AbiWord 实际上如何执行其语法检查的复杂性,但我在关于语法检查的问答中读到了基本方法(我现在已经丢失了链接)。与我接触过的其他一些解析器不同,Link Grammar 会在句子的语法格式不正确时产生非常不同的结果:它无法为语法不正确的句子找到完整的链接

您可以使用在线解析器自己查看:输入句子“这是我买了狗的人”会产生 1 个链接,而“这是我买的狗的人”不会产生完整的链接。

这不会像我要求的那样“计算”错误的数量。然而,它确实满足了原始的一种排除语法上不合理(即不正确共轭)可能性的方法。

Python 绑定:它们存在!

Link Grammar 是用 C 编写的。当我第一次研究时,这给我带来了一个问题,因为我只有一年的 Python 编码,而且我很难自己创建绑定。我也担心我的进程/服务计数,所以我不想在我的 Python 进程之上运行 Link Grammar 程序。但是在 1 月 13 日发布这个问题后的一两天,我遇到了 Jeff Elmore(enzondio)对pylinkgrammar对 PyPi 的贡献——这仅发生在前一天。

正如pylinkgrammar页面所解释的,您仍然必须首先构建和安装 linkgrammar。有关如何使用它的说明在该页面上。但是关于安装pylinkgrammar的一些注意事项:

  1. 我无法让 pylinkgrammar 在 Windows 7 上使用 Python 2.7,我认为这是因为 CMake 在 Windows 7 上使用 Python 2.7 时出现问题。
  2. 因此,我将整个项目移到了 Ubuntu (10.10) 中,因为我非常需要这个。但是当我设置 Ubuntu 时,我尝试为 Python 2.7 安装所有东西(甚至删除了 2.6)。我仍然无法让 pylinkgrammar 使用 Python 2.7。我认为这仍然是由于 CMake 和 Python 2.7 之间的问题。
  3. 我重新开始安装 Ubuntu,因为事情变得一团糟,而是使用 Python 2.6 设置所有内容。我现在已经让 pylinkgrammar 使用 Python 2.6。(但我必须输入from pylinkgrammar.linkgrammar import Parser,这与 pypi 页面的说明略有不同)。

NodeBox 语言学:我的解决方案的另一部分

在我的问题中,我表示需要生成给定句子的所有变形/变位,以检查所有这些变化并消除语法上不合理的项目。(我正在使用 WordNet 在输出之前更改某些用户输入,并且 WordNet 结果是未变形的;它们需要变形以使输出(更)易于理解)。

一篇内容丰富的博文将我带到了NodeBox Linguistics 库这是一组工具,“您可以使用这些工具对英语内容进行语法变形语义操作”。实际上,该库可用于动词共轭、名词单数化和复数化,以及许多其他操作。这正是我所需要的。我的应用程序知道它已将输入中的哪些单词换成了新的、未变形的语言;这些片段是它使用 NodeBox 语言学中的方法生成变体的片段。

我将这些变体输入 pylinkgrammar 并删除无法找到完整链接的变体。有时这根本不会产生任何结果,但通常会产生有用的结果。请注意,链接语法不会为大多数不完整的句子找到完整的链接。如果您想像我一样检查碎片句子中的变位,请尝试在检查之前使用填充符扩展碎片句子,然后在输出之前删除填充符。我通过从数据中取出最后一个词,在布朗语料库中查找它,然后从语料库中附加该句子的其余部分来获得这个“填充物”。

我没有任何测试来报告这种方法在统计上的准确性,但它在大多数情况下都适用于我的(特殊)目的。我仍在充实此实现并编写异常案例和清理输入数据的方法。希望这些信息也可以帮助其他人!请不要犹豫,要求澄清。

于 2012-01-19T18:15:08.130 回答
2

非常酷的项目,首先。

我找到了一个java 语法检查器。我从未使用过它,但文档声称它可以作为服务器运行。基本上任何地方都应该支持 java 和监听端口。

我刚刚进入具有 CS 背景的 NLP,所以我不介意更详细地帮助您集成您决定使用的任何内容。随时询问更多细节。

于 2012-01-16T01:51:04.857 回答
1

另一种方法是使用所谓的过度生成和排名方法。在第一步中,您让诗歌生成器生成多个候选生成。然后使用亚马逊的 Mechanical Turk 之类的服务来收集人类对流畅度的判断。我实际上建议对从相同种子条件生成的多个句子同时进行判断。最后,您从生成的句子中提取特征(可能使用某种形式的句法解析器)来训练模型以对问题质量进行评分或分类。你甚至可以抛出上面列出的启发式方法。

Michael Heilman 使用这种方法生成问题。有关更多详细信息,请阅读以下论文: 好问题!使用 Mechanical Turk 对计算机生成的问题进行问题生成和 评级的统计排名

于 2012-02-01T06:23:05.360 回答
1

上面提供的 pylinkgrammar 链接有点过时了。它指向版本 0.1.9,该版本的代码示例不再有效。如果您走这条路,请务必使用最新版本,该版本可在以下位置找到:

https://pypi.python.org/pypi/pylinkgrammar

于 2013-10-21T19:00:53.030 回答