使用NLTK进行语义解析

5

我正在尝试使用NLTK进行语义分析,以解析口头导航命令,例如"go to San Francisco",“give me directions to 123 Main Street”等。

可以使用相当简单的CFG文法来完成此操作,例如:

S -> COMMAND LOCATION
COMMAND -> "go to" | "give me directions to" | ...
LOCATION -> CITY | STREET | ...

问题在于这涉及到非原子(超过一个词长)的文字,例如“去”,而NLTK似乎没有为此设置(如果我错了,请纠正我)。解析任务需要标记作为先决条件,所有标记器似乎都会对单个单词进行标记。因此,我的选择似乎是:
a)定义一个自定义标记器,可以将非句法标记分配给单词序列而不是单个单词(例如,“去”:“COMMAND”)。 b)使用功能来增强语法,例如:
COMMAND -> VB[sem='go'] P[sem='to'] | ...

c) 使用分块器提取COMMAND等子结构,然后对结果应用解析器。NLTK是否允许分块器->解析器级联?

其中一些选项似乎很复杂(hack)。有没有更好的方法?


NLTK有一个discourse模块,它本质上是一个语义解析器,可以生成文本意义的表示。 - Anderson Green
3个回答

1

看起来你想要识别祈使句。

这个答案已经探讨了这个问题并提供了一个类似于选项(a)的解决方案,但稍有不同,因为它让标注器做大部分工作。(b)确实有点hacky...但你正在创建一个相当定制化的应用程序,所以它可能有效! 我会选择(c) - 先解析,然后基于(a)中的CFG进行分块。

但总体而言,正如其他答案所解释的那样,目前似乎没有完美的方法来做到这一点

你可能还想看看pattern.en(也可以查看他们的GitHub存储库)。他们的

mood()函数试图将解析出的句子识别为陈述、祈使、条件或虚拟语气


更新了 pattern.en 的链接,原链接为 http://www.clips.ua.ac.be/pages/pattern-en,但截至 2021 年 9 月已无法使用。 - Chiarcos

0
我建议您使用spacy中提供的“基于规则的匹配器”,它提供了标记匹配器、短语匹配器、实体规则器等选项。我曾使用过标记匹配器来指定模式(go + to + place),效果非常好。
token_pattern = [{"LEMMA": "go"}, {"POS": "ADP"}, {"POS": "PROPN"}]

这个模式可以匹配到 "去纽约"、"正在去纽约"、"和玛丽一起去了" 等等。

另外,如果你只想提取名词,比如你的例子中的 "旧金山"、"123 Main Street",命名实体识别(NER)可能会有所帮助。


0

针对相关任务(商业交易的语义解析器(链接)的复制),我之前做了类似于(c)的事情。级联解析器工作流程的最大优点是语法可以保持相对简单(和快速),因为它们不必进行全局消歧。我想这是最不破坏性的方法,因为它实际上是一种有效的策略来设计解析器工作流程。

至于(a),自定义标记器需要某种形式的训练数据。如果您能够创建或引导该数据,那将是最自然的解决方案。要使用标记器进行跨度注释,请考虑使用BIO(IOBES)模式,如常用于命名实体注释,即You/B-COMMAND shall/I-COMMAND not/I-COMMAND pass/E-COMMAND !/O


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接