RASA Chatbot:Parallels体验



聊天机器人行业正在蓬勃发展。 刚开始他们很愚蠢,可以与用户进行对话,领导并提供可能的答案。 然后,机器人变得更聪明了,并开始要求用户输入文本,以使答案中没有关键字。 机器学习的发展导致人们也可以通过语音与机器人通信。 但是,大多数解决方案与对话图的相同构造及其通过关键字在其节点之间的过渡没有很大的距离。

最近,在Parallels,我们决定优化一些内部流程,并创建一个满足自己需要的机器人作为实验。 经过短暂的搜索,我们决定尝试使用RASA开源项目。 根据开发人员自己的说法,他们制作了第三代聊天机器人。 也就是说,该机器人不仅可以绕过状态图,还可以保存和使用前一个对话框的上下文。 迄今为止,现代聊天机器人的最佳插图如下所示:



也就是说,聊天机器人只是一组用于从图形中的一个点移动到另一个点的经过验证的规则。 如果您查看市场巨头的现有解决方案,则实际上与那里的规则集没有什么大不同。 粗略地说,这个集合看起来像这样:

在XXX点的对话。
如果用户输入带有['buy','ticket']字样的报价,请转到“在哪里问”
如果用户输入的报价为['buy','cutlet'],请转到“从以下地方询问”

如果用户输入:“我想买一张去波尔图的票,”他们仍然会问他“你要去哪里?”,这显然是垃圾。 为了使对话更加人性化,您必须添加新的规则,以在有位置指示的情况下进行操作。
然后添加有关指示时间和地点的操作规则,依此类推。

这套规则会足够快地增长,但这并不是最坏的事情,所有“正确”的方式都可以得到描述,改进和完善。

最让人不愉快的是,与机器人不同,一个人是一个无法预测的生物,可以随时开始提出完全不同的要求。 也就是说,在机器人已经准备好预订机票的时候,人们可能会问“顺便问一下,天气怎么样?” 或“尽管不是,我想开车兜风,路要走多久?”

但是,他也可以在选择城市之后,但在选择出发时间甚至选择他想去的地方之前询问。 基于状态机的漫游器将卡住,其机械伪脚将令人不安地抽搐,从而使用户感到沮丧。

在这里您可以(并且应该)使用机器学习。 但是随后出现了新问题:例如,如果您使用强化训练来预测到图形点的过渡,则会出现问题:在哪里可以获取此训练的数据,谁来评估答案的质量?

用户不太可能同意教您的机器人,并且如实践所示,用户社区可能根本不教您想要什么以及社会认为像样的机器人。 此外,该机器人在初始阶段将完全无法响应,这将使用户感到紧张,并且在原则上不会破坏此类支持。

在分析并考虑了现有机器人的所有缺点之后,RASA开发人员试图解决以下问题:

  • 来自用户的任何输入都经过“意图确定”,即,使用机器学习输入的文本被映射到一个(或几个)意图。 另外,如有必要,实体与文本隔离,并添加到机器人的内存中。
  • 除了使用的意图确定模型外,此过程与其他漫游器相似。
  • 根据上下文使用机器学习来预测机器人的下一个动作,即机器人的先前动作,意图和内存状态。
  • 同时,初始培训不需要太多数据,即使没有特定的示例和规则,该机器人也可以完全预测要执行的操作。

更详细地考虑工作机制。

拉萨国家大学


让我们从机器人赖以生存的第一条鲸鱼开始。 这是一种自然语言理解,包括两个主要部分:意图的确定和实体的识别。

目的检测
意向确定基于Tensorflow上实施的Facebook改进算法StarSpace。 在这种情况下,不使用单词的矢量表示的预训练模型,这使您可以规避这些表示的限制。

例如,在RASA算法中确定意图对于任何语言以及您在培训示例中指定的任何特定单词都适用。 当通过预先训练的矢量表示形式(例如GloVe或word2vec)实施时,该机器人的本地化及其在高度专业化领域的应用将带来足够的麻烦。

该算法在通过单词袋对句子进行矢量化并比较它们的“相似性”的基础上工作。 使用单词袋将意图和意图本身的示例转换为向量,并将其馈送到相应神经网络的输入中。 在神经网络的输出处,针对该特定单词集(相同的嵌入)获得一个向量。

训练以这样的方式进行:以两个相似矢量和k个相似矢量之间的成对距离(余弦或矢量乘积)之和的形式最小化损失函数。 因此,在训练之后,某个向量将与每个意图相关联。

收到用户输入后,提案将进行类似的矢量化处理,并遍历经过训练的模型。 此后,计算从所得向量到所有意图向量的距离。 对结果进行排名,突出显示最可能的意图并消除负值,即完全不同。

除了上述包子之外,这种方法还可以使您自动从提案中区分出多个意图。 例如:“是的,我了解这一点。 但是我现在怎么回家?” 识别为“ intent_confirm + intent_how_to_drive”,它使您可以与该机器人建立更人性化的对话框。

顺便说一句,在培训之前,您可以通过混合现有示例来增加示例数量,从而从示例中创建人工语句。

RASA实体识别


NLU的第二部分是从文本中提取实体。 例如,一个用户写道:“我想和两个朋友一起去一家中餐馆”,该机器人不仅必须突出意图,还必须突出对应的数据。 也就是说,请记住,餐厅里的菜应该是中国菜,游客人数是三。

为此,使用了基于条件随机场的方法,该方法已经在哈布雷(Habré)上的某处进行了介绍,因此我不再赘述。 希望的人可以在Stanford网站上阅读有关此算法的信息

此外,我注意到您可以从基于模板的文本,文本(例如城市名称)中获取实体,以及连接到单独的Facebook Duckling服务,这也总有一天会写得很好。

RASA的故事


RASA Core所基于的第二条蓝鲸是故事。 故事的一般本质是与机器人进行真实对话的示例,其格式为意图反应。 基于这些故事,训练了循环神经网络(LSTM),该神经网络将先前的消息历史记录映射到所需的操作。 这使您不必严格设置对话框图,也不必确定所有可能的状态和它们之间的过渡。

通过足够数量的示例,网络将充分预测过渡的下一个状态,而不管是否存在特定示例。 不幸的是,有关此故事的确切数目尚不清楚,并且所有可以作为指导的是开发人员的短语:“越多越好”。

要训​​练系统,而不仅仅是在此处记录一些发明的对话框,还可以使用交互式训练。

有两种选择:
1.让许多工程师与机器人进行对话,纠正错误的预测,对实体的错误定义以及对故事进行预测的动作。

2.将对话保存到数据库中,然后继续使用经过专门培训的工程师查看用户无法解决他的问题(即切换到某个人,或者漫游器承认他的无助且无法回答)的那些对话框。

为了理解故事的机制,最简单的方法是解析一些简单的例子。 假设在餐厅预订餐桌,这是开发人员在“源代码示例”部分中提供的示例。 首先,我们将确定我们的意图,然后我们将讲述两个故事。

意图及其示例:

Intent_hello
  • 你好
  • 你好
  • 阿罗哈
  • 早安

...
Intent_thanks
  • 谢谢啦
  • 好啊
  • 谢谢啦

...
Intent_request
  • 再见跳过

Intent_inform
  • 再见跳过

接下来,您需要放置机器人的内存,即确定将记录用户需求的插槽。 定义插槽:

美食:
类型:未完成
自动填充:false
num_people:
类型:未完成
自动填充:false

现在,我们将展示一些示例(一小部分)以说明上面省略的意图。 示例中的括号是用于训练Ner_CRF的数据,格式为[实体](存储的变量名称:我们存储的内容)。

intent_request_restaurant
  • 我正在寻找餐厅
  • 我可以为[六个人]获取[瑞典式](美食)食物吗?(num_people:6)
  • 一家供应[加勒比](美食)食品的餐厅
  • 像餐厅一样的身份证
  • 我正在寻找一家供应[地中海式](美食)食品的餐厅

intent_inform
  • [2](人数)
  • 为[三](人数:3)人
  • 仅仅[一个](人数:1)人
  • 怎么样[东方东方](美食)
  • 那(印度)美食呢?
  • 呃,[土耳其](美食)类型的食物怎么样
  • 嗯(英语)(美食)

现在我们确定主要路径的历史:

*打招呼
-utter_greet
* Intent_request
-restaurant_form
-形式{“ name”:“ restaurant_form”}
-形式{“ name”:null}
-action_book_restaurant
*谢谢
-utter_noworries

这就是完美世界的完美机器人。 如果用户在第一句话中立即指出了所有必要的数据,则将保留一个表。 例如,他写道:“我想在西班牙餐厅预订5个人的桌子”。 在这种情况下,num_people将为5,并且美食-西班牙文,这足以使漫游器可以对预订进行进一步的操作。

但是,如果查看示例,您会发现数据并不总是以所需的数量出现,有时甚至根本不存在。 因此出现了非核心对话。

假设请求中没有关于厨房的数据,即类似于以下对话框:
你好
你好
我想预定五个人的餐厅
...

为了使其正确完成,您需要确定以下表单的历史记录:
*打招呼
-utter_greet
* Intent_request
-restaurant_form
-形式{“ name”:“ restaurant_form”}
-广告位{“ requested_slot”:“ num_people”}
-utter_ask_coven
*形式:告知{“美食”:“墨西哥”}
-广告位{“美食”:“墨西哥”}
-形式:restaurant_form
...

最好的部分是,如果您为多个厨房创建故事,那么遇到陌生人时,该机器人会自行预测下一步的行动,尽管不确定。 同时,如果您创建了一个类似的故事,但是在其中填充了“ cuisine”(烹饪)插槽而不是“ num_people”(插槽)插槽,则该漫游器绝对不会在乎将以何种顺序提供有关表保留参数的信息。

有两种方法可以阻止试图引导机器人通过正确途径进行的任何尝试:识别可能的故事以谈论“什么都不做”,或者阻止所有尝试进行此类对话的尝试-回答值得重新做生意。

由于我们公司正处于进入聊天机器人世界的惊人旅程的开始,因此有可能会有新的文章介绍我们收集的耙子和所做的事情。 敬请期待!

Source: https://habr.com/ru/post/zh-CN470754/


All Articles