软件开发架构师

使用 Intel Analytics Zoo 在客户服务平台中引入 AI

人工智能 30 2019-06-07 02:24

本文要点

  • 现在,很多客户支持平台都配备了人工智能,大大节省了人力,提高了用户体验。
  • 历史会话数据会随着时间的推移而增加。将这些数据放到 Apache Hadoop 集群中是一个可扩展的数据管理和共享解决方案。
  • Analytics Zoo 是一个面向 Apache Spark 上分布式 TensorFlow、Keras 和 BigDL 的统一分析 + AI 平台,由英特尔开源。
  • Analytics Zoo 为从集群中读取和预处理文本数据提供了丰富的支持。用户可以轻松地使用内置模型以分布式方式执行自然语言处理任务。
  • 本文将逐步演示如何使用 Analytics Zoo 构建端到端的 QA 排名应用程序。该解决方案已被 Microsoft Azure 成功地用于服务其客户。

本系列文章讨论了微软 Azure 中国团队在 Azure 上使用Intel Analytics Zoo构建人工智能客户支持平台的实践。

上一篇文章中,我们详细介绍了构建文本分类模块以更有效地处理客户请求的成功经验。在接下来的文章中,我们将继续介绍我们的客户服务平台中的另一个重要 AI 模块——QA 排名,它用于对 QA 模块中的大量候选项进行排序,并选出最佳答案。

下图展示了客户支持平台的总体架构,并以橙色突出显示了问答(QA)组件。上一篇文章介绍了更多关于客户支持平台背景和架构的信息。

使用 Intel Analytics Zoo 在客户服务平台中引入 AI-1

我们有很多 Azure 中国客户不断寻求帮助来解决他们遇到的技术问题(用中文描述),他们经常希望得到及时的支持。因此,我们打算设计一个 QA 模块,目的是为客户的问题提供尽可能多的准确答案(也是用中文),同时尽可能地减少人的干预。在我们最初的实现中,我们根据预先定义的对话流以及基于信息检索的文档搜索、索引和权重为用户提供答案。

遗憾的是,当我们开始处理这个问题时,QA 模块返回的结果不是很令人满意。如果客户的问题属于预定义的对话流,那么提供的答案可能很有用。然而,在大多数情况下,预定义的对话流不能捕获客户提出的问题,所提供的答案也不是用户所期望的。

为了改善结果以获得更好的用户体验,我们决定尝试使用 AI 技术来帮助完成这项任务。利用 NLP 技术和深度学习相结合的方法是一个自然的选择。随着数据的累积,它们可以增量训练和演进。我们决定添加一个深度学习 QA 排名模块,从搜索引擎提供的候选答案中选择最佳答案。

针对我们的场景,我们采用了 Analytics Zoo 提供的内置文本匹配模型,并将其集成到我们的服务平台中。通过新添加的 QA 排名模块,根据基准测试结果和客户反馈,我们已经看到了显著的性能改进。在本文剩下的部分中,我们将与你分享在 Intel Analytics Zoo 中添加 QA 排名模块的一般步骤和实践经验。

为什么选择 Analytics Zoo?

Analytics Zoo是一个开源的统一分析 + 人工智能平台,由英特尔开发,用于 Apache Spark 上的分布式 TensorFlow、Keras 和 BigDL。该平台提供了非常丰富的功能支持,包括高级管道 API、预定义模型、公共数据集上的预训练模型、参考用例等。我们之前使用 Analytics Zoo 成功集成了文本分类器模块,因此我们认为,Analytics Zoo 是我们以及其他 Azure 大数据用户在 Azure 上构建端到端深度学习应用的一个很好的选择。有关 Analytics Zoo 的更详细介绍,可以参考本文

什么是问答(QA)排名?

问答(QA)是一种常见的自然语言处理任务,它试图用自然语言自动回答人类提出的问题。在我们的场景中,我们的客户支持平台有一个 FAQ 文本和文档文章的集合,可以作为回答语料库使用,它试图从这些语料库中为用户的每个问题找到最佳的相关答案。这样的问题可以看作是一个文本匹配问题,我们可以创建一个模型来预测一个问题和候选列表中每个候选答案的相关度,然后对候选答案进行排序,并将得分最高的答案返回给客户。

与文本分类类似,文本匹配模型的训练也包括数据收集、训练和验证数据集的准备、数据清理和预处理,然后是模型训练、验证和调优。Analytics Zoo 为我们提供了一个内置的文本匹配模型和PythonScala语言的参考示例。有关文本匹配 API 和功能的更详细文档,参见此处

数据收集和预处理

我们维护了一个整洁有序的候选答案和文章(均为中文)集合,每一项都有一个不同的 ID。我们有一个从不同来源收集的用户问题的集合(也是中文),每个问题也分配了不同的 ID。然后,我们让人标记出每个问题的最佳匹配答案。我们使用这些数据来训练用于 QA 排名的文本匹配模型。

问答语料库示例如下:

使用 Intel Analytics Zoo 在客户服务平台中引入 AI-2

备注:实际内容为中文。原文作者把它们翻译成了英语。

对于数据加载,首先我们使用 Analytics Zoo 中的TextSet API 把 CSV 格式的问答语料库加载到一个基于 TextSet 的、文本的弹性分布式数据集(RDD)中,用于如下分布式预处理:

复制代码
1. from zoo.common.nncontext import init_nncontext
2. from zoo.feature.text import TextSet
3.
4. sc = init _nncontext()
5. q_set = TextSet.read _csv("question_corpus.csv", sc, partition_num)
6. a_set = TextSet.read _csv("answer_corpus.csv", sc, partition_num)

接下来,我们需要准备关系文件,表明问题答案对之间的相关性。一对标记为 1(正)或 0(负)的问答表示答案是否与问题匹配。由于原始的标签数据只有正标签,我们通过对每个问题的所有非匹配答案随机抽样,生成一个负样本集合。

我们为训练、验证和测试分别构建了手动和半自动的关系文件。每个关系记录包含一个问题 ID、一个答案 ID 和一个标签(0/1)。关系示例如下所示:

使用 Intel Analytics Zoo 在客户服务平台中引入 AI-3

CSV 格式的关系也可以使用以下 API 轻松读取为 RDD:

复制代码
1. from zoo.feature.common import Relations
2.
3. train_relations = Relations.read( "relation_train.csv", sc, partition_num)
4. validate_relations = Relations.read( "relation_validate.csv", sc, partition_num)

下面的预处理步骤与我们在文本分类器模块中所做的非常相似。每个输入都需要经过符号化、从单词到索引的转换和序列对齐。有关详细信息,你可以参考前一篇文章中相应的部分。

Analytics Zoo 中的 TextSet 提供了内置的操作,帮助我们非常方便地构建预处理管道。Analytics Zoo 提供的原始实现只能处理英语。由于我们的数据是中文的,所以我们进行了修改,并利用jieba及自定义的标记将中文句子分成单词。代码的预处理部分是这样的 :

复制代码
1. transformed_q_ set = a_ set.tokenize () .word2idx () .shape_sequence (q_len)
2. transformed_a_ set = q_ set.tokenize () .word2idx (existing_map=q_set.get_word_index()) \
3. .shape_sequence (a_len)
4. word_index = transformed_a_ set.get_word_index ()

在内部,上述过程首先对问题语料库进行预处理。然后对答案语料库进行类似的预处理,不过是将新单词添加到从问题语料库获得的单词索引图中,使两个语料库共享相同的单词索引。上面的操作基于 RDD,因此可以很容易地扩展并以分布式方式在大型问答数据集上执行。

模型定义和构造

对于文本匹配模型,我们使用 Analytics Zoo 中内置的K-NRM模型,该模型利用内核池技术来有效地获取排名。下面是 K-NRM 模型的架构:

使用 Intel Analytics Zoo 在客户服务平台中引入 AI-4

输入查询和文档将首先经过一个共享嵌入层,该层通常使用预先训练的词嵌入向量作为其初始权重。随后的点层生成翻译矩阵,其中每个条目表示查询和文档中每个单词之间的相似性。RBF 内核用于提取多级软匹配特征,然后是一个“学习排名(learning-to-rank)”层,它将这些软 TF 特征组合成最终的排名得分。有关详细信息,可以参考“带有内核池的端到端神经即时排名”一文。

K-NRM 模型可以使用以下开箱即用的 API 进行构建:

复制代码
1. knrm = KNRM(text1_length, text2_length, embedding_file, word_index=None,
2. train_embed= True, kernel_num=21, sigma=0.1, exact_sigma=0.001,
3. target_mode= "ranking")

该模型的输入是问题索引序列以及答案索引,输出是它们之间的相关性分值。用户需要分别指定问题和答案的长度 q_len 和 a_len。注意,对于词嵌入,该模型支持用于英语单词预训练的GloVe。同样,由于我们处理的是中文,所以我们选择并修改FastText作为中文词嵌入。参数 word_index 只是上面介绍的答案语料库 TextSet 生成的单词及其 ID 的映射。

是否对嵌入层进行训练是可配置的,实验结果表明,根据内核池的结果对词嵌入向量进行微调,可以获得更好的性能。你还可以指定使用多少内核和内核宽度。实际上,默认参数对于我们的数据集来说已经足够好了。

这实际上是一个多用途模型,它的 target_mode 可以是“ranking”或“classification”。你可以查看这个文档了解更多细节。

模型训练、评估和优化

现在,我们有了开始训练所需的所有要素。训练和验证关系、经过预处理的问答语料库 TextSet,这些是我们训练文本匹配模型所必须的。

该模型可以按照上面介绍的两种 target_mode 值以两种方式进行训练。一种是将每个关系记录单独训练,作为一个二元分类问题,输出将是问题与答案相关的概率。另一种方法是联合训练一对记录,每对记录由同一问题的正关系(标签为 1 的关系)和负关系(标签为 0 的关系)组成,并优化两者之间的间隔。我们已经尝试了两种方法,并发现后者的表现更好。

Pairwise 训练是以相同问题的一对关系作为输入。每对关系包含一个标签为 1 的关系和一个标签为 0 的关系。因此,在这种情况下,我们在 K-NRM 模型外封装了一个 TimeDistributed 封装器:

复制代码
1. from zoo .pipeline .api .keras .models import Sequential
2. from zoo .pipeline .api .keras .layers import TimeDistributed
3.
4. model = Sequential().add(TimeDistributed(knrm, input_shape=( 2, q_len + a_len)))

Analytics Zoo 还提供了一个 API,可以直接生成给定关系和预处理语料库的所有关系对,这些关系对的结果可以直接输入到模型中。

复制代码
1. train_set = TextSet.from _relation_pairs(train_relations, q_set, a_set)

然后,我们使用便捷的 Keras-Style API 来编译和训练 K-NRM 模型。有一个损失函数 RankHinge 是专门为 Pairwise 训练提供的。损失函数hinge用于最大间隔分类,RankHinge 是其方差,其目的是使正样本与负样本之间的间隔最大化。

复制代码
1. model.compile( optimizer=SGD(learning_rate), loss= "rank_hinge")
2. model.fit(train_set, batch_size, nb_epoch)

可调参数包括周期数、批大小、学习率等。用户还可以在训练期间获取快照,然后从快照中恢复训练。

排名模型的评价与训练有一点不同。基本上,对于每一个验证问题,我们都会准备一个正确的答案和一些错误的答案。我们想根据输出分数按降序排列所有候选答案。标签为 1 的得分越高越好。NDCGMAP是评估排序任务的常用指标。Listwise 评估的示例代码如下:

复制代码
1. validate_set = TextSet.from _relation_lists(validate_relations, q_set, a_set)
2.
3. knrm.evaluate _ndcg(validate_set, k=3)
4. knrm.evaluate _map(validate_set)

你可以从日志控制台找到计算结果。NDCG 和 MAP 都会给出 0 到 1 之间的值。如果指标接近 1,那么最相关的答案应该排在第一位。你还可以在训练期间保存即时结果,并使用 Tensorboard 可视化损失曲线。如果度量指标相对较低,或者模型没有如预期的那样收敛,这表明模型性能不够好,我们必须对模型进行调优。这通常是一个反复检查数据质量、选择合适的训练超参数或调整模型参数的过程,直到得到满意的结果,然后训练好的模型就可以投入生产。

模型服务及发布

这部分与我们在前一篇文章中详细说明的文本分类器模块中所做的工作非常相似。我们在我们的服务中使用了类似 POJO的 Java 推理 API(更多细节参见这里)。由于 QA 排名中每个问答的预处理与文本分类器基本相同,所以这两个模块共享这部分的代码,这样便于维护。Analytics Zoo 还提供了 Web 服务示例(包括文本分类推荐)供我们参考。

随着我们不断收集用户反馈,我们会有越来越多的关系,我们会定期重新训练和发布更新后的排名模型。

小结

本文到这里就结束了。总结一下,本文演示了我们使用 Intel Analytics Zoo 在 Azure 大数据平台上成功构建 QA 排名模块的过程。你可以遵循我们上面的步骤,并参考 Analytics Zoo 提供的指南和示例,将其添加到你自己的应用程序或服务中!在本系列的后续文章中,我们将继续介绍在构建客户支持平台方面的更多实践经验。

要了解更多信息,请访问 Github 上Analytics Zoo 的项目主页,你也可以下载并尝试在 Azure 市场上预安装 Analytics Zoo 和 BigDL 镜像

作者简介

Chen Xu,微软高级软件工程师。他负责 Mooncake Support Chatbot AI 组件的设计和开发。
Yuqing Wei ,微软软件工程师,专注于大数据平台及相关技术。她致力于 Mooncake Support Chatbot AI 的开发。
Shengsheng (Shane) Huang ,英特尔高级软件架构师,Apache Spark 提交者和 PMC 成员。她有 10 多年的大数据经验,目前在 Apache Spark 上的分布式深度学习基础设施和应用程序开发方面担任领导角色。
Kai Huang是英特尔公司的一名软件工程师。他的工作主要是在 Apache Spark 上开发深度学习框架,帮助客户在大数据平台上制定端到端的深度学习解决方案。

查看英文原文Using Intel Analytics Zoo to Inject AI Into Customer Service Platform (Part II)

文章评论