GTLC全球技术领导力峰会·上海站,首批讲师正式上线! 了解详情
写点什么

深度学习是如何帮助携程机票客服提高对话效率的

2019 年 12 月 08 日

深度学习是如何帮助携程机票客服提高对话效率的

一、背景介绍

作为一家“以客户为中心”的服务型企业,携程一直以来都在旅行服务上下了很大的功夫。从成为第一家设立大规模联络中心的公司,到开办中国旅游业首个客服节,服务已经成为了携程最核心的竞争优势。快速的服务响应能给旅客带来更好的出游体验。


对于机票在线客服而言,如何在部分聊天内容中快速判断客人问询的意图,进而提供解决方案或者引导客人自助操作,成为了一个十分重要的问题。


当客人进入机票客服聊天界面后,是有两个对话阶段的。


一个是机器对话阶段。这个时候还没有接通人工客服,是机器客服在引导客人自助解决问题。机器客服,也叫机器管家,会提供一些常见的问题,用户点击问题后获得对应的解答。


但是常见问题不一定是客人想要的问题,这个时候就需要人工客服出场了,即进入第二个对话阶段:人工对话阶段。


在人工对话阶段,会有客服人员解答客人的疑惑。但事实上,很多客人在机器对话阶段就已经描述了自己遇到的问题,而接通人工客服后,客服可能还需要先翻看客人之前的描述,这个过程比较耗时,效率低而且对客人的体验不好。因此我们需要在接通人工客服前先对客人描述的内容做一次总结,这样客服就可以预知客人想了解什么,并且提前寻找解决方案。



在实际建模过程中,由于机票场景的复杂性,要想模型有非常好的效果,既需要对机票的业务知识有很深的理解,又需要对机票客服对客人的服务习惯有很好的认识。例如当碰到客人的问题是“我要退票”时,客服更关心客人为什么退票,是航班延误导致了退票,能否帮客人获得补偿?还是日期订错导致的退票,能否提醒客人直接改签?


这就要求我们在建模过程中,把对机票业务的理解融入到模型之中,除了基本的文本挖掘模型之外,还要设计一套针对机票业务场景的模型调用方案,以实现模型的定制化,这部分既是我们模型效果提升的重点,也是提高服务质量的关键。


接下来我们会从分析问题着手,分享怎样一步步去解决问题,以及一些注意事项和总结。内容主要包括:理解问题的本质、文本的预处理、样本平衡和文本等长处理、模型框架、模型训练方式、模型效果、线上的定制化等。


二、理解问题的本质

开始解决问题之前需要先弄懂问题的实质,因为我们的处理对象是文本,因此这是一个 NLP(自然语言处理)问题,而 NLP 要解决的问题主要有:


  • 文本聚类


例如:我们会根据一些关键词的出现次数对用户聚类,划分不同的用户群等。


  • 文本分类


例如:对评论内容分类,区分是正向评论或负向评论等。


  • 文本生成


例如:机器翻译等。


我们要解决的问题实质上是一个文本多分类问题,因为我们要把用户描述的内容对应到一些标准问题上,这些标准问题(也叫业务点)是客人常问的几百个问题,并且这些业务点已经有了比较标准的解决方案。


值得注意的是,比较常见的问题通常有非常多的样本,相比而言,那些不常见的问题可能就只有很少的样本,因此样本不平衡在我们的问题中尤为突出,后续我们会谈到解决方案。


在下一步的建模之前先对我们的样本做一些基本描述:我们用到的样本量为 30 万+,对应的标签类别数为 400+,其中不同类别对应的样本量极不平衡,样本比的最大差距在 3000:1 以上。


三、文本的预处理

机器学习建模过程都要有一个预处理的过程,甚至是整个建模工作的核心,NLP 问题同样不例外。因此我们需要先对文本数据做一些预处理。


一段文本从构成来看,可以简单分为中文、英文、特殊字符,由于我们用到的是客人的聊天数据,中文和英文居多,因此这里把其他文字、标点符号、表情符号等都认为是特殊字符,接下来这三部分也分别做相应的处理。



3.1 中文的处理

中文的处理主要包括:简繁体转换、分词。


a. 简繁体转换


通常把繁体转简体,这里推荐使用 HanLP 模块;


b.分词


指的把一句话切割成不同的词,分词的作用在于提供先验信息。例如“派出所有人吗”,这句话是有两种切分方式的,对于我们而言,使用哪种切分方式既取决于我们已有的知识(哪些字组合起来是一个词),也取决于当前的语境(哪种词汇组合出现的可能性最大)。


而分词其实就是提供这样一种先验信息,即提前指出哪些字应该组合起来形成词,一句话的哪种拆分方式最常用。这里我们推荐使用 jieba 或 HanLP 模块,两个模块之中更加推荐 HanLP。


3.2 英文的处理

英文的处理主要包括:大小写转换、词根还原、误拼转换等。


a. 大小写转换


可以全部转为小写或者全部转为大写。


b. 词形还原


指把英文词汇还原成为一般形式,例如复数还原为单数,过去时还原为原始形态等等。


c. 误拼转换


可以针对一些高频误拼或者缩写的词可以做一下还原,统一成原始形态。


3.3 特殊字符的处理

特殊字符主要是一些标点符号和表情符号等,这类字符需要过滤掉。可以考虑过滤掉除有效字符(中文、英文、数字)外的所有其他字符,需要注意的是句子中的标点符号(通常是逗号、句号)由于起到分割句子的作用,因此可以考虑不做剔除。


需要注意的是,文本预处理中绝大部分处理的目的都是为了降维,即通过把同一个词的不同形式还原,缩小最终词汇量。


四、其他处理

4.1 样本平衡

前面提到过,我们的数据有非常明显的样本不均衡问题,由于最终的评估指标是准确率,因此需要先对样本不均衡做处理、这里我们的做法是对样本量过少的类别进行重采样,但要注意采样时需要设置合适的比例。


4.2 文本的等长处理

在将文本投入模型之前,需要把分词后的句子转化为相同长度的向量,这就意味着过长的句子我们需要截取,过短的句子需要在句子前或句子后补零,那么多长才是合适的呢?


这要看分布,例如我们发现绝大部分句子包含的有效词组都在 N 个以内,因此我们可以设置最终输入的长度为 N。


五、模型框架

模型框架包括文本向量化和模型结构两部分。


5.1 文本向量化

文本向量化指的是把文本表示为数值向量,才能投入模型进行数值计算,这里有两种做法,一种是词袋模型(BOW),以所有样本中出现的词为词典,统计每个词出现的次数,这样就能把一句话转化为一个向量,向量的长度等于词典大小,向量中的数值就是词频。


很显然,这种做法忽略了词的顺序,并且生成的向量带有高维度、高稀疏性的特点,那么怎样才能利用词的顺序信息呢?我们把每个词都表示一个向量,这样把整句向量化时就可以保留词的顺序信息,这就是词向量模型。


词向量模型基于分布假说,即上下文相似的词,语义也应该相似,这样根据词的上下文关系构建模型,训练后就将每个词都表示成了一个向量,这方面比较常用的方法有 Word2Vec、GloVe、Bert 等。



词向量可以这样理解:当我们把词表示成 one-hot 形式后,通过乘上一个嵌入矩阵(Embedding Matrix)就可以得到词向量,而不管是采用无监督或有监督的词向量模型,其最终目标都是为了获得这个嵌入矩阵和对应的词向量。


5.2 模型结构

模型结构这里我们主要讲两种比较常用的模型,TextCNN 模型和 Bi-GRU 模型。


TextCNN 模型


TextCNN 模型由 Yoon Kim 于 2014 年提出,是将原本常用于图像领域的 CNN 模型应用于 NLP 领域,主要结构如下:


a. 卷积窗的高度


卷积核的高度通常设置为 3、4、5,代表一次覆盖多少个单词。


b. 卷积的方向


卷积时通常使用一维卷积,即只沿着高度这一个方向卷积,如果使用二维卷积,需要限制卷积窗口的宽度始终等于词向量的长度,等价于一维卷积。


c. 卷积通道 (Channels)


将卷积窗口作用于不同的词向量矩阵,例如 Word2Vec 和 GloVe,也可以是静态词向量和动态词向量


d. 池化层(Pooling)


通常使用 Max Pooling 或 K-Max Pooling。


TextCNN 的优势是可以充分利用并行优势,并且也拥有很好的效果,缺点是池化操作会丢失位置信息,并且模型的可解释性不强。



Bi-GRU 模型


Bi-LSTM 由 Schuster,Paliwal 等人于 1997 年提出,Bi(Bidirectional)是双向的意思,就是同时使用时序数据的前向及反向信息。GRU 由 Cho 等人于 2014 年提出,主要是将 LSTM 的遗忘门(Forget Gate)和输入门(Input Gate)合并成为单一的更新门(Update Gate)。



Bi-GRU 的优点是可以捕捉到较长时间的信息,使用双向 GRU 相比单向 GRU 有更强的表达能力,而 GRU 相比于 LSTM 有更少的参数,因而可以更快收敛。缺点是由于时序结构的特点,并行效率很低。


六、模型训练方式

模型训练方式大体上分为两种,静态词向量方式和动态词向量方式。


6.1 静态词向量

指的是预训练词向量后固定起来,在训练模型的过程中词向量不再更新,这种方式在数据量很少时会有比较好的效果,因为预训练的词向量带来了额外的有用信息。


6.2 动态词向量

指的是预训练词向量或生成词向量后,在后面的训练过程中也要更新,在数据量很大的情形下,这种方式最终会生成比较适用于当前数据集的词向量。


七、模型效果

我们使用一块 GPU 做训练,并且比较了不同模型的效果,结果如下:


模型主要结构每轮训练时长准确率
TextCNNFilters=128
Kernel size=【3,4,5】
104s91.07%
LSTMUnits=300953s90.9%
Bi-LSTMUnits=1501700s92.3%
Bi-GRUUnits=1501440s91.29%


需要注意的是,由于参数量的差别,此处的准确率对比并不严谨,但可以看出在使用 GPU 的情况下,TextCNN 拥有非常短的训练时长,并且取得了不错的效果。


八、线上定制化

模型的离线效果只代表了线下理想场景中的预估结果,而在线上实际调用时,还需要针对机票的业务场景设计专门的调用方案,以做到针对机票场景的“定制化”。


在实际使用时,我们经常会碰到这样的场景:客人在描述一个问题时会说很多句话,并且穿插一些和业务无关的语气词、感谢词等,例如:“你好”、“谢谢”、“嗯嗯”、“麻烦啦”等等。在这种场景下,我们第一步要做的就是过滤无意义的内容,只将包含业务点的句子投入模型。


8.1 无意义句子的识别

过滤无意义句子的一个传统方法就是把无意义的关键词加入正则表达式中,使用正则表达式过滤掉包含这些关键词的整句话,但这种做法的缺点是无法穷举所有的无意义词汇组合,此外,如果是包含业务点的句子含有无意义词汇,使用这种过滤方式会丢失整个业务点。


在这里我们使用了一种无意义程度算法,做法如下:


a. 先把无意义的关键词写入正则表达式,使用正则表达式对原句正则提取;


b. 把正则提取的词汇按顺序拼接起来,形成一个整句;


c. 将拼接后的句子和原句计算相似度(使用编辑距离),根据相似度计算的结果设置一个阈值,从而剔除掉无意义句子。


使用这种无意义程度算法,我们可以灵活的调整阈值,既可以保留机票的业务点,又能过滤无意义句子。


在实际工作中,任何机器学习模型都应该是为当前的业务场景定制的,只有适合机票业务场景的模型,才能发挥更大的价值。因此我们也针对模型的应用场景做了专门的优化。


8.2 针对机票业务场景的优化

由于我们的模型最终是为一线客服提供参考,因此评判输出结果是否合格的核心标准就是:模型结果是否有助于客服判断客人潜在意图,是否能够作为直接参考,来帮助客服快速解决客人的问题。


前面提到过,在机票场景下,有一些问题对应的样本量非常多,原因是这些问题在客人的订票流程中非常常见。


例如“我要改签”就是比较常见的一个问题,尽管这是个常见的问题,但背后可能有复杂的原因,客人可能是遇到航班延误想要改签,也可能是日期订错想要改签,甚至是一些其他的服务问题导致的改签需求,这时客服就更希望能了解客人的改签原因,以便更好的帮助到客人。在这种场景下,当我们判断出当前的业务点是“我要改签”时,就需要从前面的句子中追溯到上一个业务点,把这两个业务点同时展示给客服。


此外我们还做了其他针对机票场景的细节调整,这些调整都需要对机票业务点有比较深的理解,使模型最终做到了“定制化”。经过这部分调整后,模型的线上准确率由 91%提升到了 97%以上。


九、总结

最后,我们做一下简单的总结,整理一下建模过程中的注意事项。


分词


由于分词模块通常都是使用的 98 年人民日报语料库,其包含的单词及词频不一定适用于你的数据集,因此建议维护一套自有的词库。


样本


在训练过程中,预测错误的样本(Bad Case)非常重要,分析预测错误的样本并做相应的调整对提升我们模型效果有很大的帮助,同时,对样本做平衡处理也会对模型有很大的影响。


训练方式


训练方式部分我们推荐使用动态词向量的方式,因为只有这样最终得到的词向量才更适合你的数据。


模型结构


值得一提的是,TextCNN 是非常好用的入门模型,更快的训练速度及不错的效果保证了你可以很快得到一个基准结果(Baseline),在这个结果的基础上你可以进行调参操作或尝试使用更复杂的模型。


防止过拟合


由于深度学习模型很容易过拟合,因此 Dropout 对于你的模型来说是必备的。


针对业务场景的调整


无论是传统的统计模型、机器学习模型,或是机器学习比较火的一个分支——深度学习,乃至人工智能(AI)技术,都是为了从数据中寻找当前场景背后的规律,因此都应该植根于应用场景,针对应用场景做数据的分析、整理、模型选择以及后期的优化。


作者介绍


李元上,携程机票研发部高级数据分析师,擅长结合业务经验设计模型方案。目前负责携程值机选座算法设计、机票客服会话机器人的模型开发工作,关注新技术在项目中的应用价值。


本文转载自公众号携程技术中心(ID:ctriptech)。


原文链接


https://mp.weixin.qq.com/s?__biz=MjM5MDI3MjA5MQ==&mid=2697269173&idx=2&sn=b6b848336f1dbfbbf0cce22f40f3e8a8&chksm=8376f081b4017997a025dd1c1d39d339978495ae6e981d6b8b9b823f8da3c1d3650bf5c6af91&scene=27#wechat_redirect


2019 年 12 月 08 日 08:001114

评论

发布
暂无评论
发现更多内容

测试驱动开发英制单位转换

escray

学习 CSD 认证实战营

系统的安全性设计

Janenesome

读书笔记 程序员 架构 安全

这样理解Java中的函数式编程就对了

jerry

java8 函数编程

Redis学习笔记(散列类型)

编程随想曲

redis

在 TypeScript 处理空值异常

寇云

typescript 前端开发

jenkins集成maven获取远程项目

kcnf

性能优化第一课:性能指标

kimmking

性能优化

一个英语渣的自救手册

寇云

学习 效率工具 程序员人生 工作效率

权限系统设计的一种解法

双城笔录

产品 总结 产品设计

央行:取消境外机构投资者额度限制,推动金融市场进一步开放

kimmking

人生需要做减法:少即是多

我心依然

程序员 人生 减法 少即是多 less is more

iTerm2使用小技巧-密码管理器

小菜与老鸟

iTerm

牛排等级之美国篇

地藏@易果18916037281

Java并发编程基础--Synchronized

Java收录阁

线程

吾谈教育

ItsFitz

关于架构的几件小事:架构是什么

北风

架构 企业架构

第一篇InfoQ的博客

程序员小岑

写作 体验

最好的汇报是不需要汇报

伯薇

团队管理 领导力 沟通 汇报 可视化

讨论:应不应该用存储过程?

kimmking

地址收录

gogogo

深入理解Java中的Lambda表达式和函数式编程的关系

jerry

Lambda java8 函数编程

道德和正确的认知

沈传宁

信息安全 计算机道德

没有业务规则的技术实现

wd

吐槽

算法篇之数组右移

月夜

算法 数组右移

我为什么不买Mac

Winann

效率 效率工具 Mac apple

回"疫"录(9):守住我们自己的净土

小天同学

疫情 回忆录 现实纪录 纪实

不安全的“安全密码”

沈传宁

信息安全 口令安全

spring boot 集成 elasticsearch 7.x (一)

wd

elasticsearch high level client

关于 DeepL 机器翻译能力

梁帅

产品 互联网 机器翻译 谷歌Google DeepL

Ubuntu 20.04 装机手册

小柒

Linux #Ubuntu #geek

写文章的目的是什么?

小天同学

思考 写作 感悟 表达

DNSPod与开源应用专场

DNSPod与开源应用专场

深度学习是如何帮助携程机票客服提高对话效率的-InfoQ