Python 聊天机器人构建指南(一)

原文:Building Chatbots with Python

协议:CC BY-NC-SA 4.0

一、可爱的聊天机器人

当你开始构建聊天机器人时,了解聊天机器人做什么和它们看起来像什么是非常重要的。

你一定听说过 Siri,IBM Watson,Google Allo 等。这些机器人试图解决的基本问题是成为一个中介,帮助用户变得更有生产力。它们通过允许用户更少地担心如何检索信息以及获取特定数据可能需要的输入格式来做到这一点。随着机器人处理用户数据输入并从中获得更多见解,它们往往会变得越来越智能。聊天机器人之所以成功,是因为它们能给你想要的东西。

当您每次在不同的网站上必须输入相同的姓名、电子邮件 ID、地址和密码时,您是否感到恼火或沮丧?想象一下,一个单独的机器人来完成你的任务——比如,从不同的供应商那里订购食物,从各种电子商务公司在线购物,或者预订机票或火车票——并且你不必每次都提供相同的电子邮件 ID、送货地址或支付信息。机器人有能力知道这些信息,并且足够聪明,当你用自己的语言或计算机科学中称为自然语言的语言询问时,它可以检索到所需的信息。

聊天机器人的开发比几年前容易多了,但是聊天机器人在几十年前就已经存在了;然而,聊天机器人的受欢迎程度在过去几年里呈指数级增长。

如果你是一个技术人员,或者对 web 应用程序或移动应用程序的工作原理有所了解,那么你一定听说过术语 API。您今天需要的任何类型的数据都可以以不同服务提供商和机构提供的 API 的形式使用。如果你在寻找天气信息、订票、点餐、获取航班信息、将一种语言转换成另一种语言,或者在脸书或 Twitter 上发帖,所有这些都可以使用 API 来完成。基于 web 或移动设备的应用程序使用这些 API 来完成这些任务。聊天机器人也可以根据我们的请求使用这些 API 来完成相同的任务。

聊天机器人比传统的在线完成事情的方法更有优势的原因是你可以在聊天机器人的帮助下做多件事情。它不仅仅是一个聊天机器人,它就像你的虚拟私人助理。你可以在 booking.com 上预订一个酒店房间,也可以在酒店附近的餐厅预订一张桌子,但是你可以使用你的聊天机器人。聊天机器人满足了多用途的需求,因此节省了大量的时间和金钱。

在本书中,我们将学习如何使用机器人建立自然的对话体验,以及如何教机器人理解我们的自然语言,并让它从单一界面为我们完成任务。

一般来说,机器人只不过是一台足够智能的机器,可以理解你的请求,然后以其他软件系统可以理解的方式制定你的请求,以请求你需要的数据。

聊天机器人使用的普及程度

聊天机器人变得流行起来,就像最近的事情一样。让我们试着看一下图 1-1 ,图中描绘了聊天机器人的崛起,同时也试着理解为什么对构建聊天机器人有巨大的需求。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-1

Y 轴上的数字表示相对于图表最高点的全球所有类别的搜索兴趣

想到的简单答案是,这不是一个复杂的软件,任何人都可以使用。当我们构建软件时,我们的目标是将使用它的受众,但是当它被其他任何人使用时,它就变得困难和不可用了。当我们开发聊天机器人时,我们牢记它将被所有年龄段的人使用。这种情况只发生在聊天机器人身上,这种软件试图表现得像一个哑巴(但它是智能的),让用户做他或她自己。在所有其他软件中,你会发现你应该知道一些术语,或者逐渐知道如何最佳地利用它,但聊天机器人不是这样。如果你知道如何与人交谈,使用聊天机器人就不会有任何问题。

对聊天机器人的需求持续增长。然而,还没有太多的研究从经验上试图找出使用聊天机器人背后的动机。在最近的一项研究中,一份在线问卷调查了美国 16 至 55 岁的聊天机器人用户,询问他们在日常生活中使用聊天机器人的需求。调查显示“生产力”是使用聊天机器人的主要动机。

Python 的禅以及为什么它适用于聊天机器人?

我记得 Python 的禅,它说,“简单比复杂好”,这适用于软件中的许多地方。

Python 的禅是影响 Python 编程语言设计的 20 个软件原则的集合。

—蒂姆·彼得斯

想知道“Python 的禅是什么?"试试下面的步骤。

如果您的计算机上已经安装了 Python。只需进入您的 Python 解释器并import this:

Python 2.7.15 (default, May  1 2018, 16:44:08)
[GCC 4.2.1 Compatible Apple LLVM 9.1.0 (clang-902.0.39.1)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one—and preferably only one—obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea—let's do more of those!

你可能无法理解以上所有关于聊天机器人的观点,但你肯定能理解其中的大部分。

好吧,回到我们的话题,我记得当我来自 Orkut 背景时,开始使用脸书用户界面时遇到了困难。如果你从未使用过 Orkut,你不会理解它,但是试着想想你生活中的一个情景,你开始使用一些新的软件或应用程序,你很难掌握它的窍门。也许从 Windows 切换到 MacOS/Linux 或者相反?当你使用一个新的应用程序时,你需要学习一些东西,这需要时间来适应它,并知道它做什么和如何工作。有时,即使在使用了几年之后,您还是会知道这个应用程序的一些特性。如果你在 MacOS 上,试试 Shift + Option +音量调高/调低,看看会发生什么。如果这让你感到惊讶,如果你还不知道,请告诉我。

就聊天机器人而言,用户和服务器或后端系统之间的通信非常简单。这就像使用消息应用程序与其他人交谈一样。

你只需键入你想要的,机器人应该能够给你你想要的,或者应该指导你如何得到它。换句话说,它应该通过给你一个链接或文档来给你指出正确的信息。机器人甚至能够从文章和文档中挖掘信息并提供给用户的时代已经到来。

谷歌、脸书和 IBM 等公司以及亚马逊 Lex、wit.ai、api.ai、luis.ai、IBM Watson、亚马逊 Echo 等机器学习服务在人工智能方面取得了重大进展。导致了这种机器人的惊人增长和需求。

对聊天机器人的需求

现在,我们将尝试从两个不同的角度来看待聊天机器人在这个快速发展的信息创建和检索时代的需求:商业角度和开发者角度。因此,如果你是产品经理、销售经理,或者来自市场营销或任何直接推动业务的相关领域,那么你不应该跳过聊天机器人的业务视角。它将让您清楚地了解当今的企业需要采用这项技术来增加收入。

商业视角

我们将尝试从商业的角度来看待聊天机器人。对于一个企业来说,拥有一个聊天机器人或者将大量的工作转移到聊天机器人身上是好的吗?

企业将聊天机器人视为这一代营销工具之一的时机已经到来。

  • 可访问性:它们很容易访问。消费者可以打开网站,开始提问或开始解决他们的疑问,而不必拨打号码,并遵循 IVR 中“按 1 这个,按 2 那个”的丑陋方式。他们只需要一组基本的信息就能很快抓住要点。

  • **效率:**顾客可以坐在办公室的办公桌前或客厅的沙发上观看比赛,并获得信用卡申请状态,查找食品订单状态,或对任何问题提出投诉。

如果你让客户变得高效和多产,他们就会开始喜欢你。机器人正是这样做的,并有助于促进业务。

  • 可用性 : 聊天机器人每周 7 天、每天 24 小时都可以使用。他们永远不会向你请假,也不会像人类员工一样累。他们每次都会以同样的效率和表现完成同样的任务或新任务。当一些客户服务电话号码说,“请在上午 9:00 到下午 6:00 之间打电话给我们”,只是为了一条信息时,你一定很沮丧。你的机器人永远不会这么说。

  • 可扩展性**😗*One Bot =>100 万员工。你看到这个了吗?是的,如果你的机器人可以做客户需要的事情,它可以轻松地同时处理成千上万的客户查询,而不用担心。你不需要让你的客户排队等候,直到客户代表有空。

  • 成本 : 不用说,它为企业节省了大量成本。谁不喜欢省钱?当机器人为你做这些的时候,你没有理由不喜欢它们。

  • 洞察力 : 你的销售代表可能无法记住用户的行为,并为你提供关于消费者行为模式的独家见解,但你的机器人可以使用机器学习和数据科学的最新技术。

聊天机器人带来收入

事实证明,聊天机器人成功地为企业带来了更多收入。与竞争对手相比,以聊天机器人支持或创建新的聊天机器人来支持客户查询开始的企业在市场上表现良好。

根据 stanfy.com 上的一篇博文,在引入脸书聊天机器人后的头两个月,1-800-Flowers.com 报告称,超过 70%的 Messenger 订单来自新客户。这些新客户也普遍比该公司的典型购物者年轻,因为他们已经熟悉 Facebook Messenger 应用程序。这大大增加了他们的年收入。

聊天机器人最大的附加值之一就是利用它们创造潜在客户。你可以在潜在客户关注的地方直接接触他们(信使),并向他们展示你的最新产品、服务或商品。当客户想要购买产品/服务时,他/她可以在聊天机器人中进行购买,包括支付过程。1-800flowers.com、易贝和 Fynd 等机器人已经证明了这一点。

——Julien Blancher,联合创始人@ Recast。人工智能

在 ChatbotsLife 的创始人 Stefan Kojouharov 的一篇文章中,他提到了不同的公司如何比没有聊天机器人的公司赚更多的钱。他说,

电子商务领域已经开始以多种方式使用聊天机器人,这迅速增加了他们的利润。让我们看看早期的成功案例:

  • **1–800-Flowers:**报告称,超过 70%的 Messenger 订单来自新客户!

  • 丝芙兰:通过 Facebook Messenger 聊天机器人,她们的化妆预约增加了 11%。

  • Nitro Café: 通过他们的 Messenger chatbot,销售额增加了 20 %,该聊天机器人旨在方便订购、直接支付和即时双向交流。

  • **Sun 的足球:**聊天机器人通过特定的足球报道将近 50%的用户引回了他们的网站;43%的聊天机器人用户在其最好的时期点击进入。

  • Asos: 使用 Messenger 聊天机器人,订单增加了 300 %,获得了 250%的投资回报,同时接触到了 3.5 倍多的人。

图 1-2 试图让你了解为什么聊天机器人和收入之间有直接的关联。让我们看看图 1-2 来了解一下。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-2

聊天机器人带来收入

聊天机器人用法一瞥

我们将尝试看看聊天机器人因其可用性和效率对消费者有多大帮助。在这个炙手可热的 IT 时代,每个人都想在每件事上都快一点,使用聊天机器人让你的工作每天都变得更容易、更快。它是个性化的,不会重复显而易见的事情;这让我们重新思考软件的传统用法。图 1-3 提供了一个图解,应该可以让你对聊天机器人的使用有一个大致的了解。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-3

消费者使用聊天机器人一瞥

顾客更喜欢聊天机器人

聊天机器人不仅仅是现代的软件。聊天机器人就像我们的私人助理,理解我们,可以微配置。它们会记住我们的好恶,而且永远不会忘记我们已经教过它们的东西,这也是为什么每个人都喜欢聊天机器人的原因。下次你遇到一个人或者你的客户,不要忘记问他们是喜欢传统的软件还是新的尖端聊天机器人。让我们看一下图 1-4 来理解为什么相比其他人机交互软件系统,客户更喜欢聊天机器人。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-4

顾客更喜欢聊天机器人

在本章的下一节,我们将讨论为什么聊天机器人是初露头角的开发者的下一件大事。无论您是新手、中级开发人员还是有经验的 SME,您都必须了解开发人员在构建聊天机器人时可以使用什么。

开发者的视角

当你为了使用新功能而不得不更新电脑、手机或任何其他应用程序的操作系统时,你有没有感到痛苦?如果没有太多需要每次更新 app 才能使用新功能怎么办?或者说,不是有多个应用程序,而是可以有一个应用程序来完成当前由多个应用程序完成的大部分事情?

开发人员创建机器人很有趣。这就像教你的孩子走路、说话、举止和做事。你喜欢让它变得更加智能和自给自足。从开发者的角度来看,聊天机器人是一个非常重要的话题。

功能发布和错误修复

许多功能可以轻松地添加到聊天机器人中,而无需用户更新你的聊天机器人应用程序。如果你发布了一个有 bug 的应用程序版本,这可能是一件痛苦的事情,你必须修复它,并在 AppStore 中再次发布以获得批准,最重要的是,用户最终将不得不更新应用程序。如果他们不更新,那么客户会一直抱怨这个问题,这会导致每个人的生产力损失。在聊天机器人中,一切都是基于 API 的,因此您只需在后端修复问题,在生产中部署更改,然后就可以为您的用户解决问题,无需担心。您还可以从用户报告的错误中节省大量时间。

假设您构建了一个查找餐馆的机器人,然后您想添加搜索酒店、航班等的功能。用户可以很容易地请求这些信息,你的后台聊天系统会处理好一切。

假设你正在构建一个 Facebook Messenger 聊天机器人;你可以直接从你的后端控制几乎一切,包括用户在他的应用程序中看到的界面。在 Facebook Messenger 机器人中,你可以选择用户是点击一个按钮来说是/否,还是仅仅输入简单的文本。

市场需求

2016 年,全球 54%的开发者首次开发聊天机器人。构建一个适用于公司的简单聊天机器人有着巨大的需求,他们正在寻找能够为他们构建聊天机器人的开发者。一旦你完成了这本书的第三章,我打赌你可以很容易地开始向公司推销你的服务。你也可以在你擅长的领域里通过引入聊天机器人来创业。能够建立一个端到端的聊天机器人是一项新技能,这就是为什么聊天机器人开发者的平均市场薪酬也非常高。

对聊天机器人日益增长的需求可以从脸书等开发者平台上开发的聊天机器人数量中看出。脸书的 Messenger 平台上每月有 10 万个活跃的机器人,而且还在增加。你会惊讶地知道,2015 年 4 月,Messenger 的用户有 6 亿,2016 年 6 月增长到 9 亿,2016 年 7 月 10 亿,2017 年 4 月 12 亿。

学习曲线

无论你是来自前端/后端背景,还是对编程知之甚少,当你正在构建或学习构建聊天机器人时,有巨大的可能性去学习新的东西。在这个过程中你会学到很多东西。例如,你可以学到更多关于人机交互(HCI)的知识,它讨论计算机技术的设计和使用,重点是人和计算机之间的界面。您将学习如何构建或使用 API 或 web 服务,使用第三方 API,如 Google APIs、Twitter APIs、优步 API 等。你将有巨大的机会学习自然语言处理,机器学习,消费者行为,以及许多其他技术和非技术的东西。

受聊天机器人影响的行业

让我们快速浏览一下将从聊天机器人中受益最多的行业。Mindbowser 与 Chatbots Journal 联合进行的一项研究收集了 300 多名个人的数据,这些人来自广泛的行业,包括在线零售、航空、物流、供应链、电子商务、酒店、教育、技术、制造和营销&广告。如果我们看看图 1-5 中的图表,很明显电子商务、保险、医疗保健和零售是聊天机器人的最大受益行业。这些行业在很大程度上依赖于客户服务团队以节省时间的高效方式做出响应。鉴于聊天机器人在这方面的优势,很明显它将很快在这些行业大受欢迎。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-5

从聊天机器人中受益最多的顶级行业

此时此刻,聊天机器人仍然以不同的形式在较新的领域受到关注。未来 5 到 10 年将是聊天机器人在没有聊天机器人工作经验的不同行业传播信息的关键时期。

聊天机器人的简要时间表

让我们看看聊天机器人是如何形成的时间线的简史。了解聊天机器人技术的来源和形成过程非常重要。聊天机器人最近当然越来越受欢迎,但这种努力是利用这项技术几十年的工作来进行的。聊天机器人的历史肯定会让你惊讶,自从我们开始以来,我们已经走了多远。

One thousand nine hundred and fifty

图灵测试是由艾伦·图灵开发的。这是一项对机器表现出与人类同等或不可区分的智能行为的能力的测试。

One thousand nine hundred and sixty-six

第一个聊天机器人伊莱扎(Eliza)是由约瑟夫·韦岑鲍姆(Joseph Weizenbaum)创建的,旨在成为一名治疗师。它过去通过使用“模式匹配”和替代方法来模拟对话,给用户一种理解机器人的错觉。

One thousand nine hundred and seventy-two

精神病学家和斯坦福大学科学家肯尼斯·科尔比的计算机程序 Parry 模拟了偏执型精神分裂症患者的行为。

One thousand nine hundred and eighty-one

贾巴沃克聊天机器人是由英国程序员罗洛·卡彭特创建的。它始于 1981 年,并于 1997 年在互联网上推出。

这个聊天机器人的目的是“以有趣、娱乐和幽默的方式模拟自然的人类聊天。”

One thousand nine hundred and eighty-five

这款名为 Tomy Chatbot 的无线机器人玩具可以重复录制在磁带上的任何信息。

One thousand nine hundred and ninety-two

Sbaitso 博士是由 Creative Labs 为 MS-DOS 开发的聊天机器人,它用数字化的声音与用户“对话”,就像一个心理学家一样。用户反复的咒骂和错误的输入导致斯拜索博士在它能够自我重置之前就“崩溃”在“奇偶校验错误”中。

One thousand nine hundred and ninety-five

A.L.I.C.E(人工语言互联网计算机实体)是由诺贝尔奖获得者理查德·华莱士开发的。

One thousand nine hundred and ninety-six

由 Jason Hutchens 开发的 Hex 以 Eliza 为原型,于 1996 年获得了 Loebner 奖。

Two thousand and one

Smarterchild 是由 ActiveBuddy 开发的智能机器人,广泛分布在全球实例消息传递和 SMS 网络中。最初的实现很快发展到提供对新闻、天气、股票信息、电影时间、黄页列表、详细的体育数据以及各种工具(个人助理、计算器、翻译器等)的即时访问。).

Two thousand and six

沃森的想法是在餐桌上创造出来的;它被设计用来参加电视节目《危险边缘》的比赛。在第一次测试中,它只能获得大约 15%的正确答案,但后来沃森能够定期击败人类参赛者。

Two thousand and ten

智能个人助理 Siri 是作为 iPhone 应用程序推出的,然后集成为 iOS 的一部分。Siri 是 SRI 国际人工智能中心的副产品。它的语音识别引擎由 Nuance Communications 提供,Siri 使用先进的机器学习技术来运行。

Two thousand and twelve

谷歌推出了 Google Now 聊天机器人。它最初的代号是“Majel ”,以 Majel Barrett 命名,Majel Barrett 是吉恩·罗登伯里的妻子,也是《星际迷航》系列中计算机系统的声音;它的代号也是“助手”

Two thousand and fourteen

亚马逊发布了 Alexa。单词“Alexa”与 X 有一个硬辅音,因此可以更精确地识别它。这是亚马逊选择这个名字的主要原因。

Two thousand and fifteen

微软打造的虚拟助手 Cortana。Cortana 可以设置提醒,识别自然语音,并使用来自 Bing 搜索引擎的信息回答问题。它是以《光环》电子游戏系列中一个虚构的人工智能角色命名的。

Two thousand and sixteen

2016 年 4 月,脸书宣布了一个用于 Messenger 的机器人平台,包括用于构建聊天机器人与用户互动的 API。后来的增强包括机器人能够加入群体,预览屏幕,以及通过 Messenger 的摄像头功能将用户直接带到机器人面前的 QR 扫描功能。

2016 年 5 月,谷歌在该公司的开发者大会上发布了其亚马逊 Echo 竞争对手的语音机器人 Google Home。它使用户能够说出语音命令来与各种服务进行交互。

Two thousand and seventeen

Woebot 是一个自动化的对话代理,可以帮助你监控情绪,了解自己,让你感觉更好。Woebot 使用 NLP 技术、心理学专业知识(认知行为疗法【CBT】)、优秀的写作和幽默感的组合来治疗抑郁症。

使用聊天机器人可以解决什么样的问题?

当你不知道你的机器人的范围或者不想限制它回答查询时,这个问题变得具有挑战性。

记住聊天机器人的能力是有限的,这一点非常重要。它总感觉我们在和一个很智能的类似人类的东西对话,但特定的 bot 是被设计和训练成以某种方式表现的,并且只解决特定的问题。它不能做所有的事情,至少目前是这样。前途肯定是光明的。

所以,我们来看看你的问题陈述是不是真的很好,你可以围绕它建立一个机器人。

如果这三个问题的答案都是肯定的,那么你就可以走了。

问题可以通过简单的问答或者来回的交流来解决吗?

在解决任何对你来说非常新的问题时,不要逞英雄,这真的很重要。你应该始终致力于限制问题的范围。构建基本功能,然后在此基础上进行添加。不要试图在第一次切割时就把它复杂化。它在软件中不起作用。

想象一下马克·扎克伯格从一开始就大胆思考并花时间构建脸书的所有功能。给朋友加标签、有喜欢按钮、喜欢用户评论、更好的消息传递、实时视频、对评论的反应等等。—即使脸书在平台上注册用户超过 100 万,这些功能也不存在。如果他先构建这些功能,然后推出平台,他真的会成功吗?

因此,我们应该总是尝试创建只在当前需要的功能,而不必过度设计。

现在,回到第一个问题,“问题可以通过简单的问答或来回沟通来解决吗?”

你只需要保持你的范围有限,你的答案将是肯定的。我们并没有把自己局限于解决复杂的问题,而是明确地把自己局限于一次性解决一个复杂的问题。

“你必须让每个细节都尽善尽美。你必须限制细节的数量。”

—杰克·多西

它是否存在需要分析或获取数据的高度重复性问题?

这个问题很重要,因为无论是从商业的角度还是从开发者的角度来看,chatbot 所做的和被要求做的是让人们使用它变得高效和多产。你是怎么做到的?通过消除用户自己做重复事情的需要。

聊天机器人无疑更有能力自动化一些高度重复的东西,但你总是会发现大多数聊天机器人主要试图解决同一问题——无论是在监督下学习(阅读:“通过监督学习”)还是自学(阅读:“通过无监督学习”)。

你的机器人的任务可以自动化和固定吗?

除非你只是出于学习的目的而想建造一个聊天机器人,否则你应该确保你试图解决的问题可以自动化。机器已经开始自己学习和做事情,但这仍然是一个非常初级的阶段。你认为现在不能自动化的,几年后可能会自动化。

QnA 机器人

QnA 机器人是构建聊天机器人的问题陈述的一个很好的例子。想象一下,一个经过训练的机器人能够理解用户提出的各种问题,这些问题的答案已经可以在网站的 FAQ 页面上找到。

如果你回过头去试着寻找前述三个问题的答案,答案会是肯定的。

见图 1-6 你会发现一个 FAQ 机器人在做什么。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-6

常见问题聊天机器人示例

这些都是非常重复的问题,特定商店的顾客可能会打电话询问,或者试图通过访问网站并浏览页面来找到答案。

想象一下,当你有一个像这样的聊天机器人,它像人一样在几秒钟内回答你的问题,甚至做的比你想象的还要多。这只是聊天机器人能力的一小部分。

现在,我们试着以 QnA Bot 为例,分析一下前面提到的三个问题及其答案。

  • 问题可以通过简单的问答或者来回沟通来解决吗?

    是的,FAQ 只不过是简单的常见问题及其相关答案。可能会有一个基于上下文的 FAQ,但是除非你正在使用聊天机器人解决一个多领域的问题,否则你不会有这个问题。可能会有两个或更多的问题看起来相似的情况,但是你总是可以设计机器人在有疑问的时候问用户一个问题。

  • 它是否存在需要分析或获取数据的高度重复性问题?

    是的,常见问题要求我们从数据库中提取数据,并在网站上一次性显示出来,或者动态显示。但是用户必须一个接一个地浏览所有的问题来找到他/她正在寻找的问题,然后看到它的答案。在消费者真正得到答案之前,需要对用户界面进行大量的梳理…也可能不是。为什么不让我们的机器人替我们做呢?

  • 你的机器人的任务可以自动化和固定吗?

    是的,FAQ 机器人需要获取问题,分析问题,从数据库中获取信息,并将其返回给用户。这里没有什么是使用编码做不到的。此外,它几乎固定的流程不会实时改变。

从聊天机器人开始

在构建聊天机器人之前,应该遵循三个步骤。我们将在这里简要讨论它们中的每一个。

  1. 考虑你希望你的聊天机器人能够完成的所有场景或任务,并以不同的形式收集所有相关的问题来完成这些任务。你希望你的聊天机器人做的每一项任务都会定义一个意图

  2. 你列出的每个问题或意图都可以用多种方式来表达。就看用户怎么表达了。

    比如:Alexa,关灯。Alexa,你能把灯关掉吗?你能关掉灯吗?用户可以使用这些句子中的任何一句来指示机器人关灯。所有这些人都有同样的意图/任务去关灯,但是他们被要求用不同的话语 / 差异

  3. 在您认识到用户的意图后,编写所有的逻辑来保持用户与您选择的流程的联系。

    例如,假设您正在构建一个预约医生的机器人。然后你要求你的用户给一个电话号码,姓名,和专家,然后你显示插槽,然后预订它。

在这种情况下,你可以期望用户知道这些细节,而不是试图适应机器人本身的所有事情,就像一个耳朵问题的专家被称为耳鼻喉科。然而,这样做并不是什么大事。因此,这又回到决定你的机器人的范围,取决于你必须建立应用程序的时间和资源。

聊天机器人中的决策树

如果你知道决策树,那很好,因为在设计聊天机器人的流程时,你会经常需要这些知识。但是如果你不知道决策树,那么谷歌搜索将帮助你学习这个在计算机科学中广泛使用的简单概念。

在聊天机器人中使用决策树

在聊天机器人的环境中,决策树只是帮助我们找到用户问题的准确答案。

决策树 是一种决策支持工具,它使用决策及其可能后果的树状图形或模型,包括偶然事件结果、资源成本和效用。这是显示只包含条件控制语句的算法的一种方式。

—维基百科

构建聊天机器人时最困难的部分是跟踪 if…else 代码块。要做的决策越多,如果…否则会出现在代码中。但同时需要这些块来编码复杂的对话流。如果问题很复杂,并且在现实生活中需要很多 if…else,那么这将需要代码以同样的方式进行调整。

决策树有什么帮助?

决策树的编写和理解都很简单,但它们是对问题解决方案的有力表示。他们继承了一种独特的能力来帮助我们理解很多事情。

  • 有助于全面了解手头的问题。查看决策树,我们可以很容易地了解缺少什么或需要修改什么。

  • 有助于更快地调试。决策树就像一本简短的圣经,或者说,软件需求规范文档的可视化表示,开发人员、产品经理或领导层可以参考它来解释预期的行为或在需要时进行任何更改。

  • 人工智能仍然没有达到可以用大量数据训练并以 100%的准确率执行的阶段。它仍然需要通过编写业务逻辑和规则进行大量的手动操作。决策树在要求机器学习和做这件事变得有点困难的任何地方都有帮助。

让我们举一个简单的例子,并尝试理解它如何帮助构建聊天机器人。请看聊天机器人的示例图,该图以用户是在找 t 恤还是牛仔裤的问题开始,基于输入,图流通过询问更多的问题进一步给出与产品相关的选项。你不需要创建一个完全成熟的决策树,但在开始构建聊天机器人之前,你肯定应该在每一步都定义一个问题流。

假设你正在开发一个类似的聊天机器人,帮助人们在线购买服装。你要做的第一件事是做一个类似的决策树或流程图,帮助你的聊天机器人在正确的时间问适当的问题。这对于设定每个步骤的范围以及在该阶段需要做什么是非常必要的。当你真正编写你的第一个聊天机器人时,你将需要状态图或者简单的流程图。在创建如图 1-7 的图表时,切记不要过于严格;尽可能保持简单,以后再添加扩展功能。这种过程的好处是开发时间将会减少,以后功能将会松散耦合,并开始作为组件有意义。像示例中一样,在创建基本功能后,您还可以添加颜色选择、价格范围、评级和折扣选项。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-7

一个服装聊天机器人的简单表示,用于在线购买服装

根据您的需求,肯定有更多的东西可以添加到早期的用例中。但是你必须确保不要让它对你自己和用户来说都太复杂。

决策树不仅可以帮助你将用户与流程联系在一起,也是一种非常有效的方式来识别下一个意图,这个意图可能是来自客户的一个问题。

所以,你的机器人会按照你建立的决策树问一系列问题。每个节点通过聊天机器人的意图缩小客户的目标。

假设您正在为一家金融机构——比如说一家银行——创建一个聊天机器人,它可以在身份验证后根据您的请求进行转账。在这种情况下,您的 bot 可能首先希望验证帐户详细信息,并要求用户确认金额,然后 bot 可能要求验证目标帐户名称、帐号、帐户类型等。您不能或不想调用 OTP(一次性密码)API,除非您已经验证了用户的帐户余额是否大于请求的金额。

这发生在我们所有人身上,也发生在顾客身上。当他们的问题没有得到正确回答时,他们会感到沮丧。在聊天机器人中使用决策树肯定会比不使用决策树给用户带来更好的体验。

很多时候,你会发现以编程方式解决一些意图的问题。所以,底线是,"如果你不能通过编程来解决问题,那么就通过设计来解决它。"

请看图 1-8 ,机器人正试图进行一项健康测试,并想知道抗生素是否对所有疾病都有效。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1-8

通过设计解决用例的例子

因为答案应该是一个布尔值(真/假),所以您只给用户两个按钮来点击,而不是让他们键入并等待修复他们的错误。

这是通过设计来解决,而不是编写大量代码来处理意外的用户输入。在创建聊天机器人时,你会有很多场景,只要按下按钮,你就能很快知道用户的意图。理解这样的场景并提供按钮是很重要的,这既是为了你自己的方便,也是为了那些不需要输入明显的可选答案的用户。

最佳聊天机器人/机器人框架

  • https://woebot.io/

    • 可以跟踪你的心情

    • 让你感觉更好

    • 通过观察你的情绪模式给你洞察力

    • 教你如何变得积极和精力充沛

  • https://qnamaker.ai/

    • 基于 FAQ、URL 和结构化文档,在几分钟内构建、训练和发布一个简单的问答机器人。

    • 使用熟悉的聊天界面测试和优化回复。

  • https://dialogflow.com/

    • 原名 api.ai,在聊天机器人爱好者中广受欢迎。

    • 通过构建由人工智能支持的引人入胜的基于语音和文本的对话界面,为用户提供与您的产品交互的新方式。

    • 在 Google Assistant、Amazon Alexa、Facebook Messenger 和其他流行的平台和设备上与用户联系。

    • 分析并理解用户的意图,帮助你以最有用的方式做出回应。

  • https://core.rasa.ai

    • 构建对话式软件的框架

    • 您可以用 Python 代码实现您的 bot 可以采取的操作。

    • 你的机器人的逻辑不是一堆 if…else 语句,而是基于在示例对话中训练的概率模型。

  • https://wit.ai

    • Wit.ai 让开发者可以轻松构建你可以与之交谈或发短信的应用和设备。

    • wit.ai 团队在推出后 21 个月内被脸书收购,为脸书在脸书开发自己的 NLP 引擎做出了贡献。

    • 你可以使用 wit.ai 来构建聊天机器人、家庭自动化等。

    • Wit.ai 类似于 Dialogflow 的工作方式,但功能不如 Dialogflow 丰富。人们最初使用 wit.ai,因为它是免费的,而 Dialogflow 不是,但后来 Dialogflow 也变得免费了。

  • https://www.luis.ai/

    • 基于机器学习的服务,将自然语言构建到应用程序、机器人和物联网设备中。

    • 快速创建可持续改进的企业级定制模型。

  • http://botkit.ai

    • 可视对话生成器

    • 内置的统计数据和指标

    • 可以很容易地与脸书、微软、IBM Watson、Slack、Telegram 等集成。

聊天机器人的组件和使用的术语

聊天机器人系统的组件非常少。在这一节中,我们将简要讨论您将在后面章节中遇到的聊天机器人的组件。

在深入潜水之前,对任何系统有一个基本的理论了解总是有帮助的。在阅读完这一节之后,您应该对使用 Python 构建聊天机器人时使用的技术术语有一个大致的了解。当我们真正开始构建聊天机器人时,这些术语将在接下来的章节中频繁使用。

目的

当用户与聊天机器人交互时,他使用聊天机器人的意图是什么/他的要求是什么?

例如,当用户对聊天机器人说:“预订电影票”时,我们作为人类可以理解用户想要预订电影票。这是机器人的意图。可以命名为“book _ movieintent。

另一个例子是当用户说,“我想点餐”,或者“你能帮我点餐吗?”这些可以被命名为“订单 _ 食品”意图。同样,您可以定义任意多的意图。

实体

意图有关于意图的元数据,称为"实体。“在示例中,“预订电影票”,预订票可以是一个意图,并且实体是“电影,”,这也可以是其他的东西,如航班、音乐会等。

您可以将通用实体标记为在整个意图中使用。实体可以用数量、计数或体积来表示。意图也可以有多个实体。

比如:给我订一双 8 码的鞋。

这里可能有两个实体:

类别:鞋子

尺寸:8

言论

话语只不过是你的用户可能表现出的同一问题/意图的不同形式。

  • 记得我们讨论过关掉灯的意图吗?这是一个用户如何使用不同的话语来表达相同意图的例子。

  • 建议每个意图有最佳的 10 个话语,最少 5 个,但这不是限制性的。

训练机器人

训练本质上意味着建立一个模型,该模型将从已定义的意图/实体和话语的现有集合中学习如何对新的话语进行分类,并提供一个置信度得分。

当我们使用话语训练系统时,这被称为监督学习。我们很快会学到更多关于实际操作的知识。

置信度得分

每当你试图找出一个话语可能属于什么意图时,你的模型就会给出一个置信度得分。这个分数告诉你你的机器学习模型在识别用户意图方面有多自信。

这就是我们想在“聊天机器人简介”的第一章中介绍的全部内容你必须从商业角度和技术角度对聊天机器人有一个公平的想法。我们走过了属于聊天机器人的历史车道。聊天机器人的进化程度令人着迷。

我们了解了聊天机器人在一段时间内是如何发展的,以及为什么聊天机器人是一个企业在这场残酷的竞争中成长的必备工具。我们了解了不同的聊天机器人框架,并通过示例了解了聊天机器人的术语。我们将在接下来的章节中使用它们。你现在应该已经知道你想要构建什么样的聊天机器人,以及它在构建后会有什么样的表现。

如果需要的话,做好你所有的记录和决策树,在下一章我们学习了自然语言理解的基础知识之后,我们可以快速开始构建我们的聊天机器人。

即使你没有任何想法,也不要担心。我们将尝试用接下来几章学到的所有概念一步一步地构建一个很酷的聊天机器人。

下一章见。

二、聊天机器人的自然语言处理

本章旨在让你开始使用 Python 进行自然语言处理(NLP)来构建聊天机器人。您将使用一个名为 spaCy 的令人惊叹的开源库来学习 NLP 的基本方法和技术。如果您是 Python 生态系统的初学者或中级用户,那么不要担心,因为您将开始学习聊天机器人 NLP 所需的每一步。这一章不仅教你 NLP 中的方法,还用实际例子和编码例子来演示它们。我们还将讨论为什么聊天机器人可能需要特定的 NLP 方法。注意 NLP 本身就是一种技能。

我们将密切关注词性标注、词干、实体检测、停用词、依存句法分析和名词组块,并找出单词之间的相似性。当你构建你的用例的聊天机器人时,所有这些方法都会对你很有帮助。

除了本章介绍的方法之外,还有很多其他的 NLP 方法。基于你对正在构建的聊天机器人的需求,你可以尝试学习它们。在本章结束时,我们将要学习使用的 SpaCy 库将会给你足够的关于如何扩展你的 NLP 知识库及其理解的想法。所以,让我们开始,在下一节中首先尝试理解聊天机器人的 NLP。

为什么我需要知道自然语言处理来构建聊天机器人?

要了解这个问题的答案,我们先来了解一下自然语言处理(NLP)。

自然语言处理(NLP) 是人工智能的一个领域,使计算机能够分析和理解人类语言。

现在,为了执行 NLP,或者说,自然语言理解(NLU),我们有很多方法,接下来我们将讨论这些方法。你听到了一个新术语自然语言理解(NLU)——那是什么?

简单来说,NLU 是 NLP 更大图景的子集,就像机器学习、深度学习、NLP 和数据挖掘是人工智能(AI)更大图景的子集,人工智能是任何做一些智能事情的计算机程序的总称。

一个很好的经验法则是使用术语 NLU 来表达机器理解人类提供的自然语言的能力。

现在,关于你是否真的需要了解 NLP 来构建一个聊天机器人的问题——答案是肯定的和否定的。困惑了吗?你没听错,不是说你不知道 NLP 的方法和技术就根本造不出聊天机器人,只是你的范围会有些局限。您无法在扩展应用程序的同时保持代码整洁。当聊天机器人不能行走和奔跑时,NLP 给了它飞翔的翅膀。

对于普通人来说,聊天机器人只不过是与另一端的智能机器进行交流的一种方式。这种机器既可以是基于语音的,也可以是基于文本的,用户将用他们自己的语言输入,这在计算机科学中通常被称为自然语言。

我们知道不存在有魔力的黑盒,一切都很好。一要知道 AI 里没有什么人工的东西;它实际上是由伟大的人编写的机器学习和深度学习算法,在引擎盖下运行。机器还没有达到可以像人类一样思考拥有自己智能的阶段。今天的人工智能系统——它们做什么和它们的行为方式——是我们如何训练它们的结果。

因此,要理解用户的自然语言,不管它是什么语言,也不管它是什么输入形式(文本、语音、图像等)。),我们必须编写算法并使用 NLP 的技术。NLP 被认为是聊天机器人的大脑,它处理原始数据,执行 munging,清理数据,然后准备采取适当的行动。

NLP 本身是一个巨大的主题,需要时间和毅力来完全学习,但是对于一个聊天机器人开发者来说,有一些方法是必须知道的,这是我们在本章将要学习的。

spaCy 是什么?

spaCy 是一个用于高级 NLP 的开源软件库,用 Python 和 Cython 编写,由 Matthew Honnibal 构建。它提供了直观的 API 来访问其由深度学习模型训练的方法。

spaCy 提供了世界上最快的语法分析器。直接取自 spaCy 的文档,他们有一些惊人的基准测试结果,如下所示。

spaCy 的基准结果

2015 年的两篇同行评议论文证实,spaCy 提供了世界上最快的语法分析器,其准确性在现有最佳水平的 1%以内。少数更精确的系统要慢 20 倍甚至更多。让我们试着看一下图 2-1 ,它显示了基于速度和准确性的 spaCy 基准测试结果,与其他库进行了比较。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-1

空间基准测试结果

spaCy 还提供多种语言的统计神经网络模型,如英语、德语、西班牙语、葡萄牙语、法语、意大利语、荷兰语和多语言 NER。它还为各种其他语言提供了标记化。此表显示了 Choi 等人的速度基准,因此在不同硬件上比较 spaCy v2.x 基准是不公平的。这就是您看不到 spaCy v2.x 的速度列值的原因。

spaCy 提供了什么?

spaCy 声称提供了三个主要的东西,并且非常有帮助。让我们来看看这些,并理解为什么人们应该知道并使用 spaCy 作为进行 NLP 的首选模块。

世界上最快的图书馆

spaCy 在提取大规模信息方面做得非常好。在 Cython 库的帮助下,它是从零开始编写的,对内存有着极大的关注。

把事情做完

spaCy 的设计理念是“把事情做好”。它帮助我们完成真实世界的 NLP 场景。干净的文档为开发人员和计算语言学爱好者节省了大量时间,并使他们更有效率。它很容易安装,就像任何其他 Python 包一样。

深度学习

spaCy 是开源社区中处理深度学习算法文本的最佳库之一。它与 TensorFlow、PyTorch、scikit-learn、Gensim 以及 Python 的其他相关技术无缝协作。深度学习开发者可以很容易地为一系列 NLP/NLU 问题构建语言复杂的统计模型。

空间特征

没有其他 NLP 库提供了范围极其广泛的 API 来做几乎所有的事情,这正是 spaCy 所做的。这个库最大的优点是它在不断发展,变得越来越好。让我们先睹为快,看看他们官网[ https://spacy.io/ ]上提到的 spaCy 的特性。

  • 非破坏性标记化

  • 命名实体识别

  • 支持 28 种以上的语言

  • 8 种语言的 13 种统计模型

  • 预先训练的单词向量

  • 轻松的深度学习集成

  • 词性标注

  • 标记依存句法分析

  • 句法驱动的句子分割

  • 语法和 NER 的内置可视化工具

  • 方便的字符串到哈希映射

  • 导出到 numpy 数据数组

  • 高效的二进制序列化

  • 简单的模型打包和部署

  • 最先进的速度

  • 稳健、经过严格评估的精确度

现在,让我们深入研究 Python 中这个令人敬畏的 NLP 模块:spaCy。

安装和先决条件

在我们真正深入空间和代码片段之前,请确保您的操作系统上安装了 Python。如果没有,请参考[1]。

你可以使用你喜欢的任何版本的 Python。今天,大多数系统都预装了默认的 Python 2.7 . x 版本。在本章中,我们将使用 Python 3。所以,如果你想使用 Python 3,请从 https://www.python.org/downloads/ 下载 Python 3 安装在你的操作系统上。如果已经安装了 Python 2,也可以使用它;它可能需要也可能不需要微小的代码更改。

我们将通过 pip [2]安装 spaCy。

我们将使用虚拟环境[3]并将 spaCy 安装到一个用户目录中。

如果您使用的是 macOS/OSX/Linux,请遵循以下步骤:

Step 1:
python3 -m pip install -U virtualenv

Step 2:
virtualenv venv -p /usr/local/bin/python3 #Make sure you use your own OS path for python 3 executable.

Step 3:
source venv/bin/activate

Step 4:
pip3 install -U spacy # We'll be using spaCy version 2.0.11.

最后一步可能需要时间,所以耐心等待。

如果您使用的是 Windows,只需将步骤 3 更改为

venv\Scripts\activate

现在,我们将在我们的虚拟环境中安装 Jupyter Notebook ,这是我们在步骤 3 中激活的。使用 Jupyter Notebook 比标准的 Python 解释器要容易得多,效率也更高。在接下来的章节中,我们将执行 Jupyter 笔记本中的所有片段。

要安装 Jupyter Notebook,请运行以下 pip 命令:

pip3 install jupyter

此命令将在您的系统中安装 Jupyter 笔记本。

此时,您应该已经在您的 virtualenv 中安装了 spaCy 和 Jupyter Notebook。让我们验证一下是否所有的东西都安装成功了。

  1. 转到您的命令行界面,键入以下内容,您应该会看到一个服务器正在启动,并在您的默认浏览器中打开一个 url。

    $ jupyter notebook
    
    

    默认的网址是http://localhost:8888/tree。它应该看起来像图 2-2 。

  2. Click on New as shown in Figure 2-2, and choose Python 3. It will open a new tab in your current browser and create a new notebook for you, where you can play with the Python code. You can execute any Python code, import libraries, plot charts, and markdown cells.

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 2-2

    木星笔记本第一眼

  3. Type import spaCy and run the cell by clicking on “Run” button or by pressing Shift + Enter. It should look something like Figure 2-3.

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 2-3

    验证空间安装

如果步骤 3 没有抛出任何错误消息,那么您已经成功地在您的系统上安装了 spaCy 模块。你应该在你的笔记本上看到你安装的空间版本。如果您想安装相同版本的 spaCy,那么您可以在通过 pip 安装 spaCy 时指定版本。

pip3 install –U spacy==2.0.11

什么是 SpaCy 模型?

SpaCy 模型就像任何其他机器学习或深度学习模型一样。模型是算法的产物,或者说,是在使用机器学习算法训练数据之后创建的对象。spaCy 有很多这样的模型,可以像下载其他 Python 包一样直接放在我们的程序中。

现在,我们将把 spaCy 模型作为 Python 包安装。

为此,我们将利用 notebook 的 magic 命令在 notebook 中运行以下命令。通过前缀!在 shell 命令之前,我们也可以从 Jupyter 笔记本中运行 shell 命令。让我们看看它看起来怎么样。

!python3 -m spacy download en

使用 Jupyter Notebook 下载Python 3的空间模型时,您可能会遇到权限问题。转到您的终端,运行以下命令:

sudo python3 –m download en

参见图 2-4 进行参考。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-4

下载空间模型

如图 2-4 所示,spaCy 试图下载一些核心文件,并作为 Python 包安装。

注意

!【感叹号运算符】只在 Jupyter 笔记本中起作用。要直接从终端安装 spaCy 型号,您需要删除!【感叹号运算符】;否则会导致错误。

  1. https://www.python.org/downloads/

  2. https://packaging.python.org/tutorials/installing-packages/#installing-from-pypi

  3. http://docs.python-guide.org/en/latest/dev/virtualenvs/

构建聊天机器人的自然语言处理基本方法

擅长基础知识,成为某方面的专家,并高效地完成它,这真的很重要。要构建聊天机器人,我们需要了解自然语言处理的基本方法。这些方法有助于我们将输入分解成块,并使其有意义。在下一节,我们将学习一些最常用的自然语言处理方法,这些方法不仅能帮助你擅长自然语言处理,还能帮助你构建很酷的聊天机器人。我们越能更好、更有效地处理输入文本,我们就能更好地响应用户。

词性标注

词性标注是一个过程,在这个过程中,你阅读一些文本,并为每个单词或标记分配词性,如名词、动词、形容词等。

当你想识别给定句子中的某个实体时,词性标注变得极其重要。第一步是做词性标注,看看我们的文本包含什么。

让我们用一些真正的 POS 标记的例子来弄脏我们的手。

例 1:

nlp = spacy.load('en') #Loads the spacy en model into a python object
doc = nlp(u'I am learning how to build chatbots') #Creates a doc object
for token in doc:
    print(token.text, token.pos_) #prints the text and POS

输出:

('I', 'PRON')
('am', 'VERB')
('learning', 'VERB')
('how', 'ADV')
('to', 'PART')
('build', 'VERB')
('chatbots', 'NOUN')

例 2:

doc = nlp(u'I am going to London next week for a meeting.')
for token in doc:
    print(token.text, token.pos_)

输出:

('I', 'PRON')
('am', 'VERB')
('going', 'VERB')
('to', 'ADP')
('London', 'PROPN')
('next', 'ADJ')
('week', 'NOUN')
('for', 'ADP')
('a', 'DET')
('meeting', 'NOUN')
('.', 'PUNCT')

正如我们所看到的,当我们打印从方法nlp,返回的Doc对象的标记时,方法nlp,是一个用于访问注释的容器,我们得到了用句子中的每个单词标记的 POS。

这些标签是属于单词的属性,它们决定了单词在语法正确的句子中的使用。我们可以利用这些标签作为信息过滤等领域的词汇特征。

让我们试着举另一个例子,我们试着探索来自Doc对象的令牌的不同属性。

例 3:

doc = nlp(u'Google release "Move Mirror" AI experiment that matches your pose from 80,000 images')

     for token in doc:
          print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
                token.shape_, token.is_alpha, token.is_stop)

输出:

|

正文

|

引理

|

位置

|

标签

|

dep

|

形状

|

alpha

|

停止

|
| — | — | — | — | — | — | — | — |
| 谷歌 | 谷歌 | -好的 | NNP | 复合的 | 五 x 综合征 | 真实的 | 错误的 |
| 发布 | 释放;排放;发布 | 名词 | 神经网络 | 模式 | 电影站 | 真实的 | 错误的 |
| | " | 点点 | `` | 点点 | " | 错误的 | 错误的 |
| 移动 | 移动 | -好的 | NNP | 模式 | 电影站 | 真实的 | 错误的 |
| 镜子 | 镜子 | -好的 | NNP | 模式 | 五 x 综合征 | 真实的 | 错误的 |
| | " | 点点 | " | 点点 | " | 错误的 | 错误的 |
| | 人工智能 | -好的 | NNP | 复合的 | xx | 真实的 | 错误的 |
| 实验 | 实验 | 名词 | 神经网络 | 根 | 电影站 | 真实的 | 错误的 |
| 那个 | 那 | 形容词 | 禁水试验 | nsubj | 电影站 | 真实的 | 真实的 |
| 匹配 | 比赛 | 动词 | 核黄素 | relcl | 电影站 | 真实的 | 错误的 |
| 你的 | PRON | 形容词 | PRP 元 | 可能的 | 电影站 | 真实的 | 真实的 |
| 姿势 | 姿态 | 名词 | 神经网络 | 扔过来 | 电影站 | 真实的 | 错误的 |
| 来自 | 从 | 腺苷二磷酸 | 在…里 | 准备 | 电影站 | 真实的 | 真实的 |
| 8 万 | Eighty thousand | 全国矿工联合会 | 激光唱片 | nummod | dd,ddd | 错误的 | 错误的 |
| 图像 | 图像 | 名词 | 非营养性吸吮 | 比吉 | 电影站 | 真实的 | 错误的 |

例 4:

doc = nlp(u'I am learning how to build chatbots')
for token in doc:
    print(token.text, token.lemma_, token.pos_, token.tag_, token.dep_,
        token.shape_, token.is_alpha, token.is_stop)

输出 :

|

正文

|

引理

|

位置

|

标签

|

dep

|

形状

|

alpha

|

停止

|
| — | — | — | — | — | — | — | — |
| | PRON | 代词 | 富含血小板血浆 | nsubj | X | 真实的 | 错误的 |
| 上午 | 是 | 动词 | 文件 | 去吧 | xx | 真实的 | 真实的 |
| 学习 | 学习 | 动词 | 静脉全血葡萄糖 | 根 | 电影站 | 真实的 | 错误的 |
| 如何 | 怎么 | 副词 | war refugee board 战时难民事务委员会 | advmod | xxx | 真实的 | 真实的 |
| | 到 | 部分 | 到 | 去吧 | xx | 真实的 | 真实的 |
| 建造 | 建设 | 动词 | 动词 | 断续器 | 电影站 | 真实的 | 错误的 |
| chatbots | 聊天机器人 | 名词 | 非营养性吸吮 | 扔过来 | 电影站 | 真实的 | 错误的 |

请参考下表,了解我们在代码中打印的每个属性的含义。

|

文本

|

正在处理的实际文本或单词

|
| — | — |
| 引理 | 正在处理的单词的词根形式 |
| 刷卡机 | 词的词性 |
| 标签 | 它们表达词性(如动词)和一定量的形态信息(如动词是过去式)。 |
| 资料执行防止 | 句法依赖性(即,标记之间的关系) |
| 形状 | 单词的形状(例如,大写、标点、数字格式) |
| 希腊字母的第一个字母 | 令牌是字母字符吗? |
| 停止 | 这个单词是停用词还是停用列表的一部分? |

您可以参考下表来了解 token 对象的每个 POS 属性值的含义。这个列表给出了 spaCy 模型分配的词性标签的详细想法。

|

位置

|

描述

|

例题

|
| — | — | — |
| ADJ | 形容词 | 大,老,绿,不可理解,第一 |
| ADP | ADHD 位置 | 在,到,在期间 |
| ADV | 副词 | 很,明天,下来,哪里,那里 |
| au | 辅助的 | 是,已经(做了),将要(做了),应该(做了) |
| CONJ | 结合 | 与,或,但 |
| cconj | 并列连词 | 与,或,但 |
| | 限定词 | 一个,一个, |
| intj | 感叹词 | 嘶,哎哟,好极了,你好 |
| 名词 | 名词 | 女孩,猫,树,空气,美女 |
| 中的 | 数字 | 1,2017,一,七十七,四,MMXIV |
| 部分 | 颗粒 | 的,不是的, |
| pron | 代词 | 我,你,他,她,我自己,他们自己,某人 |
| 提议 | 专有名词 | 玛丽、约翰、伦敦、北约、HBO |
| | 标点 | 。, (, ), ? |
| scoj | 从属连词 | 如果,虽然,那 |
| SYM | 标志 | $、%,、、、+、-、×、:、 |
| 动词 | 动词 | 跑,跑,跑,吃,吃,吃 |
| X | 其他的 | sfpksdpsxma |
| 空间 | 空间 |   |

那么为什么聊天机器人需要词性标注呢?

回答:降低理解一篇无法训练或者训练的信心不足的文本的复杂度。通过使用词性标注,我们可以识别文本输入的各个部分,并仅对这些部分进行字符串匹配。例如,如果您要查找一个位置是否存在于一个句子中,那么词性标记会将位置词标记为名词,因此您可以从标记列表中获取所有名词,并查看它是否是预设列表中的位置之一。

词干化和词汇化

词干化是将屈折词还原为词干(基本形式)的过程。

词干算法将单词“say”简化为词根单词“say”,而“proposely”变成了 propose。如你所见,这可能是也可能不是 100%正确的。

词汇化词干化密切相关,但词汇化是根据单词的预期含义确定其词汇的算法过程。

例如,在英语中,动词“行走”可能显示为“行走”、“散步”、“散步”或“散步”人们可能会在字典中查找的基本形式“walk”被称为该词的词条。spaCy 没有任何内置的词干分析器,因为词汇化被认为更加正确和有效。

词干化和词汇化的区别

  • 词干提取以一种粗糙的、启发式的方式来完成这项工作,即砍掉单词的末尾,假设剩下的单词就是我们真正要找的,但它通常包括去除派生词缀。

  • 词汇化试图通过使用词汇和词形分析来更优雅地完成这项工作。它尽最大努力只删除屈折词尾,并返回单词的字典形式,称为词条。

尽管很少有库提供词干化和词汇化的方法,但使用词汇化来正确获取词根始终是最佳实践。

让我们通过一些例子来探讨词汇化:

例 1:

from spacy.lemmatizer import Lemmatizer
from spacy.lang.en import LEMMA_INDEX, LEMMA_EXC, LEMMA_RULES
lemmatizer = Lemmatizer(LEMMA_INDEX, LEMMA_EXC, LEMMA_RULES)
lemmatizer('chuckles', 'NOUN') # 2nd param is token's part-of-speech tag

输出:

[u'chuckle']

例 2:

lemmatizer('blazing', 'VERB')

输出:

[u'blaze']

例 3:

lemmatizer('fastest', 'ADJ')

输出:

[u'fast']

如果您想比较词干分析器和 lemmatizer,那么您需要安装 Python 最流行的库之一:自然语言工具包(NLTK)。spaCy 最近很受欢迎,但正是 NLTK 让每个 NLP 爱好者投身到 NLP 及其技术的海洋中。

查看下面的例子,我们尝试使用 NLTK 提供的两种词干技术。首先,我们尝试使用 PorterStemmer 获得单词“First”的词干,然后使用 SnowBallStemmer。两者给出的结果是一样的——也就是“最快”——但是当我们用 spaCy 的方法做引理化时,它给我们的是“fast”作为“fast”的词干,这更有意义,也更正确。

from nltk.stem.porter import *
from nltk.stem.snowball import SnowballStemmer
porter_stemmer = PorterStemmer()
snowball_stemmer = SnowballStemmer("english")
print(porter_stemmer.stem("fastest"))
print(snowball_stemmer.stem("fastest"))

fastest
fastest

注意

在尝试运行这段代码之前,确保使用 pip3 安装nltk包。

既然你很清楚在 NLP 中词干化或词元化是做什么的,你应该能够理解每当你遇到需要单词的词根形式的情况时,你需要在那里做词元化。例如,它经常被用于构建搜索引擎。你一定想知道谷歌是如何在搜索结果中给你你想要的文章的,即使搜索文本没有被恰当地表达。

这就是使用词汇化的地方。想象一下,你用文字“搜索,《权力的游戏》下一季什么时候上映?

现在,假设搜索引擎做简单的文档词频匹配,给你搜索结果。在这种情况下,前面提到的查询可能不会匹配标题为“Game of Thrones next season release date”的文章

如果我们在将输入与文档进行匹配之前对原始问题进行词汇化,那么我们可能会得到更好的结果。

在接下来的章节中,我们将尝试测试这一理论。

命名实体识别

命名实体识别(),又名实体识别实体提取**,是在给定文本中寻找命名实体并将其分类到预定义类别的过程。**

**NER 任务非常依赖于用来训练 NE 提取算法的知识库,因此它可能工作也可能不工作,这取决于它被训练的所提供的数据集。

spaCy 带有一个非常快速的实体识别模型,能够从给定的文档中识别实体短语。实体可以是不同的类型,例如人、位置、组织、日期、数字等。这些实体可以通过doc对象的.ents属性来访问。

让我们借助 spaCy 强大的 NER 标记功能,通过一些例子来尝试找到命名实体。

例 1:

my_string = u"Google has its headquarters in Mountain View, California having revenue amounted to 109.65 billion US dollars"
doc = nlp(my_string)

for ent in doc.ents:
    print(ent.text, ent.label_)

输出:

('Google', 'ORG')
('Mountain View', 'GPE')
('California', 'GPE')
('109.65 billion US dollars', 'MONEY')

我们可以看到 spaCy 模型是如何漂亮和自动地识别出单词 Google 是一个组织California 是一个地缘政治实体,在给定的句子中,我们谈论的是**1096.5 亿美元,**实际上是关于钱的。

让我们试着探索更多的例子。

例 2:

my_string = u"Mark Zuckerberg born May 14, 1984 in New York is an American technology entrepreneur and philanthropist best known for co-founding and leading Facebook as its chairman and CEO."
doc = nlp(my_string)

for ent in doc.ents:
    print(ent.text, ent.label_)

输出:

('Mark Zuckerberg', 'PERSON')
('May 14, 1984', 'DATE')
('New York', 'GPE')
('American', 'NORP')
('Facebook', 'ORG')

例 3:

my_string = u"I usually wake up at 9:00 AM. 90% of my daytime goes in learning new things."
doc = nlp(my_string)
for ent in doc.ents:
    print(ent.text, ent.label_)

输出:

('9:00 AM', 'TIME')
('90%', 'PERCENT')

如您所见,实体提取器可以很容易地从给定的字符串中提取时间信息。此外,正如你所看到的,实体提取器不仅试图识别数字,而且准确的百分比值。

根据 spaCy 的文档,在onto notes 51语料库上训练的模型支持以下实体类型。

|

类型

|

描述

|
| — | — |
| | 人,包括虚构的 |
| NORP | 国籍、宗教或政治团体 |
| FAC | 建筑物、机场、高速公路、桥梁等。 |
| 组织 | 公司、代理处、机构等。 |
| gpe | 国家、城市、州 |
| LOC | 非 GPE 地区、山脉、水体 |
| 产品 | 物体、交通工具、食物等。(非服务) |
| 事件 | 命名飓风、战役、战争、体育赛事等。 |
| 艺术品 | 书籍、歌曲等的名称。 |
| 定律 | 被命名为法律的文件 |
| 语言 | 任何命名语言 |
| 日期 | 绝对或相对的日期或时期 |
| 时间 | 小于一天的时间 |
| 百分比 | 百分比,包括“%” |
| | 货币价值,包括单位 |
| 数量 | 测量,如重量或距离 |
| 序数 | “第一”、“第二”等等。 |
| 基数 | 不属于另一种类型的数字 |

每当我们打算用简单的术语构建一个对话代理或聊天机器人时,我们总是在头脑中有一个域。例如,我们希望聊天机器人预约医生、点餐、支付账单、填写银行申请、电子商务等。聊天机器人也可以解决这些问题。通过找出问题中的实体,人们可以对提出问题的背景有一个公平的想法。

让我们以两个单词相似但意思不同的句子为例来试着理解这一点。

my_string1 = u"Imagine Dragons are the best band."
my_string2 = u"Imagine dragons come and take over the city."

doc1 = nlp(my_string1)
doc2 = nlp(my_string2)

for ent in doc1.ents:
    print(ent.text, ent.label_)

上面的for循环遍历doc1对象给出一个输出:

('Imagine Dragons', 'ORG')

太棒了,不是吗?当您意识到实体识别器不能识别第二个字符串中的任何实体时,这将变得更加有趣。运行下面的代码,doc2不会产生任何输出。

for ent in doc2.ents:
    print(ent.text, ent.label_)

现在,假设您要在真实环境中提取上述两个字符串的上下文。你会怎么做?在实体提取器的帮助下,人们可以很容易地找出语句的上下文,并智能地进一步展开对话。

停止言语

停用词是像 a、还有这样的高频词,我们有时想在进一步处理之前将其从文档中过滤掉。停用词通常没有什么词汇内容,也没有多少意义。

下面是在 Reuters-RCV1 中常见的 25 个语义非选择性停用词的列表。

a   an    and    are    as    at    be    by    for
from    has    he    in    is    it    its    of    on
that    the    to    was    were    will    with

让我们进入一些代码,试着理解事物是如何工作的。

要查看 spaCy 中定义为停用词的所有词,可以运行以下代码行:

from spacy.lang.en.stop_words import STOP_WORDS
print(STOP_WORDS)

您应该会看到类似这样的内容:

set(['all', 'six', 'just', 'less', 'being', 'indeed', 'over', 'move', 'anyway', 'fifty', 'four', 'not', 'own', 'through', 'using', 'go', 'only', 'its', 'before', 'one', 'whose', 'how',
......................................................................................................................................................................................................................................................................................................
'whereby', 'third', 'i', 'whole', 'noone', 'sometimes', 'well', 'together', 'yours', 'their', 'rather', 'without', 'so', 'five', 'the', 'otherwise', 'make', 'once'])

spaCy 的停用词表中定义了大约 305 个停用词。如果需要,您可以随时定义自己的停用字词,并覆盖现有列表。

要查看一个单词是否是停用词,可以使用 spaCy 的nlp对象。我们可以使用nlp对象的is_stop属性。

例 1:

nlp.vocab[u'is'].is_stop

输出:

True

例 2:

nlp.vocab[u'hello'].is_stop

输出:

False

例 3:

nlp.vocab[u'with'].is_stop

输出:

True

停用词是文本清理的一个非常重要的部分。它有助于在我们尝试进行实际处理以理解文本之前删除无意义的数据。

假设你处于这样一种情况,你正在建造一个机器人,通过评估人们的情绪来让他们开心。现在,需要分析用户输入的文本中的情感,以便可以制定正确的响应。这里,在乞求做基本的情感分析之前,我们要去除数据中以停用词形式存在的噪音。

依存句法分析

依赖解析是 spaCy 更漂亮、更强大的特性之一,它既快又准确。解析器还可以用于句子边界检测,并让您遍历基本名词短语或“组块”

spaCy 的这个特性为您提供了一个解析树,它解释了单词或短语之间的父子关系,并且与单词出现的顺序无关。

让我们举一个例子,你必须分析下面的句子:

帮我订一张从班加罗尔到果阿的机票

例 1:

doc = nlp(u'Book me a flight from Bangalore to Goa')
blr, goa = doc[5], doc[7]
list(blr.ancestors)

输出:

[from, flight, Book]

上面的输出可以告诉我们,用户希望预订从班加罗尔出发的航班。

让我们试着列出goa.ancestors物体的祖先:

list(goa.ancestors)

输出:

[to, flight, Book]

这个输出可以告诉我们,用户希望预订飞往果阿的航班。

依存解析中的祖先是什么?

祖先是这个标记的语法后代的最右边的标记。就像上例中对于对象blr的祖先分别是从、书。

记住,你总是可以使用ancestors属性列出一个doc对象项目的祖先。

list(doc[4].ancestors) #doc[4]==flight

上面的代码将输出:

[flight, Book]

为了以编程方式检查一个doc对象项是否是另一个 doc 对象项的祖先,我们可以做以下事情:

doc[3].is_ancestor(doc[5])

以上返回True,因为doc[3](即 flight)是doc[5](即 Bangalore)的祖先。您可以尝试更多这样的例子,以便更好地理解依赖解析和祖先概念。

如果我们试着想象一个真实世界的场景,我们可能会在尝试构建聊天机器人时遇到类似这样的句子

我想预订一辆去酒店的出租车和一张餐馆的桌子。

在这句话中,重要的是要知道请求了什么任务以及它们的目标是哪里(即用户是想预订出租车去酒店还是餐馆 )

让我们试着用下面的代码来做这件事:

例 1:

doc = nlp(u'Book a table at the restaurant and the taxi to the hotel')
tasks = doc[2], doc[8] #(table, taxi)
tasks_target = doc[5], doc[11] #(restaurant, hotel)

for task in tasks_target:
          for tok in task.ancestors:
              if tok in tasks:
                  print("Booking of {} belongs to {}".format(tok, task))
      break

输出:

Booking of table belongs to restaurant
Booking of taxi belongs to hotel

依存解析中的子元素是什么?

子代是该标记的直接语法依赖项。我们可以像使用ancestors一样使用children属性来查看单词的子单词。

list(doc[3].children)

将输出

[a, from, to]

用于依存解析的交互式可视化

第一次理解完整的依存解析概念是非常困难的。spaCy 提供了一种非常简单的交互式方法来理解它的依赖解析。spaCy v2.0+有一个可视化模块,在这里我们可以传递一个Doc或一列Doc对象给 displaCy,并调用 displaCy 的serve方法来运行 web 服务器。

图 2-5 显示了交互式可视化将如何寻找依赖解析。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-5

用于依存解析的交互式可视化

您也可以生成图 2-5 中的依赖解析可视化。要创建这样的可视化效果,运行下面的代码,然后在浏览器中转到http://localhost:5000

让我们试着将我们的任务示例和任务目标可视化。

from spacy import displacy
doc = nlp(u'Book a table at the restaurant and the taxi to the hotel')
displacy.serve(doc, style="dep")

运行这段代码将得到如图 2-6 所示的输出。如果你得到类似的东西,那么转到浏览器的另一个标签,输入http://localhost:5000

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-6

正在本地主机上启动依赖关系解析服务器

我们在代码中得到这个字符串的依赖解析的可视化(如图 2-7 所示)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2-7

依存解析示例

让我们再举一个依赖解析的例子,我们假设用户在问下面的句子:

柏林有哪些值得参观的地方,在吕贝克逗留的时间有哪些?

我们将首先创建 d oc对象,如下所示:

 doc = nlp(u"What are some places to visit in Berlin and stay in Lubeck")

现在,我们得到了正在谈论的地点和用户想要的动作:

places = [doc[7], doc[11]] #[Berlin, Lubeck]
actions = [doc[5], doc[9]] #[visit, stay]

因为您已经知道了词性标注和实体提取,所以您可以很容易地自动获得位置和动作。

现在我们有了位置,让我们遍历它的每个祖先,并检查是否在 actions 中找到了任何祖先。在动作列表中找到的 place 的第一个父代应该是有问题的 place 的动作。

for place in places:
    for tok in place.ancestors:
        if tok in actions:
            print("User is referring {} to {}").format(place, tok)
            break

输出:

User is referring: Berlin to visit
User is referring: Lubeck to stay

正如我们在这些例子中看到的,依赖解析使得理解用户所指的内容变得非常容易。我们看到,在两个不同任务的情况下,我们可以很好地计算出期望,并在此基础上,制定下一个响应。

聊天机器人中的依赖解析有什么用?

从零开始构建聊天机器人时,依赖解析是最重要的部分之一。当你想弄清楚用户向聊天机器人输入的文本的含义时,这就变得更加重要了。可能会有这样的情况,你没有训练你的聊天机器人,但你仍然不想失去你的客户或像一个哑机器一样回复。在这些情况下,依赖解析确实有助于找到关系,并解释更多关于用户可能要求的内容。

如果我们要列出依赖关系解析有所帮助的事情,有些可能是:

  • 它有助于发现语法正确的句子的单词之间的关系。

  • 它可以用于句子边界检测。

  • 发现用户是否同时谈论一个以上的上下文是非常有用的。

你一定想知道,如果你的机器人用户说了任何语法不正确的句子,或者在输入一些东西时使用了任何短信,那该怎么办?正如在第一章中所讨论的,你必须对这些情况保持谨慎,并相应地使用 NLP 技术来处理它们。

你需要编写自己的自定义 NLP 来理解用户或聊天机器人的上下文,并在此基础上识别用户可能犯的语法错误。

总而言之,您必须准备好应对用户输入垃圾值或语法错误句子的情况。您不能一次处理所有这样的场景,但是您可以通过添加自定义 NLP 代码或通过设计限制用户输入来不断改进您的聊天机器人。

名词块

名词组块或 NP 组块基本上是“基本名词短语”我们可以说它们是以名词为中心的扁平短语。你可以把名词块想象成一个名词和描述这个名词的词。

让我们试着举个例子,更好地理解它。

例 1:

doc = nlp(u"Boston Dynamics is gearing up to produce thousands of robot dogs")
list(doc.noun_chunks)

输出:

[Boston Dynamics, thousands, robot dogs]

尽管从给定的句子中获取名词块很有帮助,spaCy 还提供了其他有用的属性。让我们试着探索其中的一些。

例 2:

doc = nlp(u"Deep learning cracks the code of messenger RNAs and protein-coding potential")
for chunk in doc.noun_chunks:
    print(chunk.text, chunk.root.text, chunk.root.dep_,
          chunk.root.head.text)

输出:

|

正文

|

根。正文

|

根。DEP_

|

根。头.正文

|
| — | — | — | — |
| 深度学习 | 学问 | nsubj | 裂缝 |
| 代码 | 密码 | 扔过来 | 裂缝 |
| 信使核糖核酸 | royal naval air station 皇家海军航空兵基地 | 比吉 | 关于 |
| 蛋白质编码潜能 | 潜在的 | 连词 | royal naval air station 皇家海军航空兵基地 |

从这个表中我们可以看到,我们得到了名词块和它们的属性。下表将帮助您理解每一列。

|

|

意为

|
| — | — |
| 正文 | 原始名词块的文本 |
| 根文本 | 连接名词块和剩余语法分析的原始单词的文本 |
| 根 dep | 连接根和头的依赖关系 |
| 根头文字 | 根令牌头的文本 |

寻找相似性

寻找两个词之间的相似性是一个用例,你会发现大部分时间都在使用 NLP。有时发现两个词是否相似变得相当重要。在构建聊天机器人时,你会经常遇到这样的情况,你不仅要找到看起来相似的单词,还要找到两个单词在逻辑上有多接近。

spaCy 使用高质量的单词向量,使用手套算法(单词表示的全局向量)来查找两个单词之间的相似性。

GloVe 是一种无监督学习算法,用于获取单词的矢量表示。GloVe 算法使用来自语料库的聚合的全局单词-单词共现统计来训练模型。

让我们尝试使用令牌的 vector 属性来查看 spaCy 的向量内部的实际值。

doc = nlp(u'How are you doing today?')
for token in doc:
    print(token.text, token.vector[:5])

输出:

(u'How', array([-0.29742685,  0.73939574, -0.04001453,  0.44034013,  2.8967502 ],      dtype=float32))(u'are', array([-0.23435134, -1.6145049 ,  1.0197453 ,  0.9928169 ,  0.28227055],      dtype=float32))(u'you', array([ 0.10252178, -3.564711  ,  2.4822793 ,  4.2824993 ,  3.590245  ],      dtype=float32))(u'doing', array([-0.6240922 , -2.0210216 , -0.91014993,  2.7051923 ,  4.189252  ],      dtype=float32))(u'today', array([ 3.5409122 , -0.62185854,  2.6274266 ,  2.0504875 ,  0.20191991],      dtype=float32))(u'?', array([ 2.8914998 , -0.25079122,  3.3764176 ,  1.6942682 ,  1.9849057 ],      dtype=float32))

看到这个输出,没有太大的意义和意义。从应用程序的角度来看,最重要的是不同单词的向量有多相似——也就是单词本身的意思。

为了找到空间中两个词之间的相似性,我们可以做以下工作。

例 1:

hello_doc = nlp(u"hello")
hi_doc = nlp(u"hi")
hella_doc = nlp(u"hella")
print(hello_doc.similarity(hi_doc))
print(hello_doc.similarity(hella_doc))

输出:

0.7879069442766685
0.4193425861242359

如果你看到单词 *hello,*它与单词 hi 更相关和相似,尽管单词 hellohella 之间只有一个字符的区别。

让我们再举一个句子的例子,了解 spaCy 是如何进行相似性比较的。还记得我们前面章节中的《权力的游戏》的例子吗?我们将尝试这样做,看看相似之处。

代码:

GoT_str1 = nlp(u"When will next season of Game of Thrones be releasing?")
GoT_str2 = nlp(u"Game of Thrones next season release date?")
GoT_str1.similarity(GoT_str2)

输出:

0.785019122782813

正如我们在这个例子中看到的,两个句子之间的相似度约为 79%,这足以说两个句子非常相似,这是真的。这可以帮助我们在构建聊天机器人*时节省大量编写自定义代码的时间。*因此,我们得出一个事实,spaCy 使用单词向量给我们两个单词之间有意义的相似性,而不仅仅是看它们的拼写或字母。

我们将举一个非常简单的例子,试图找出单词之间的相似性。

example_doc = nlp(u"car truck google")

for t1 in example_doc:
    for t2 in example_doc:
        similarity_perc = int(t1.similarity(t2) * 100)
        print "Word {} is {}% similar to word {}".format(t1.text, similarity_perc,  t2.text)

输出:

Word car is 100% similar to word car
Word car is 71% similar to word truck
Word car is 24% similar to word google
Word truck is 71% similar to word car
Word truck is 100% similar to word truck
Word truck is 36% similar to word google
Word google is 24% similar to word car
Word google is 36% similar to word truck
Word google is 100% similar to word google

当我们打算构建任何非常依赖于 NLP 实现的应用程序时,寻找单词或句子之间的相似性变得非常重要。如果你曾经使用过 StackOverFlow,每当我们试图提出一个新的问题时,它都会试图列出平台上已经问过的类似问题。这是最好的例子之一,在这种情况下,寻找两组句子之间的相似之处可能会有所帮助。spaCy 基于一个已经训练好的模型找到两个词之间相似性的信心纯粹取决于所采取的一般假设的种类。

在构建聊天机器人时,查找相似性对于以下情况非常方便:

  • 当构建聊天机器人进行推荐时

  • 删除重复项

  • 构建拼写检查器

我们学到的这些东西在构建聊天机器人时非常重要,这样我们就知道如何解析用户输入,以便在代码中编写业务逻辑时它们有意义。

聊天机器人了解自然语言处理方面的知识很好

在这一节中,我们将了解几个有趣的主题,当您计划编写自己的自定义 NLP 方法来处理某些场景时,这些主题经常会派上用场。确保你看完它们,因为当你最不期待的时候,它是最需要的。我们将简要讨论在聊天机器人场景中正则表达式的标记化和使用。

标记化

标记化是 NLP 的一个简单而基本的概念,我们将文本分割成有意义的片段。spaCy 首先对文本进行标记(即,将其分割成单词,然后是标点符号和其他东西)。您可能会想到一个问题:为什么我不能使用 Python 语言内置的 split 方法来进行标记化呢?Python 的 split 方法只是一个原始的方法,在给定分隔符的情况下将句子分割成标记。它不考虑任何意义,而标记化也试图保留意义。

让我们尝试一些代码,看看标记化是如何工作的。

例 1:

doc = nlp(u'Brexit is the impending withdrawal of the U.K. from the European Union.')
for token in doc:
    print(token.text)

输出:

Brexit
is
the
impending
withdrawal
of
the
U.K.
from
the
EuropeanUnion

如果您在上面的输出中看到,在标记化过程之后,U.K .作为一个单词出现,这是有意义的,因为 U.K .是一个国家名称,拆分它是错误的。即使在这之后,如果您对 spaCy 的标记化不满意,那么在完全依赖 spaCy 的标记化方法之前,您可以使用它的add_special_case case 方法来添加您自己的规则。

正则表达式

您必须已经了解正则表达式及其用法。这本书假设你必须熟悉一般的正则表达式。在本节中,我们将浏览一些例子,看看正则表达式在构建聊天机器人时是如何有益和有用的。

文本分析和处理本身就是一个大课题。有时候,单词以一种让机器极难理解和训练的方式组合在一起。

正则表达式可以方便地用于机器学习模型的一些回退。它具有模式匹配的能力,可以确保我们正在处理的数据是正确的还是不正确的。在“聊天机器人的历史”一节的第一章中讨论的大多数早期聊天机器人都非常依赖模式匹配。

让我们举两个简单易懂的例子。我们将尝试使用正则表达式从两个句子中提取信息。

帮我订一辆从机场站到香港站的地铁。

帮我订一辆从香港机场到亚洲国际博览馆的出租车。

代码如下:

sentence1 = "Book me a metro from Airport Station to Hong Kong Station."
sentence2 = "Book me a cab to Hong Kong Airport from AsiaWorld-Expo."

import re
from_to = re.compile('.* from (.*) to (.*)')
to_from = re.compile('.* to (.*) from (.*)')

from_to_match = from_to.match(sentence2)
to_from_match = to_from.match(sentence2)

if from_to_match and from_to_match.groups():
    _from = from_to_match.groups()[0]
    _to = from_to_match.groups()[1]
    print("from_to pattern matched correctly. Printing values\n")
    print("From: {}, To: {}".format(_from, _to))

elif to_from_match and to_from_match.groups():
    _to = to_from_match.groups()[0]
    _from = to_from_match.groups()[1]
    print("to_from pattern matched correctly. Printing values\n")
    print("From: {}, To: {}".format(_from, _to))

输出:

to_from pattern matched correctly. Printing values
From: AsiaWorld-Expo., To: Hong Kong Airport

尝试将sentence2改为sentence1,看看代码是否能很好地识别模式。鉴于目前机器学习的能力,正则表达式和模式匹配已经后退了一步,但请确保您对它有所了解,因为它可能随时需要从单词、句子或文本文档中解析特定细节。

摘要

在这一点上,你必须有公平的想法,为什么我们需要知道 NLP 之前,开始建立聊天机器人。在本章中,我们学习了 Python 中的 spaCy 模块,它的特性,以及如何安装它。我们深入研究了 NLP 的各种方法,这些方法在构建聊天机器人时被广泛使用。我们学习了词性标注、词干化和词条化之间的区别、实体识别、名词组块以及寻找单词集之间的相似性。

我们执行了所有这些概念的代码,并通过实践而不仅仅是阅读来学习所有这些,这正是本书所强调的。我们还复习了记号化和正则表达式的基础知识。我们将在下一章使用一个免费的工具 Dialogflow 来构建我们的聊天机器人。我们将在下一章学习如何训练我们的聊天机器人理解并提取用户给出的信息。

https://catalog.ldc.upenn.edu/ldc2013t19

**

三、使用最简单的方式构建聊天机器人

构建聊天机器人的简单方法已经写好了,请记住,有时你不想从头开始构建一切,只想把事情做好。这一章并不要求你做大量的编码工作,但是仍然给你一个公平的想法,如何以一种简单的方式构建聊天机器人,并将其公开。

这一章之所以对学习构建聊天机器人变得更加重要,是因为软件世界发展得太快,以至于无法适应。有时我们需要非常快速地构建应用程序,我们试图在开源库中寻找可用的工具,这些工具可以用来快速构建应用程序,而不需要重新发明轮子。有时候,我们不擅长编码来从零开始构建一切。即使我们想从头开始构建应用程序,我们也不能,因为对于新手来说,学习曲线太陡了。

本章将帮助你快速构建聊天机器人,并将其公之于众。

我们将尝试一个以前被称为 Api.ai 的工具,现在它被称为 Dialogflow。

Dialogflow 简介

Dialogflow 通过构建引人入胜的基于语音和文本的对话界面,如语音应用程序和聊天机器人,为用户提供了与产品互动的新方法。Dialogflow 由 AI 提供支持。它可以帮助你在你的网站、移动应用程序、谷歌助手、亚马逊 Alexa、Facebook Messenger 和其他流行的平台和设备上与用户联系。

Dialogflow 中的下图显示了它们如何处理用户请求。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-1

Dialogflow 架构的工作图

事情是这样的:

  1. 用户对着输入设备说话。

  2. 用户查询进入 Dialogflow 引擎。

  3. Dialogflow 试图识别其意图。

  4. 根据意图,完成一个履行,并从数据库返回数据。

  5. 响应返回给意图。

  6. 响应被转换成可操作的数据。

  7. 用户对信息的请求被反馈给输出设备。

在 Dialogflow 中有一个代理的概念,最好描述为自然语言理解(NLU)模块。这些可以包含在你的应用、产品或服务中,并将自然的用户请求转化为可操作的数据。当用户输入与代理内部的意图之一相匹配时,就会发生这种转换。

代理也可以被设计成以特定的方式管理对话流。这可以借助上下文、意图优先级、位置填充、责任和通过 webhook 的实现来完成。

入门指南

了解到目前为止我们所学到的东西是非常重要的,因为开源的免费工具和软件包并不总是有助于构建一个成熟的聊天机器人应用程序。

很多时候,您可能会遇到这样的情况:您希望自己构建所有东西,以便对应用程序有更多的控制权。我们将在下一章学习这些,并使用以前学过的 NLP 技术。

这一章是关于创建一个聊天机器人作为一个概念的证明,并使它准备好以最少的编程或没有编程经验的世界使用。

构建一个点餐聊天机器人

我们将创建一个聊天机器人的帮助下,一个特定的餐厅的 Dialogflow。我们把它命名为 OnlineEatsBot 。简而言之,我们可以称之为在线产品。您可以选择您想要构建聊天机器人的任何其他用例。在这一章中,我们将构建一个点餐聊天机器人。

确定范围

让我们来决定这个聊天机器人的范围——也就是说,它能做什么,能做到什么程度。

  • 它应该能够动态地问候用户。

  • 它应该能够理解菜单项及其数量的要求。

  • 聊天机器人应该能够代表用户下订单。

  • 当被询问时,告诉用户订单的状态。

上市意向

这里我们列出了我们希望聊天机器人用来训练的意图,这样当用户询问时它可以理解这些意图。

意图

  • 默认欢迎意图:当用户给聊天机器人发消息时

  • 下单意图:当用户要求机器人点餐时

  • 项目描述意图:当用户告诉他们想要什么项目和数量时

  • 订单状态:当用户想知道他的订单状态时

  • order _ ID:bot 需要理解用户的订单 ID 以便跟踪。

  • 用户感谢:当用户感谢机器人时

列出实体

我们将尝试在这里列出所有可能的实体。在这一章的后面,我们将看到它们被定义为适用的任何意图。

实体

  • food_items:用户想点什么菜?

  • 数量:用户愿意订购的食物数量是多少?

  • order_id:用户下订单的 order_id

构建一个点餐聊天机器人

让我们根据我们应该能够看到聊天机器人做的最少事情来设定对它的期望值。为此,让我们创建一个聊天机器人和用户之间的对话脚本。这有助于我们坚持计划,准备好一个基本的工作聊天机器人,假设用户以一种良好和正确的方式进行对话。

聊天机器人和用户对话脚本:

  • **用户:**你好

  • 你好,欢迎光临!我能帮你什么吗?

  • 用户:我想点中餐。

  • 当然,你今天想点什么?

  • **用户:**一份鸡肉馅饺子,两份春卷。

  • OnlineEatsBot: 完成。您的最终金额是 XYZ,您的订单是 1 个鸡肉饺子和 2 个春卷。

  • 用户:我还没有收到我的订单。我的食物在哪里?

  • 你能帮我输入你的订单 ID 吗?

  • 用户: 123456

  • OnlineEatsBot: 订单 ID 为 123456 的订单状态。送货员在你所在的地方,你的食物将在 5 分钟内到达。

  • **用户:**谢谢。

  • 非常感谢你的合作。

既然我们已经编写了一个基本脚本来构建我们的聊天机器人,现在我们将进入 Dialogflow。

Dialogflow 入门

让我们按照这些步骤在 Dialogflow 中创建一个帐户,然后创建一个代理。(代理只不过是聊天机器人的另一个名字。)

  1. https://dialogflow.com 创建账户,并登录账户。

  2. Create an agent.

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 3-2

    在 Dialogflow 中创建新代理

输入详细信息,如代理名称、时区、默认语言和您想要选择的 Google 项目,或者创建一个新的 Google 项目。

  1. 创造意图。

如果你看到图 3-3 ,你会看到我们已经有了两个意图。

  • **默认回退意图:**如果用户的输入与任何常规意图或启用的内置闲聊都不匹配,则触发回退意图。创建新代理时,会自动创建默认的回退意图。如果愿意,您可以修改或删除它。

  • Default welcome intent: We can extend this welcome intent for our own chatbots. You should add some of your own user expressions and default responses.

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 3-3

    在对话流中创建意图

在我们创建自己的意图之前,让我们先在默认的欢迎意图中添加一些话语,并使用以下步骤做好准备:

  1. 点击默认欢迎意向。

  2. 在训练短语中添加您自己的用户表达式。

  3. 点击保存。

当我们点击保存时,后台的机器学习模型会运行并训练我们提供的数据(即用户表情)。训练数据意味着让机器理解它基于我们提供的数据的意图,并能够预测我们何时向它提供任何新数据。例如,如果我们看图 3-4 ,在那里我们已经定义了五个用户表达式,机器已经知道它们属于“欢迎意图”,如果用户说“你好”,这在任何地方都没有定义呢?机器仍会将“Hello there”归类为默认欢迎意图,因为在新的用户表情中,训练中使用的功能和机器的欢迎意图是相似的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-4

在 Dialogflow 中定义默认欢迎或问候意图

让我们试着看看欢迎的意图是否对我们有用。有了 Dialogflow,我们可以在仪表板本身中完成这项工作。见图 3-5 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-5

测试 Dialogflow 中的欢迎意图

创建意图时要记住的几点

让我们看看在 Dialogflow 上创建意图时需要知道的一些要点。

  • Dialogflow 的 intent 还具有对每个 intent 进行默认响应的功能。默认响应是每次识别出意图时返回给用户的响应。在我们的例子中,当用户说“你好”,我们得到的是“你好!”作为机器人的回应。

  • 如果你愿意,你可以添加更多的响应或删除现有的响应,拥有多个响应会使机器人看起来更真实,这样它就不会每次都用相同的响应进行回复,并且对与机器人交谈的用户来说感觉更像人类。

  • 对话流中的意图也能够被标记为对话的结束。换句话说,您可以让机器人假设用户将不再参与对话,机器人可以根据这些信息采取必要的措施来结束对话。

创造意图和添加话语

现在我们已经创建了欢迎意向,让我们创建订单意向。我把它命名为 place_order_intent 。以下是我输入的用户表达式:

我想要食物

我想尽快点餐

你能帮我点菜吗?

请为我点餐

我想点中餐

我想下订单

请你帮我点餐好吗?

你能帮我点餐吗?

我想点餐

我想点泰国菜

我想点中餐

现在,我们已经建立了识别上述用户表达式或相关用户表达式的意图。现在,是时候使用对意图的默认响应将响应添加回用户了。

将默认回应添加到意向中

我们将添加三个可能的响应,一旦遇到 place_order_intent ,这些响应将返回给用户。

当然,你今天想要订购什么?

当然,你今天想吃什么?

当然,我会尽力帮助你。你今天想吃什么?

现在,下一步是等待用户输入他想要的条目并解析这些条目。

现在我们将创建一个新的意图,告诉我们用户实际想要点什么(例如,食物)。

我们创建一个名为 items_description 的新意图

首先,我们添加我们的标准用户表达式。

一份鸡肉饺子和两份春卷。

当我们添加用户表达式时,我们可以选择想要指定为意图实体的特定单词。这可能是数量、日期或时间、位置等。,这是预定义的,但我们可以在获得弹出框后,通过单击右下角的 Create New 按钮来创建自己的实体。

突出显示要将所选单词作为实体的话语中的单词。之后,它打开弹出框来创建我们自己的实体。

在这个例子中,我们应该能够以一种良好的可读格式解析数据,这样我们就可以使用任何编程语言来使用它。JSON 格式是当今跨平台应用程序中最好的格式。默认情况下,Dialogflow 以 JSON 格式返回数据,可以将其解析为类似下面的代码。人们总是建议让你的数据尽可能少;不要给出过多的数据来淹没 API 的响应。记住,所有这些都是要花钱的。

{

  "food_items": {
    "chicken dumpling": 1,
    "Spring rolls": 2
  }

}

项目说明意图和所属实体

我们可以选择一个和两个,并将其定义为@sys.number,它只不过是数据类型。我们将创建一个名为 food_items_entity 的新实体来标识食品。

如果你看一下图 3-6 ,你会发现我们有一个名为 food_items_entity 的实体,但是当我们选择单词时,我们将参数命名为 food_items_entity1food _ items _ ENTITY 2;食物数量也是如此,我们将第一个和第二个参数分别命名为 quantity1quantity2,

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-6

项目描述意图

我们在这里定义的内容将帮助我们理解 JSON 响应,我们将在 intent 被触发后得到它。我们应该有所有这些价值,以推进聊天机器人流程。

因此,选择整个单词或单词组合,然后点击 Create New *。*一个新的创建实体的屏幕将出现;只需输入这个新实体的名称并保存即可。

现在,回到我们对物品 _ 描述的意图,你应该会看到类似图 3-6 的东西。

继续在训练短语中添加更多的用户表达式,并继续定义其中的实体。

到目前为止,我们已经添加了四种话语,这是它们的样子。我们将添加尽可能多的,以便我们的代理对意图分类的准确性更好。

Dialogflow 还具有共享代理培训数据的功能。本书中使用的训练数据可通过 press 网站 https://github.com/Apress/building-chatbots-with-python 获取。正如您在图 3-7 中看到的,我们试图在 dialogflow 代理的项目描述意图中添加更多示例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-7

在项目描述意图中添加更多话语

现在,在这一点上,一旦我们保存了我们的意图,我们的代理已经完成了模型的训练。如果我们在右边输入下面的句子,我们应该能够看到下面的 JSON 响应:

一份鸡肉饺子和两份春卷

意向响应:

{
  "id": "e8cf4a44-6ec9-49ae-9da8-a5542a80d742",
  "timestamp": "2018-04-01T21:22:42.846Z",
  "lang": "en",
  "result": {
    "source": "agent",
    "resolvedQuery": "One chicken dumpling and two spring rolls",
    "action": "",
    "actionIncomplete": false,
    "parameters": {
      "quantity1": 1,
      "food_items_entity1": "chicken dumpling",
      "quantity2": 2,
      "food_items_entity2": "spring rolls"
    },
    "contexts": [],
    "metadata": {
      "intentId": "0b478407-1b37-4f9a-8779-1866714dd44f",
      "webhookUsed": "false",
      "webhookForSlotFillingUsed": "false",
      "intentName": "items_description"

    },
    "fulfillment": {
      "speech": "",
      "messages": [
        {
          "type": 0,
          "speech": ""
        }
      ]
    },
    "score": 1
  },
  "status": {
    "code": 200,
    "errorType": "success",
    "webhookTimedOut": false
  },
  "sessionId": "e1ee1860-06a7-4ca1-acae-f92c6e4a023e"
}

如果您查看 JSON 响应的参数部分,我们会看到

{
"quantity1": 1,
"food_items_entity1": "chicken dumpling",
"quantity2": 2,
"food_items_entity2": "spring rolls"
}

我们可以轻松地编写一些 Python 代码,将 JSON 转换成我们讨论过的预期格式。

你能做到吗?

只需测试您的 Python 技能,并尝试编写一段代码来读取类似前面的 JSON,并以我们之前讨论过的另一种 JSON 格式返回属于它的数量和食物项目。

理解并回复用户

现在,对话中的下一步是让机器人回复用户订单已被理解,以及任何新的信息。新信息可以是生成的 order_id、订单金额或预期交货时间。这些东西将在你的服务器端被填充,你可以用机器人的响应把它公式化给用户。

现在,让我们尝试在我们的案例中添加订单金额;为此,我们可以使用 Dialogflow 的默认响应特性,并将其添加到 intent 中。现在让我们硬编码这个金额,因为这个金额会根据食物项目、它们的数量或餐厅而变化。在本章的后面,我们将讨论如何通过调用一个 API 来使它动态化。

有趣的是,我们可以访问从意图中获得的参数(例如,食物项目及其数量)。

响应可以包含对参数值的引用。我们马上就会明白这一点。

如果一个参数出现在参数表中,我们可以使用下面的格式在“文本响应”字段中引用它的值:$parameter_name。

我们可以在默认响应中使用这个参数,以便机器人向用户确认订单。

添加“完成。您的最终金额为 XYZ,作为回应,您的订单为$数量 1 f o o d i t e m s e n t i t y 1 和 food_items_entity1 和 fooditemsentity1数量 2 $food_items_entity2"

注意

如果我们的意图无法解析食物项目或它们的数量,我们需要给出不同的默认响应,要求解释我们的机器人无法理解的内容,或者至少确认一下。我们已经在“向意向添加默认响应”一节中学习了如何向意向添加默认响应

订单状态意图

现在,让我们创建 order_status 意图,其中用户可能试图在下订单后询问订单的状态。

图 3-8 提供了我们为订单状态意图添加的一些训练短语,我们将该意图命名为 order_status

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-8

创建订单状态意图

现在,让我们尝试一些随机的订单状态询问话语,看看我们的代理是否足够聪明来识别意图。

我试了试,“还没有收到我的食物,瞧,我的代理完全正确地认为这是一个订单状态意向。

参见图 3-9 中 JSON 的 resolvedQuery 及其 intentName。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-9

查询解析后来自 Dialogflow 的 JSON 响应

User_Order_ID 意图

现在,接下来是向用户询问订单 ID,所以让我们设置这个意图的默认响应来询问下面的问题。

你能帮我处理一下你的订单 ID 吗?

现在,用户将给出他们的订单 ID,我们的任务是识别并再次给出响应。

因此,为此我们需要创建另一个意图来识别用户何时谈论订单 ID。

请注意,我们正在创建的意图几乎是相互独立的。在这种情况下,我们知道用户将给出订单 ID,这在大多数情况下是正确的。如果它是错误的,你可以随时回到用户那里再次询问。

我们还应该注意,在某些情况下,order_id 和电话号码可能都是整数。在这种情况下,我们需要进行一些验证,比如 order_id 或电话号码中的位数。此外,根据上一个问题的上下文,您可以判断用户给出的是 order_id 还是电话号码。正如在第一章中所讨论的,我们总是可以使用决策树来更好地管理聊天机器人的流量。此外,我们可以通过编程保持跟踪,在 order_status intent 之后,我们请求订单 ID,用户将发送一些订单 ID(一些数字),这在代码中更容易解析,而不是创建一个新的 intent。

在本例中,我们将创建 user_order_id 意向,因为不存在冲突。

现在,我们创建一个名为 user_order_id 的新意图

图 3-10 显示了我们的 user_order_id 意图的样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-10

在我们的代理中定义用户订单 ID 意图

我测试了几个表达式,将它们正确分类为 user_order_id intent 效果很好。始终使用 Dialogflow 控制台进行测试,以查看您的意图是否如预期的那样运行。

现在,让我们将 user_order_id intent 的默认响应设置为来自机器人的以下响应:

订单 ID:$Order _ ID 的订单状态。送货员在你所在的地方,你的食物将在 5 分钟内到达。

我们再次使用从 user_order_id intent 解析的参数来准备对用户的回复。

User_Thanks 意图

接下来,用户可能会感谢,如果不是别的,所以我们创建了一个新的意图,称为 user_thanks 来识别用户说谢谢的不同方式。这很重要,因为一旦用户以某种方式说谢谢你,我们的机器人应该会同样回答。

我们不应该只是期望用户在交付状态默认响应后说谢谢并盲目回复,而是尝试使用自定义意图来识别它。

图 3-11 显示了我们的用户 _ 感谢意图的样子。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-11

定义用户说谢谢时的意图

现在,是时候对使用默认响应功能的用户说谢谢了,并将这一意图标记为对话的结束。

让我们添加一些文本,如“*非常感谢您的合作,”*作为我们的默认响应。

我们可以添加更多这样的响应,让机器人看起来更真实(见图 3-12 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-12

在代理中添加违反用户意图的响应

查看图 3-12 ,我们已经将此意图作为对话的结束。

如果我们试图将我们的机器人与谷歌助手集成,那么启用这意味着当意图完成时关闭谷歌助手中的麦克风。

现在,在这一点上,我们已经创建了我们的机器人,按照我们最初的设计和脚本构建它,并训练它。现在,是时候把它部署到网络上,看看它看起来怎么样。

在 Web 上部署 Dialogflow 聊天机器人

在这一部分,我们将把我们的机器人与各种平台整合起来,如 Facebook Messenger、Twitter、Slack 等。,看看它们是否有效。还有很多平台可以让你轻松集成这个机器人。

现在,我们将使用 Web 演示和 Facebook Messenger 测试我们的机器人。

让我们转到我们的 Dialogflow 帐户中的集成页面,并启用 **Web 演示。**您将会看到一个弹出窗口,如图 3-13 。单击弹出窗口中的链接。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-13

“安静”web 演示链接

你将会看到类似于图 3-14.1 到 3-14.4 的东西。我用我们写的对话测试了我的机器人,我的机器人非常好用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-14.4

OnlineEatsBot 演示对话屏幕 IV

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-14.3

OnlineEatsBot 演示对话屏幕 III

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-14.2

OnlineEatsBot 演示对话屏幕 II

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-14.1

OnlineEatsBot 演示对话屏幕 I

除此之外,我们还可以使用弹出窗口中的 iframe 代码将这个机器人嵌入到我们自己的网站中。

在此与我的在线食客交谈:

https://bot.dialogflow.com/c9b3f731-599e-4396-a35f-0d77497b46ef

与你的朋友和家人分享你自己的机器人,看看他们如何以合法的方式与机器人互动。如果你的聊天机器人没有做预期的事情,那么试着去解决它。

在 Facebook Messenger 上集成 Dialogflow 聊天机器人

在这一部分,我们将尝试将我们的聊天机器人集成到 Facebook Messenger 中,这样我们在脸书平台上的用户也可以使用它,而不必访问我们的网站。

让我们返回到 Dialogflow 仪表板中的 integrations 页面,启用 Facebook Messenger 图标,然后单击该图标,这将弹出一个与之前类似的弹出窗口。

在这里,我们需要去脸书,注册一个应用程序,并获得所需的令牌。

  • 验证令牌(任何字符串,仅供您使用)

  • 页面访问令牌(输入在脸书开发人员控制台中生成的令牌)

基于 Dialogflow 技术,Dialogflow 脸书集成非常有助于使用 NLU 轻松创建 Facebook Messenger bot。

建立脸书

为了让我们的机器人像在脸书那样工作,我们需要做以下事情:

  1. 创建一个脸书账户,如果你还没有

  2. 创建脸书页面,您可以添加您的机器人。

当用户访问你的脸书页面并向你发送消息时,他们将直接与你的机器人对话。

创建脸书应用程序

以下是创建应用程序的步骤:

  1. 登录脸书开发者控制台

  2. 点击右上角的我的应用

  3. 点击添加新应用并输入姓名和联系电子邮件地址。

  4. Click Create App ID as shown in the Figure 3-15 below.

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 3-15

    在脸书开发者平台创建新应用

  5. 在下一页,点击信使选项的设置按钮。

  6. Under the Token Generation section, let’s choose the Facebook page to which we want our bot to connect (see Figure 3-16).

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 3-16

    通过为您的机器人选择脸书页面来生成令牌

这将生成一个页面访问令牌。请将此令牌放在手边,因为我们需要在 Dialogflow 中输入它。

设置对话流控制台

以下是步骤:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-17

使用 Facebook Messenger 设置和集成 Dialogflow】

  1. 点击左侧菜单中 Dialogflow 控制台中的集成选项,并打开 Facebook Messenger ,如果你还没有打开的话。在打开的弹出窗口中,输入如下信息,如图 3-17 设置并集成 Dialogflow 与 Facebook Messenger:

    • **验证令牌:**这可以是您想要的任何字符串,并且用于您自己的目的

    • **页面访问令牌:**输入在脸书开发人员控制台中生成的令牌

  2. 点击开始按钮。

您应该会收到一条消息说,“Bot 已启动。”这意味着我们可以走了。

您一定想知道什么是回调 URL、验证令牌和页面访问令牌。让我们试着去理解这些。

回拨 URL

一个回拨网址只不过是一个公众可访问的网址,脸书将发布任何来自你的脸书页面的实时请求。

假设你试图在网上支付你的食物,然后你被重定向到一个银行的支付页面。现在, OnlineEats 必须给银行一个回拨 URL,在支付完成后,他们可以将用户重定向到该 URL。

在这里,脸书不会做任何重定向,但会把我们的用户在页面的聊天框中发送的所有信息发布到 webhook 或回调 URL。

现在,一旦我们在服务器上收到消息,我们就进行意图分类和实体解析,然后制定您想要回复给用户的内容。

验证令牌

验证令牌是在验证订阅时发送到端点的任意字符串。之所以需要它,是为了确保我们的服务器知道请求是由脸书发出的,并且与我们刚刚配置的订阅相关。

假设别人知道了你的 webhook,冒充脸书发布消息,那么 verify_token 就会进入画面,你来验证消息来源是否正确。基于这个令牌,您还可以处理来自多个源的 POST 请求,因为将为不同的源定义不同的令牌,但是回调 url 是相同的。

访问令牌

脸书 API 需要页面访问令牌来管理脸书页面。它们对每个页面、管理员和应用程序都是唯一的,并且有过期时间。

注意

保留回调 URL 和验证令牌,以便现在配置 webhook。

配置 Webhooks

要配置我们的 bot 的 webhook,让我们回到脸书开发人员控制台:

  1. 点击仪表板上的添加产品部分下的设置按钮。如果您还没有订阅 webhooks,那么您将会看到一个选项“订阅这个对象”点击此按钮,弹出一个新窗口,并输入以下信息:

    • 回调 URL :这是 Facebook Messenger 集成页面上提供的 URL。

    • 验证令牌:这是您创建的令牌。

  2. 进入信使➤设置➤设置网页挂钩。你会得到一个类似图 3-18 的弹出窗口。添加您的回拨 url 并验证令牌。

  3. 勾选订阅字段下的消息消息 _ 回发**选项。**您完全可以选择您的用例所需的任何一个。

  4. 点击验证并保存按钮。查看图 3-18 以供参考。

你将被带回到设置页面,并且 Webhooks 应该有一个“完成”状态。请确保选择一个页面,您可以为页面事件订阅您的 webhook。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-18

在脸书为 Dialogflow bot 设置 webhooks

测试信使机器人

为了能够测试我们的机器人,我们需要公开我们的应用程序:

  1. 点击脸书开发者控制台左侧菜单中的应用审查

  2. 点击下的开关让<你的 APP 名>公开?如果您得到一个无效隐私政策 URL 的提示,然后转到对话框中的基本设置链接,如果您还没有,暂时输入隐私政策 URL 的任何 URL,然后单击保存更改。现在,回到应用审查页面,尝试再次将应用切换到公共。

  3. 系统将提示您为您的应用选择一个类别。

  4. 从列表中选择教育。随意选择最适合你的机器人。

  5. Click the Confirm button as shown in the Figure 3-19, Making your facebook app public.

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    图 3-19

    公开你的 facebook 应用

我们还需要为我们的页面创建一个用户名。这是用户使用我们的机器人聊天时使用的用户名。要设置用户名,点击页面“关于”部分下的创建页面@用户名链接,如图 3-20 所示。这有助于与仅使用短名称的人共享您的页面或 bot。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-20

创建您的脸书机器人的页面用户名

让我们在 Facebook Messenger 上测试我们的机器人的相同流程,我们在 Dialogflow 的网站上测试过。从图 3-21.1 到图 3-21.4 ,你应该可以看到我的 Facebook Messenger 机器人是如何回应的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-21.4

Facebook Messenger 在线版演示屏幕四

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-21.3

Facebook Messenger 在线版演示屏幕 III

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-21.2

Facebook Messenger 在线版演示屏幕 II

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-21.1

Facebook Messenger 在线 EatsBot 演示 屏幕 I

伙计们,这就是我们建造机器人的方式。

第四章将会更加有趣。在第四章中,我们将尝试在不依赖于 Dialogflow 的 API 或 dashboard 的情况下实现同样的功能。

当你能完全控制你所拥有的一切的时候总是好的,不是吗?

注意:您可以转到您的帐户设置,导出一个代理或直接导入其他代理。可以下载 zip 文件( OnlineEatsBot.zip )。您可以使用这个 zip 文件将它导入到 Dialogflow 中,并使用我们在本章中构建的聊天机器人。

您一定想知道,如果我想实时下订单,并使用供应商/餐馆的 API 查找订单状态,然后相应地回复用户,会怎么样?它可以是您想要进行的任何 API 调用——实时检索数据并制定机器人的响应。在我们结束本章并为下一章做准备之前,是时候知道如何做了。

让我们来了解一下 Dialogflow 中被称为“ Fulfillment ”的东西。

完成

为了获得用户请求的实时信息,我们需要开发一些 API 或使用现有的 API。为了使用 Dialogflow 实现这一点,我们需要设置 fulfillment ,这需要部署一个服务并调用一个 API。

我们不会深入构建 API 以及如何部署它的细节,但是如果你曾经尝试过使用任何谷歌或脸书的 API,你至少应该熟悉如何调用它们。

我已经构建了一个基于 Flask 的小 API,并将其部署到 Heroku。我将把它用于履行,它只接受 url 中的任何 order_id,并返回一个随机的 order_status。如果您不熟悉 Heroku,那么不要担心,您可以运行本地系统上提供的代码并测试它。在接下来的章节中,我们将使用 Heroku 部署大量的应用程序,您可以从中学习相关的知识。

在代码中,您可以了解 order_identity、intentName 等。,被解析。

在这里找到代码:flask _ online eats _ demo . zip

请求网址: https://radiant-bayou-76095.herokuapp.com/onlineeatsbot/api/v1.0/order_status/

因此,在 Dialogflow Fulfillment 中,会将来自 intent 的 JSON 响应发送到这个 URL,您需要解析它以获得相关的实体及其值,并执行特定的操作。

您还可以尝试在 Heroku 上部署示例 Flask 应用程序代码,并让您自己的端点在您的 bot 中工作以实现。

现在,Dialogflow 将发布我们的端点上启用 webhook 调用的目的的 JSON 响应。它有代码来解析 order_id 实体并基于此采取行动。目前,代码只返回从列表中随机选择的状态。

要测试 API 是否工作,请使用图 3-22 中的样本数据进行测试。如果您在本地运行 Flask 应用程序,那么使用本地 url。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-22

在 POSTMAN 中测试 heroku 上部署的实现 API

启用 Webhook

因此,让我们转到 Dialogflow 中的 fulfillment 页面,并尝试启用 webhook(参见图 3-23 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-23

在 Dialogflow 中为实现设置 webhook

确保您已经为 user_order_id intent 启用了 webhook 调用(参见图 3-24 )。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-24

为特定目的启用 webhook 调用

Dialogflow 将向您的 webhook URL 发布一个 JSON 主体,看起来如图 3-25 所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-25

从 Dialogflow 到我们的 webhook 端点的传入 JSON 数据

检查响应

每当 Dialogflow 向您的 web 服务发布一个 intent 的 JSON 响应(如图 3-25 所示)时,它都会期待来自您的 web 服务的如图 3-26 所示格式的响应。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 3-26

Dialogflow 需要来自 webhook URL 的响应

如果你认为你的 API 的响应应该和图 3-26 的格式完全一样,那么放松点——事实并非如此。您的意图不会抛出错误,因为 JSON 主体中的所有键都是可选的。

下面是我的 API 响应的外观和工作方式:

{
    "fulfillmentText": "Order ID: 9999\. It's on the way",
    "payload": {
        "facebook": {
            "text": "Order ID: 9999\. It's on the way"
        }
    }
}

当我再次尝试点击相同的 API 时,我得到了不同的订单状态文本,但格式与 Dialogflow 引擎预期的相同。

{
    "fulfillmentText": "Order ID: 9999\. Rider has picked up your food, please wait for another 10-15 minutes",
    "payload": {
        "facebook": {
            "text": "Order ID: 9999\. Rider has picked up your food, please wait for another 10-15 minutes"
        }
    }
}

fulfillmentText 是代理回复用户的关键。

现在,使用公共 URL 或在 Dialogflow 代理本身中尝试 bot,以查看来自 API 的响应,而不是我们前面添加的默认静态响应。

这就是我们如何使用 Dialogflow 的 fulfillment 特性将外部 API 或我们自己的 API 集成到我们的 chatbot 中,从而使事情变得动态和实时。

摘要

在本章中,我们学习了 Dialogflow 以及如何使用 Dialogflow 来构建聊天机器人。我们学会了定义意图和它们各自的实体。我们构建了一个简单的点餐聊天机器人,它可以理解用户点餐的意图,也可以理解用户点了什么食物以及数量。我们还增强了我们的聊天机器人,让用户可以询问他们的订单状态,并从他们那里获取他们的订单 ID,然后用不同的订单状态来制定响应。

我们还学习了 Dialogflow 中的 fulfillment,我们从自己的 API 中提取订单的状态,并基于此向用户给出响应。我们学会了创建聊天机器人的 web 演示,还将聊天机器人与 Messenger 集成在一起。至此,您应该对聊天机器人的端到端工作方式有了大致的了解。

在下一章中,我们将尝试构建聊天机器人的更难的方法。是的,你没听错。我们将消除对 Dialogflow 等工具的依赖,并通过编程自己构建一切。让我们为下一章做好准备,因为当你自己从头开始构建一切的时候,那将会更加有趣。这就像训练和驯服你自己的聊天机器人。

下一章见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值