自从iPhone 4S开始内置Siri,到现在各种智能音箱,或者扎克伯格说自己做的智能管家,
我认为都算是对话机器人的一类。
以苹果的Siri和亚马逊的Echo为例,它实际上是一套非常复杂的智能系统,而对话机器人是其中一个界面。
有些文献或者商业机构把这部分称为Conversational UI(对话界面),也就是说我们通过对话来与机器沟通。
遗憾的是,本文和本文的后续文章,都不可能说清楚怎么完整的做出一个Siri或者Echo,
它们的背后都是由成百数千名工程师、学者,在无数的各种资源支持下,动用几十个、上百个很多不同的工程技术的叠加组合而成的。
本文会探讨各种简单的对话机器人技术,而这些技术,每个往往只能完成一个及其特定的功能。
岔开话题的话,在科学上,“怎么实现一个机器人”,是一个太宽泛的问题,往往此类问题都会被分解为若干个小问题。
例如:怎么让实现让机器人能回答单个问题?怎么实现让机器人能回答连续的问题?怎么让机器人帮我买咖啡?
而一个学术领域往往是一个子问题的最新、最优解,而工程上我们往往需要结合不同领域的成果构建一个可用系统。
最简单的问答系统就是当我们有足够多的问答数据,例如:
中国的首都是哪?
北京。
当数据足够多的时候,一个最简单的问答实现,就是去匹配问题的相似度。
例如用户问:中国的首都
假设我们在python中计算编辑距离的话,会发现“中国的首都”这个问题和
我们数据库中已有的问题“中国的首都在哪”很相似(距离只有2,可以粗暴理解为只差两个字)。
>>> from nltk.metrics import distance
>>> distance.edit_distance('中国的首都', '中国的首都在哪')
2
那么我们直接给用户这个问题的答案就好了,就可能有足够高的成功率。
当然这个看上去很简单粗暴的解决方案有很多问题,例如:
1、准确率取决于相似度算法;
2、很难设置相似度算法的阈值;
3、数据库要求比较大;
4、扩展性比较差;
但是实际上在真实世界中,往往必须有一部分上这个算法,因为这个算法同样有优势:
1、不需要训练,假设你的领导要你给线上产品添加一个问答的时候,他并不喜欢:“我的深度学习模型训练5个小时之后,这个答案就上线了”,这样的回答;
2、自定义问题成本低;
3、非常容易解释;
4、对于完全匹配的问题可以绝对准确,如果是其他的概率模型的话,就必然有可能不准确,而简单的模型不会出错;
简单的来说,可以分为“有数据”的问答系统,和“没数据的问答系统”。
有数据的是指,我们已经有一些已经结构化的数据,或者说知识。
例如我们的问答系统就想回答关于国家与城市的问题,
那么我们可以假设自己已经有了很多关于国家、城市、国家与城市之间关系的知识。
“有数据”的问答系统是指,例如你有一堆可以查询的知识。
一种常见的知识存储方法,就是三元组:
(中国,有首都,北京)
(北京,是某国的首都,中国)
(英国,有首都,伦敦)
(伦敦,是某国的首都,英国)
在上面的前两个三元组中出现了两个实体(entity),分别是北京和中国。
总过出现了两个关系,分别是“由首都”和“是某国的首都”。
从字面意义上来讲,他们可以解决“中国的首都是哪?”和“北京是哪个国家的首都?”这两个问题,
也就是根据一个关系和一个实体,查询另一个实体。
当然也可以解决“北京和中国的关系”这样的问题,也就是根据已知的两个实体,查询他们的关系。
从学术上来讲,这个领域叫做 Knowledge-Based Question Answering 也就是我们有了知识,
需要在上面构建一个问答系统。
题外话,上哪能弄到这些知识呢?
一般来说很多问题是在其他领域工作中,已经有了类似数据的积累。
或者是利用别人收集的数据,例如一些开放的中文知识图谱,例如英文世界的freebase。
还有或者就自己尝试制造这样的数据,例如从维基百科、从百度百科中获取。
或者……发挥想象力。
在知识图谱建模的领域,有一种称为SPARQL的语言,类似关系数据库查询的SQL语言,
例如我们要查询(中国,有首都,北京) 中的北京,则SPARQL可以写为:
Select ?x where {
中国, 有首都, ?x
}
也就是问题转换为,如何把一句自然语言“中国的首都是哪?”,转换为上面的SPARQL语句?
例如现在的一些方向是利用统计机器学习的翻译任务,完成从“自然语言”到“SPARQL”语言的机器翻译任务,就如同中英翻译等自然语言之间的翻译一样,同样也可以做到的。但是根据语料数据、SPARQL复杂度等等问题,也会有其他各种问题。
当然也有不依赖SPARQL作为中间件的查询系统,例如有的文献设计了一套在知识图谱中逐渐搜索(探索)的系统;
以这个问题为例,起始点可以是实体“中国”,中国这个实体可能有很多关系,例如有首都、有文化、有省份、有xxx,然后搜索下一步最合理的关系“有首都”;
最后探索到答案“北京”,判读任务完成。
更多细节本文不再讨论。
IR-based 问答系统 (IR: Information Retrieval)
此类问答系统不需要提前构建知识,而是根据问题去检索答案(例如从搜索引擎上)。
此类问答系统从某种意义上类似人的搜索方式,例如我们想知道“中国的首都是哪”,
可能会去搜索引擎中搜索这个问题,而答案很可能会出现在搜索结果中,
我们知道这个答案的类型很可能是“某个城市”,所以我们会在搜索引擎给我们的结果中,
寻找一个城市名。
而机器也可以完成类似过程,首先根据问题来尝试判断答案类型,这里同样也可以判断结果类型为城市。
然后机器可能需要对问题进行重构,也就是寻找一个搜索问句,能找到答案的几率最大,
例如这个问题可能被重构为:“中国 首都 城市”。(最后添加了这个词城市,是因为我们假设可以准确判断出答案类型)
然后机器去自有的非结构化文档(没有知识图谱化的文档,例如各种纯文本文章),从中寻找最接近我们重构后问题的段落。
或者去搜索引擎、百科网站等等,搜索答案、或者检索问题相关的段落。
定位到这个段落后,根据答案类型(这里是城市),尝试从这个段落中筛出答案。例如我们去搜索引擎搜索“中国的首都”,很可能第一个答案段落中的第一个出现的城市名就是我们所需要的答案。
这里的对话系统特指 Task-Oriented Dialogue System,
也就是让机器人帮助实现一种特定任务的系统,
有一文献提到的 General Dialogue System 的系统,往往指类似 Chit Chat 的系统。
一般此类对话系统的研究都基于如何让机器人在有限步骤内完成可以完成的任务的系统,并且结果往往定位到一个单一实体。此类系统的一个隐含假设往往是通过电话、文字、语音来进行人机交互,也就是没有什么“点击按钮”,“从多个选项选择”,之类的交互方式。当然在一些类似对话系统演变的工程实践中,是有类似的实现的。
因为这个关于“必须文字交互”的假设,所以实际上有些问题并不适合基于这种假设的对话系统完成。例如你在一些手机软件中搜索餐厅,结果可能会返回多家餐厅(餐厅本身即实体),他们都有名称、地址、电话等等信息(这些也可以称为餐厅这个实体的属性,当然也可以是与餐厅这个实体有关的其他实体)。而你想要通过语音、朗读的文字来获得这个列表,就显得很愚蠢了,不会有人想听机器人读5分钟搜索结果的20家餐厅然后决策吧?所以此类系统往往最后是推荐单一实体,例如结果排名最高的餐厅,如果你需要更换,可以跟系统说换一下餐厅。
一个典型的对话系统的交互过程是这样的:
用户:你好(User Dialog Act:greeting)
机器:你好,我可以帮助你搜索并预订餐厅(Sys Dialog Act:greeting)
用户:我想要找一家在中央公园2.0附近的意大利餐厅(User Dialog Act:inform(地址=中央公园2.0,口味=意大利))
机器:请问你想要在中央公园2.0附近什么价位的意大利餐厅?(Sys Dialog Act:request(价位))
用户:普通的就好(User Dialog Act:inform(价位=普通))
机器:我知道那里有一家柯南家的老意大利料理餐厅(Sys Dialog Act:inform(名称=柯南家的老意大利料理))
用户:换一个(User Dialog Act:alter())
机器:我知道那里有一家意大利油泼面餐厅(Sys Dialog Act:inform(名称=意大利油泼面))
用户:它家的价格怎么样?(User Dialog Act:request(价位))
机器:意大利油泼面的价位是普通(Sys Dialog Act:inform(价位=普通))
用户:就这家吧,帮我预订(User Dialog Act:order())
机器:请问有几个人?(Sys Dialog Act:request(人数))
用户:单身狗(User Dialog Act:inform(人数=1))
机器:真的就1个人吗?(Sys Dialog Act:confirm(人数=1))
用户:是的(User Dialog Act:confirm())
机器:已经预定成功(Sys Dialog Act:order_success())
用户:好的,再见(User Dialog Act:bye())
机器:再见,欢迎下次使用(Sys Dialog Act:bye())
Dialog Acts 如果是用户发起的(User Dialog Act),
那么它是一种处理后的用户意图的抽象表达,是一种形式化的意图描述。
The dialog act expresses an important component of the intention of the speaker (or writer) in saying what they said
系统发起的行为(Sys Dialog Act),是根据用户行为,上下文信息等等综合得出的,
下一步所要进行的操作的抽象表达,这个抽象表达后续会送入NLG部件,生成自然语言。
Asking questions, giving orders, or making informational statements are things that people do in conversation, yet dealing with these kind of actions in dialogue what we will call dialog acts is something that the GUS-style frame-based dialog systems
GUS对话系统,是 Genial Understander System 的缩写,可以追溯到1977年的论文(Daniel G. Bobrow, GUS, A Frame-Driven Dialog System, 1977)
常见的不同意图有:
用户的greeting:问好
用户的inform:用户提供一个信息,例如想要的餐厅的地址
用户的request:询问一个信息,例如当前结果餐厅的电话
用户的confirm:确认信息正确(例如上一条是机器问你对不对)
用户的bye:结束对话
机器的greeting:问好,也可以是自我介绍
机器的inform:提供机器知道的信息,例如当前结果餐厅的信息
机器的request:机器必须有足够的信息才能完成任务,如果欠缺一些必须信息,例如餐厅地址、口味,则会向用户询问
机器的confirm:根用户确认信息是否正确
机器的bye:结束对话
上文还出现了一些可能的特殊意图,例如:
用户的order:确认订餐
用户的alter:更换检索结果
系统的order_success:反馈订餐成功
整个对话系统,就是为了完成某个特定任务,这个任务所需要的特定条件需需要由用户提供(例如帮助买咖啡需要咖啡品种,热或冷等信息),当信息足够的时候,机器就能完成相应任务。
这个过程总结就是:
用户说了什么 =》
分析用户意图 =》
生成系统的对应意图(操作)=》
用户听到了系统的反馈 =》
用户说了什么(第二轮)=》
…………
当然根据任务复杂度、和其他系统结合等等问题,
对话系统本身也有各种的不同准确度与实现方式。
聊天机器人往往是没有一个明确目的,或者目的比较模糊的系统。有别于问答系统和对话系统,前两者的一个期望是用户尽可能得到信息后离开,快速找到想要的回答或者快速完成任务,是尽可能在减少与用户的交流时间。而聊天机器人往往设计上需要尽可能的占用用户时间,尽可能的延长与用户聊天、陪伴的时间,或者尽可能的再次让用户使用。
聊天机器人本身也可以是有一定目的的,不过是比较宽泛的目的。例如最近融资成功的woebot,它的目的是可以一定程度上跟踪用户心理状态、帮助用户调整自己的心理状态等等,有一定程度的心理医学性质。
最开始的希望通过图灵测试的机器人系统都有类似闲聊机器人的特征,例如Eliza(1964),或者Alicebot(1995)。
它们主要通过模板特征实现,也就是人工定义对话模板,产生类似智能的效果。
这样的机器人模板其实可以很多,例如Alicebot有超过六万条AIML模板来覆盖绝大部分日常对话。
AIML,即人工智能标记语言,是用来通过定义模板实现机器人(闲聊)的一种方法。
模板方法是机器人相关实现的最重要的方法(没有之一),实际上在绝大多数的对话系统中都依然存在(Siri,小冰),并且在一些学术文献上被证明与其他系统相比依然拥有更好的效果(例如与 Neural Conversation 模型相比)。
与模板方法相对的,是基于深度学习的 Neural Conversation 模型,是一种基于神经机器翻译技术演变而来的对话生成模型。类似机器翻译,例如一句英文翻译为一句中文,对话中,上一句对话也可以“翻译”到下一句对话;类似的还有作诗机,上一句诗“翻译”出下一句诗。
本质是根据统计学方法进行的一种文本生成,这种文本生成往往会生成语法正确的句子。
但语义、逻辑、一致话、发散性等地方会有问题。例如:
人格不一致:
Q:你今年几岁
A:我5岁了
Q:你今年多大?
A:我马上就满18了
语法正确但语义有问题:
Q:你想做我的女朋友吗
A:我是我的女朋友
发散性差,本质机器倾向于回答简单又不容易出错的回答,相当于机器学会了一种投机取巧的方法:
Q:你喜欢我吗
A:我不知道
Q:今天天气不错
A:我不知道
Q:你是谁啊?
A:我不知道