终于来到pipeline任务型对话系统的最后一个模块,也就是自然语言生成,这次就来简单看一下自然语言生成到底在做什么。
其实自然语言生成和自然语言理解几乎可以看成是一个逆过程,因为自然语言理解就是把人类的语言翻译成机器能理解的语言,而自然语言生成则是把机器内部处理的结果翻译成人类能理解的语言,所以这两个模块就像是人类和机器交流的翻译员。
根据输入数据形式的不同,自然语言生成可分为数据到文本的生成和文本到文本的生成,数据可以是语义数据、图像数据等等不同的类型。而从实际应用来说,文本到文本就有机器翻译、摘要生成这些应用,数据到文本就有图像说明之类的应用。
但是在这里,我们还是按照模型的类型,把NLG分为两类,一类是pipeline,一类是integrated,前者就是包含了多个模块,数据经过各个模块处理得到最终输出,而integrated则类似于end to end,不区分模块,直接用完整一个模型处理输入得到输出。
首先来看看pipeline,主要分为六个步骤,第一步是内容确定,这一步的目的是确定在生成的文本中应该包含什么信息,应该不包含什么信息,以任务型对话系统为例,之前我们在NLU和DST中得到了state,然后在DPL处理了action的结果,就是模型最终需要输出的内容,比如一个订机票系统,查询机票得到了机票的信息,这些信息就是应该包含在输出语句的内容。
第二步是文本结构,这是为了合理地组织文本的顺序,或者说合理地安排先展示哪些信息,再展示哪些信息。
第三步是句子聚合,不是每一条信息都需要一句话去表示,所以这一步的作用就是对信息进行类聚,把可以合并的信息用一句话表示出来。
通过前三步,已经确定出需要生成几句话,每句话带有什么信息,信息是以什么样的顺序进行表达的,而第四步就是语法化,引入一些具有连接作用的词汇,方便后面构成一个句子。
第五步称为参考表达式生成,目的是选择内容领域相关的词汇进行修饰调整,但是来到这一步,每一个句子依然是一个词汇的集合,而并未构成真正的句子。
所以第六步,也是最后一步的作用就是把之前的句子集合正式转化为一个完整的结构良好的句子。
以上这个pipeline在挺多综述中都可以看到,接下来还有另一个pipeline,来自2002年的一篇论文的模型plan-based NLG,把NLG分为三个部分:sentence plan generator、sentence plan reranker和surface realizer,在sentence planning阶段生成sentence planning tree,每个node是对话的action,在surface realizer阶段把SPT转换为最终要生成的句子。
除了pipeline,我觉得在现在的大环境下,NLG应该一般都是使用integrated方法,也就是最常见的seq2seq、transformer和bert,这些模型每个都值得用一篇文章细说。
最后我还想谈一个问题,那就是如何从数据生成文本,因为我觉得数据生成文本这种情况在对话系统中更常见,比如之前提到pipeline任务型对话系统,经过DPL处理了action后,就可能得到一些数据,而不是单纯的文本,比如说一些航班信息"时间:三月十号,出发地:北京",像这样的数据信息如何用一句或者几句话表示,或许在对话系统中更加常见。
针对上述的问题,从pipeline生成的角度来说,我觉得得到的信息对应了pipeline中的第一步,然后我们只要继续遵循其他步骤就能最终的结果,而对于integrated模型,我想到的是seq2seq,它的encode阶段会基于输入分析出一个语义向量state,然后在decode阶段会基于state生成句子,如果我们把要处理的数据输入到神经网络进行处理,转换成特征向量,就能看作是seq2seq的state,就可以指导生成最终的回复。
当然上述的方案只是我个人的一些想法,但是也说明了其实实现的方法很多,到底应该如何把现在的模型结合到NLG中,也是一个很有趣的地方。
在github写的自然语言处理入门教程,包含汇总的博客文章和相应的模型代码:NLPBeginner
最近开始研究对话系统,还在探索当中,学习笔记也会在github上整理更新:HowToCreateHomunculus