5

我正在尝试使用 NLTK 对语音导航命令进行语义解析,例如“去旧金山”、“给我到 123 Main Street 的路线”等。

这可以通过一个相当简单的 CFG 语法来完成,例如

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

问题是这涉及非原子(超过一个字长)文字,例如“转到”,NLTK 似乎没有设置(如果我错了,请纠正我)。解析任务将标记作为先决条件,并且所有标记器似乎总是标记单个单词。所以,我的选择似乎是:

a) 定义一个自定义标记器,可以将非句法标记分配给单词序列而不是单个单词(例如,“go to”:“COMMAND”)。b) 使用特征来增强语法,例如:

COMMAND -> VB[sem='go'] P[sem='to'] | ...

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

其中一些选项看起来很复杂(黑客)。有什么好办法吗?

4

3 回答 3

1

似乎您想确定命令。

这个答案对此进行了调查,并包含一个类似于您的选项 (a) 的解决方案,但有点不同,因为它让标注器完成了大部分工作。(b) 确实看起来有点老套……但是您正在创建一个非常自定义的应用程序,所以它可以工作!我会做(c)相反的方式 - 解析然后基于(a)中的CFG进行分块。

然而,总的来说,正如另一个答案所解释的那样,似乎还没有一种完美的方法来做到这一点

您可能还想查看pattern.en(另请参阅他们的 GitHub 存储库)。他们的

mood()函数尝试将解析的句子识别为指示性、命令性、条件性或虚拟语气

于 2013-09-08T17:37:29.467 回答
0

我建议您使用spacy中可用的“基于规则的匹配器” ,它提供了标记匹配器、短语匹配器、实体标尺等选项。我已经使用 Token Matcher 指定模式(去 + 到 + 地方),它工作得很好。

token_pattern = [{"LEMMA": "go"}, {"POS": "ADP"}, {"POS": "PROPN"}]

这种模式会找到“去纽约”或“去纽约”或“和玛丽一起去”等。

此外,如果您只想提取示例中的“旧金山”、“123 Main Street”等名词,NER(命名实体识别)可能会有所帮助。

于 2021-09-17T10:07:52.417 回答
0

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

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

于 2021-09-17T08:56:21.117 回答