基于Elasticsearch检索型智能问答机器人实现方案(详细)

一、设计方案

最近项目需要在做一个客服问答系统,里面涉及到了大量的问题搜索。

1.1 系统功能

在特定的垂直业务领域下,问答系统可以回答用户所提出的一系列问题,其主要功能包括问句预处理、问句理解、问句相识度匹配和标签分类。

1)问句预处理:将用户问句进行分词和词性标注

2)问句理解:提取问句中的关键词

3)问句相似度匹配:将问句与每个标签分类下的问题进行相似度计算后召回

4)标签分类:为问句添加标签,在标签分类下的问题匹配相似问题,以此来提升机器理解能力和匹配精度,同时也可以对问答对进行分类化管理,可以按业务分类、问题所属分类等自己需要的维度来管理问答对,提高问答对的管理效率。标签分类根据实际业务场景需求进行分类,切记标注标签分类的时候需要保持数据的一致性

1.2 问答型机器人处理流程:

1.3 整体产品结构图

以下是问答系统整体产品结构图,主要围绕核心模块有问答管理、关键词管理、未知问题管理。则其余模块不会做详细讲解。

按照传统的mysql去完成,虽然可以很容易地实现,但是性能方面却很力不从心,要知道mysql对like查询支持不好,如果数据量一大,很容易造成全表扫描,十分影响用户体验。

采用redis远程字典式缓存服务,将部分热点数据进行缓存,能够快速响应用户对热点内容读取的需求,另外点赞收藏等易变化的部分数据不立即存入数据库,而是通过缓存操作加定时任务,实现弱一致性的数据存取也可实现。

但是作为主业务通过最短的对话轮次(一问一答),获得精准、直接的答案以及更好地完成任务,来满足用户的需求。我们参考百度,京东,谷歌最终选择,elasticsearch搜索引擎解决这个问题。

1.4 技术选型

最终技术选型问答系统使用Python elasticsearch PythonIA(统一管理API)实现题库检索。前后端分离,题库分类,标签,权限管理等我们使用JAVA MySql实现业务的统一管理。页面展示使用VUE uni-app实现!

二、Elasticsearch介绍

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。

特点:

分布式,无需人工搭建集群(solr就需要人为配置,使用Zookeeper作为注册中心)

Restful风格,一切API都遵循Rest原则,容易上手

近实时搜索,数据更新在Elasticsearch中几乎是完全同步的。

搜索引擎按照功能通常分为垂直搜索和综合搜索,使用倒排索引。

以我的理解就是:我们对数据库原始的数据根据字或词进行索引,创建倒排索引数据区域,记录字或词在文档中出现位置(id列表)。用户在查询需求时,先访问倒排索引数据区域,得出文档id列表后,通过文档id即可快速,准确找到具体的文档内容。

Near Realtime(NRT):近实时,两个意思,从写入数据到数据可以被搜索到有一个小延迟(大概1秒);基于es执行搜索和分析可以达到秒级

Cluster:集群,包含多个节点,每个节点属于哪个集群是通过一个配置(集群名称,默认是elasticsearch)来决定的,对于中小型应用来说,刚开始一个集群就一个节点很正常

Node:节点,集群中的一个节点,节点也有一个名称(默认是随机分配的),节点名称很重要(在执行运维管理操作的时候),默认节点会去加入一个名称为'elasticsearch'的集群,如果直接启动一堆节点,那么它们会自动组成一个elasticsearch集群,当然一个节点也可以组成一个elasticsearch集群

Document&field:文档,es中的最小数据单元,一个document可以是一条客户数据,一条商品分类数据,一条订单数据,通常用JSON数据结构表示,每个index下的type中,都可以去存储多个document。一个document里面有多个field,每个field就是一个数据字段。

Index:索引,包含一堆有相似结构的文档数据,比如可以有一个客户索引,商品分类索引,订单索引,索引有一个名称。一个index包含很多document,一个index就代表了一类相同的document。比如说建立一个product index,商品索引,里面可能就存放了所有的商品数据,所有的商品document。

Type:类型,每个索引里都可以有一个或多个type(6.0之后只有一个type默认为_doc),type是index中的一个逻辑数据分类,一个type下的document,都有相同的field,比如博客系统,有一个索引,可以定义用户数据type,博客数据type,评论数据type。

shard分片:单台机器无法存储大量数据,es可以将一个索引中的数据切分为多个shard,分布在多台服务器上存储。有了shard就可以横向扩展,存储更多数据,让搜索和分析等操作分布到多台服务器上去执行,提升吞吐量和性能。每个shard都是一个lucene index。

replica分片:任何一个服务器随时可能故障或宕机,此时shard可能就会丢失,因此可以为每个shard创建多个replica副本。replica可以在shard故障时提供备用服务,保证数据不丢失,多个replica还可以提升搜索操作的吞吐量和性能。primary shard(建立索引时一次设置,不能修改,默认5个),replica shard(随时修改数量,默认1个),默认每个索引10个shard,5个primary shard,5个replica shard,最小的高可用配置,是2台服务器。

三、Elasticsearch常用查询

filter:过滤,不参与打分

must:如果有多个条件,这些条件都必须满足 and与

should:如果有多个条件,满足一个或多个即可 or或

must_not:和must相反,必须都不满足条件才可以匹配到 !非发生 描述

must该条款(查询)必须出现在匹配的文件,并将有助于得分。

filter子句(查询)必须出现在匹配的文档中。然而不像 must查询的分数将被忽略。Filter子句在过滤器上下文中执行,这意味着评分被忽略,子句被考虑用于高速缓存。

should子句(查询)应该出现在匹配的文档中。如果 bool查询位于查询上下文中并且具有mustor filter子句,则bool即使没有should查询匹配,文档也将匹配该查询 。在这种情况下,这些条款仅用于影响分数。如果bool查询是过滤器上下文 或者两者都不存在,must或者filter至少有一个should查询必须与文档相匹配才能与bool查询匹配。这种行为可以通过设置minimum_should_match参数来显式控制 。

must_not子句(查询)不能出现在匹配的文档中。子句在过滤器上下文中执行,意味着评分被忽略,子句被考虑用于高速缓存。因为计分被忽略,0所有文件的分数被返回。

四、Elasticsearch结合Python使用

创建

下面创建模板,该模板匹配类的全部索引,匹配到此模板的索引,用动态模板把所有字符串映射成text和keyword类型并使用ik_smart分词

{

'index_patterns': ['article*'], //匹配索引的,数组的形式,证明可以多个

'settings': { //基本设置

'number_of_shards': 1, //主分片数

'number_of_replicas': 0 //备份数

},

'mappings': { //映射

'_doc': { //这个其实就是es的type,在es6.*的版本中,一个index只能存储一种type(7的版本会删除type),所以写成_doc(文档),你可以自己随便定义,反正最终展现形式就是type

'_source': { 'enabled': true }, //是否存储所有源数据,建议设置成true,如果只需要设置部分数据,可以在具体字段中使用store

'dynamic_date_formats': ['yyyy-MM-dd HH:mm:ss','yyyy-MM-dd', 'yyyy/MM/dd'], //只有满足设定条件的字段会映射成date类型,不过多个类型只会存在一种,也就是第一次插入的是yyyy-MM-dd这种格式,后面也就必须全是这种格式,所以建议这个设置一个就好

'properties': { //具体设置字段

'created_at': { 'type': 'date' }, //将created_at字段设置成date类型

'updated_at': { 'type': 'date' } //将updated_at字段设置成date类型

},

'dynamic_templates': [ //动态模板设置,前面properties中默认只设置了两个字段,如果新添加没有设置的字段,es默认会自己完成映射,但是你需要自己来设置这些映射规则没救要使用动态模板.下面一整段的意思就是把字符串映射成自定义的规则

{ 'strings':

{

'match_mapping_type': 'string', //匹配本来es要映射成字符串的字段

'mapping':{

'type': '', //匹配的字段映射成text类型

'analyzer': '', //使用ik_smart分词

'fields': {

'keyword': {

'type': 'keyword', //同时映射keyword类型

'ignore_above': 256 //忽略超过256字节的字段

} } } } } ] } }}

初始化创建索引以及字段类型

创建索引数据

删除索引

查询数据

五、实现效果

知识库管理界面

数据分析界面

pc端问答界面

移动端问答界面

六、总结

本项目是综合多种技术Elasticsearch、python、java等实现的一个检索型的问答系统,离真正智能AI问答系统还有一定差距,下一步会在国内AI框架(百度飞桨paddlepaddle)上继续探索智能问答自然语言处理(尤其语义理解和分析),有兴趣的一块加入吧!

最后感谢团队所有成员!尤其是hz同学!!

(0)

相关推荐