搭建一个FAQ智能问答系统/服务

news2024/11/8 14:21:08

FAQ智能问答系统

介绍

项目传送门:https://github.com/wzzzd/FAQ_system
构建了一个FAQ智能问答系统。
使用多种方法,实现FAQ的问题-模板匹配功能。
使用Tornado框架,部署成轻量级的Web服务应用。
整体框架如下。
在这里插入图片描述

流程

  • 1.初始化流程
1.读取QA数据集
2.创建Elasticsearch的index索引
3.将QA语料导入Elasticsearch
  • 2.查询流程
输入query文本 -> 分词 -> 召回(ES) -> 粗序(PreRank) -> 精排(Rank) -> result

方法

1. 召回

  • 目的:尽可能多地召回与query相关的问题
  • 使用jieba分词
  • 基于分词,获取Elasticsearch中相关的问题模板候选集

2. 排序

  • 目的:使用基于字符或向量的方法,召回结果进行排序,用比较快的速度完成初筛,减少精排的数据量。
  • BM25
    • 基于BM25的思路,计算query与候选数据集之间的得分,作为排序分数。
  • N-gram
    • 使用2-gram3-gram4-gram提取词片段,再使用jaccard计算相似度,作为排序分数。
  • Word2Vec
    • 提供了两种获取词向量的方法:
      • (1) 使用本项目的QA数据集作为语料,基于gensim框架训练得到的word2vec模型。
      • (2) 使用腾讯AI Lab开源的词向量Embedding。需要将文件放置在目录file/model/下。项目默认使用【Original size: 1.8G; tar.gz size: 763M】的词向量,若使用其他词向量文件,需要修改Config.py下的path_w2v_tx变量值。
    • 计算词向量之间的相似度,作为排序分数。

3. 精排

  • 目的:基于无监督或有监督的方法,对粗排结果进行再排序。

3.1 基于无监督方法

  • Language Model
    • 使用开源预训练模型,原因是模型较小,消耗资源少。
    • 基于框架sentence-transformers,Base model为MiniLM,使用的模型参数为all-MiniLM-L12-v2。
  • SimCSE
    • 为了利用垂直领域的业务数据,基于指定语料,使用无监督的方法训练语言模型。
    • 使用SimCSE的无监督训练方法,使用本项目中的FAQ数据集进行训练。
    • 说明:基于Bert,使用对比学习的方法,来fine-tune模型。原理是,在超球面上,拉近语义层面相似的句子,同时尽可能地使语义不相似的句子相互远离。

3.2 基于监督方法

  • Bert
    • 垂直领域使用有监督的方法(分类模型的思路),训练一个排序模型,提升精排的准确率。
    • 可参考本人另一个项目text_classifier_pytorch
    • 训练语料使用句子对的形式,学习目标是两个句子相似与否,即分类任务。
给出句子
sentence1: 车子不小心刮花了,保险流程怎么办?
sentence2: 不小心刮花车子了,怎么走保险流程?
label: 1(语义相同)

转化为
input: 车子不小心刮花了,保险流程怎么办?[SEP]不小心刮花车子了,怎么走保险流程?
label: 1

数据集

1.保险行业语料

  • 来自项目baoxianzhidao_filter
  • 根据is_best=1筛选出回答正确的数据,获取其中的titlereply字段,处理成两个数据集,位于目录data/insurance_zhidao_test/
    • corpus.txt: 语料库,包含questionanswer两个字段。
      • question:与原始文件的title字段对应
      • answer:与原始文件的reply对应。
    • test.txt : 测试数据,包含queryquestion两个字段。
      • question:根据question字段使用回译的方法(中->英->中),获取语义相同但表述不同的句子。
      • answer:表示原始问题的标准答案。

2.自定义语料

  • 可按照上述数据集的格式,使用自定义的数据。注意,需要包含两个文件corpus.txttest.txt

环境说明

本项目基于python==3.8实现。
若安装了anaconda,建议创建一套虚拟环境,再安装环境依赖

$ conda create -n your_env_name python=3.8   # 创建虚拟环境
$ conda activate your_env_name               # 激活环境
$ pip install -r requirements.txt            # 安装依赖

若无安装anaconda,直接安装依赖

$ pip install -r requirements.txt

另外,为了在语料较大的情况下,减少召回模块消耗的时间,本项目使用Elasticsearch分布式搜索引擎来存储所有的语料。使用版本为(7-10-2)。

按照完毕后,启动ES服务

cd /your_path/elasticsearch-7.10.2/bin;
./elasticsearch -d;

效果

1.示例

在模型配置,粗排方法为bm25,精排方法为有监督的bert方法下,部分效果如下:

Query:重疾险有年龄限制吗?

PreRank:

  • question:商业养老保险是否有投保年龄限制 - score:12.33
  • question:康惠保重疾险是所有人都可以买吗?对年龄有什么限制? - score:9.42
  • question:重疾险对购买人年龄有没有要求? - score:9.01
  • question:多大年龄开始购买重疾险比较好? - score:9.01
  • question:哆啦A保对年龄有没有限制,10岁的小女孩可以买吗 - score:7.74
  • question:交强险有报案时间限制吗 - score:7.38
  • question:生育险报销有时间限制吗 - score:7.00
  • question:生育险到账有时间限制去取吗 - score:6.66
  • question:有商业保险可年龄大可以贷款吗 - score:6.51
  • question:16周岁的孩子买人身保险有什么限制吗 - score:6.07

Rank:

  • question:重疾险对购买人年龄有没有要求? - score:0.98
  • question:有年交2000块的重疾险吗 - score:0.94
  • question:康惠保重疾险是所有人都可以买吗?对年龄有什么限制? - score:0.76
  • question:多大年龄开始购买重疾险比较好? - score:0.69
  • question:缴费年限是什么? - score:0.53
  • question:重大疾病保险有必要买吗? - score:0.52
  • question:重疾险有多少种疾病 - score:0.50

2.指标

在100个样本的测试集中,分别统计top1、top3、top10的召回结果准确率。

粗排模型精排模型Top1 AccTop3 AccTop10 Acc
bm25-0.770.860.92
ngram-0.520.690.84
word2vec(tencent)-0.760.830.88
bm25lm-mini(Unsup)0.450.540.64
bm25simcse-bert(Unsup)0.920.980.99
bm25bert(sup)0.991.01.0

使用方式

1.配置文件

根目录下的Config.py文件,是配置文件。可自行修改相关的参数:

  • es_ip:ES搜索引擎的地址,默认是部署在同一台设备环境里,如果ES是部署在其他服务器,那么需要改成其他服务器的地址。
  • es_index:表示语料存储在ES中的index名字。
  • model_name:表示排序的方法,分别包含bm25/ngram/word2vec/word2vec-tx
  • dataset:表示数据集的名称,对应目录./data/下的数据文件夹名。
  • use_rank:是否使用精排模块。True开启,False关闭。
  • use_supervise:精排模块使用有监督方法,还是无监督方法。True为监督方法,False为无监督方法。
  • unsup_rank_name:表示无监督精排中,使用的模型类型,可选:simcse-distilbert/simcse-bert/lm-mini
  • sup_rank_name:表示监督方法精排中,使用的模型类型,可选:distilbert/bert

2.项目初始化

考虑到性能问题,原始的数据会被存储到Elasticsearch。
在开始以下Demo之前,需要将加工数据,并存储到ES。

$ python insert_data_to_es.py

3.训练有监督的排序模型(可选)

若配置文件config.py中,字段use_supervise=True,则表示在rank阶段,使用有监督的方法来实现。
那么就需要提前训练好一个rank模型。
本项目提供了已经处理好的保险行业rank数据集,可参考

└── data
     └── insurance_zhidao_rank
          ├── train.txt
          ├── dev.txt
          └── test.txt

模型方面,选了本人另一个项目text_classifier_pytorch中的bert模型来完成排序任务。
可直接将本数据集,替换掉该项目的数据集,再进行训练,即可得到排序模型。

若想直接使用本数据集训练的模型参数,可直接下载模型文件rank-bert,密码:khpb。并将下载的所有文件(非文件夹)放在目录file/supervise/bert/下。

4.训练无监督的语义表征模型SimCSE(可选)

若配置文件config.py中,字段use_supervise=False,则表示在rank阶段,使用有无监督的方法来实现。字段unsup_rank_name=simcse-bert时,表示使用SimCSE训练的预训练模型来进行句子语义提取。

具体的无监督SimCSE模型及训练,可参考论文源码SimCSE。

本项目提供了已经处理好的保险行业的无监督训练数据集,可参考data/insurance_zhidao_unsup/corpus.txt

若想直接使用本数据集训练的模型参数,可直接下载模型文件simcse-bert,密码:65av。并将下载的所有文件(非文件夹)放在目录file/unsupervise/simcse_bert/下。

5.FAQ问答

直接测试FAQ效果

$ python FAQ.py

6.部署FAQ问答服务

可以将FAQ部署成一个Web服务。

Step1:启动FAQ问答Web服务。

$ python service.py

Step2:以http的方式访问FAQ问答Web服务。

可在linux shell命令行下,发送http请求,其中参数说明

  • data 里面包含了两个参数
  • question 表示输入的问题
  • size 表示返回的结果数量,返回结果不一定与输入的size值一致,但是返回结果长度会小于或等于size值。
$ curl --request POST \
  --url http://localhost:5000/api/v1/faq/ \
  --header 'content-type: application/json' \
  --data '{"question": "什么是综保保险?","size": 3}'

结果会按照相似得分倒序排序,服务会返回类似以下的结果格式:

{
    "status": 200,
    "answer": [
        {
            "question": "综保是什么保险",
            "answer": "综合保险是为了维护外来从业人员的合法权益,规范单位用工行为,维护劳动力市场秩序。综合保险包括工伤(或者意外伤害)、住院医疗和老年补贴等三项保险待遇。外来从业人员在参加综合保险期间发生工伤事故或患职业病的,可以得到一次性支付的工伤保险金...",
            "score": "0.98"
        },
        {
            "question": "什么是万能型保险?",
            "answer": "万能型保险是指包含保险保障功能并至少在一个投资账户拥有一定资产价值的人身保险产品。万能型保险除了同传统寿险一样给予保护生命保障外,还可以让客户直接参与由保险公司为投保人建立的投资帐户内资金的投资活动,将保单的价值与保险公司独立运作的投保人投资帐户资金的业绩联系起来...",
            "score": "0.97"
        },
        {
            "question": "保险到底是什么?",
            "answer": "保险是指投保人根据合同约定,向保险人支付保险费,保险人对于合同约定的可能发生的事故因其发生所造成的财产损失承担赔偿保险金责任,或者被保险人死亡、伤残、疾病或者达到合同约定的年龄、期限等条件时承担给付保险金责任的商业保险行为...",
            "score": "0.96"
        }
    ]
}

说明

  • 此服务部署方式只支持同一台设备的网络访问。
  • 若想通过其他设备来访问此Web服务,需要额外配置对外开放相关端口,或者接入流量转发器(如nginx)进行请求的转发。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/185546.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

这福利给你要不要 — 用Python采集相亲网站女生数据

前言 俗话说学咱这行的男同志 找对象容易吗 这马上就要过完年了 是时候找找女朋友了 我在这里摸索到了个网站 或许你们可以来看看 送一波单身福利 不需要的也可以学学怎么采集这些数据呗 环境与模块 环境开发 Python 3.8Pycharm 模块使用 import parsel --> p…

类与对象的原理

前言 在JavaScript中,类的实现是基于原型继承机制的。 JavaScript中的类的一个重要特性是“动态可继承”。 类与原型 在JavaScript中,类的所有实例对象都从同一个原型对象上继承属性,因此原型对象是类的核心。 所有的类都有一个共同的根…

关系数据库——关系操作和关系完整性

文章目录一、关系操作1.基本的关系操作2.关系数据语言的分类关系代数语言关系演算语言具有关系代数和关系演算双重特点的语言二、关系的完整性1.实体完整性(Entity Integrity)实体完整性规则2.参照完整性(Referential Integrity)参照完整性规则引用关系3.用户定义的完整性(User…

WebRTC 的连接过程

经过前面几部分的铺垫,你应该对P2P音视频互动的过程有了一个大概的了解,有可能你会觉得过程比较繁琐,甚至涉及到了网络底层。但是,不要担心,WebRTC已经帮我们做了很多的事情,让我们在音视频开发时变得轻而易…

【Spring源码】22. 属性填充populateBean()详解

进入populateBean()对bean的属性进行填充,将各个属性值注入(存在其他bean的属性,则会递归初始化依赖的bean)一开始会先对传入的参数进行判断(如下图红框框中的逻辑)如果传入的BeanWrapper和RootBeanDefinit…

SpringBoot3+最新MybatisPlus+Mysql与TDengine双数据源

前言 昨天写的ideaApifox uploader插件apifox新年第一天上班就上榜了,真是不错。今天来补一篇,本来应该是在前一篇之前发的。实际上就是最新的springBoot集成最新的mybatisPlus,加双数据源:mysql、TDengine,一个关系型…

kvm虚拟机克隆

kvm虚拟机克隆链接克隆和完整克隆的区别完整克隆自动克隆手动克隆的步骤1.复制模板vm磁盘为新vm的磁盘2.复制模板vm配置文件为新vm的配置文件3.修改新vm配置文件中的信息为新vm的信息4.导入新vm的配置文件5.启动新vm链接克隆1.生成链接克隆虚拟机磁盘文件2.后续流程与手动克隆一…

【算法练习】链表中环的入口结点

题源&#xff1a;牛客描述给一个长度为n链表&#xff0c;若其中包含环&#xff0c;请找出该链表的环的入口结点&#xff0c;否则&#xff0c;返回null。数据范围&#xff1a;n≤10000&#xff0c;1<结点值<10000要求&#xff1a;空间复杂度 O(1)&#xff0c;时间复杂度O(…

1、数据库概述

文章目录1 为什么要使用数据库2 数据库与数据库管理系统2.1 数据库的相关概念2.2 数据库与数据库管理系统的关系2.3 常见的数据库管理系统排名(DBMS)2.4 常见的数据库介绍3 MySQL介绍3.1 概述3.2 MySQL发展史重大事件3.3 关于MySQL 8.03.4 为什么选择MySQL3.5 Oracle vs MySQL4…

学成在线项目开发技巧整理---第二部分

1.静态资源处理通常项目会采用动静分离架构,利用Nginx作为静态资源服务器,存放所有静态资源:#访问动态资源时,将请求负载均衡到多个服务器实例或者多个网关实例 upstream webservice{server 192.168.200.146:8080; }server {listen 80;server_name localhost;#动态资源l…

C++基础知识点整理笔记(一)

一直想尝试自己动手构建一个简单的深度学习训练框架&#xff0c;包括数据读取与处理、PS、NN前后向传播、模型save和load、不同训练方式&#xff08;offline/online .etc&#xff09;、指标监控、模型部署等部分, 去深入研究内部深度学习训练框架及horovod、byteps、pslite、te…

深刻理解状态机设计需要避免的冒险;时序电路可能存在essential hazard;处理单元里的control和datapath;竞争冒险【SV】【VLSI】

深刻理解状态机设计需要避免的冒险&#xff1b;时序电路可能存在essential hazard&#xff1b;处理单元里的control和datapath&#xff1b;竞争冒险【SV】【VLSI】0. 前言&#xff1a;时序电路可能存在essential hazard1. 理解control和datapath1.1 Datapath control2. 硬件电路…

MFC|创建一个对话框及窗体各个属性介绍

参考&#xff1a; VS2015 建立一个C的MFC简易窗体程序项目&#xff08;https://www.cnblogs.com/xingboy/p/11059721.html&#xff09; 对话框中各项属性介绍&#xff08;https://blog.csdn.net/u012350993/article/details/26093051&#xff09; MFC窗口风格 WS_style/WS_EX_s…

【Hadoop】YARN简述

文章目录1. YARN总述2. YARN调度器2.1 FIFO Scheduler2.2 Capacity Scheduler2.3 Fair Scheduler1. YARN总述 YARN是Hadoop资源管理器&#xff0c;它是一个通用资源管理系统&#xff0c;可为上层应用提供统一的资源管理和调度&#xff0c;它的引入为集群在利用率、资源统一管理…

关于栈和队列

目录栈&#xff08;Stack&#xff09;什么是栈栈的使用栈的模拟实现队列&#xff08;Queue&#xff09;什么是队列队列的使用队列的模拟实现循环队列双端队列 (Deque)栈&#xff08;Stack&#xff09; 什么是栈 栈是一种特殊的线性表&#xff0c;它只允许在固定的一端进行插入…

JavaScriptArray和String对象~

初识Array&#xff1a; 定义&#xff1a; 方式1 var 变量名new Array(元素列表);举例&#xff1a; <script>var arraynew Array(1,2,3);alert(array); </script>显示如下&#xff1a; 方式2 var 变量名[元素列表];举例&#xff1a; <script>var array[…

App Inspector使用 (macaca移动端元素检查器)

App Inspector安装说明&#xff1a;https://macacajs.github.io/app-inspector/zh/guide/install.html#%E7%8E%AF%E5%A2%83%E9%9C%80%E8%A6%81 依赖安装说明&#xff1a; 1、node环境&#xff1a;这里安装的时候和初始化的时候报错使用了两个版本&#xff0c;所以这里使用nvm…

Python-模块、包和发布模块

1.模块1.1模块的概念模块是python程序架构的一个核心概念每一个以扩展名.py结尾的python源代码文件都是一个模块模块名同样也是一个标识符&#xff0c;需要符合标识符的命名规则在模块中定义的全局变量、函数、类都是提供给外界直接使用的工具模块就好比工具包&#xff0c;要想…

世界坐标系->相机坐标系详细推导

基变换 理论部分 在n维的线性空间中&#xff0c;任意n个线性无关的向量都可以作为线性空间的基&#xff0c;即空间基不唯一。对于不同的基&#xff0c;同一个向量的坐标一般是不同的。因为在计算机图形学中&#xff0c;主要研究三维的空间&#xff0c;所以可以简化问题倒三维…

Hi3861鸿蒙物联网项目实战:智能测距仪

华清远见FS-Hi3861开发套件&#xff0c;支持HarmonyOS 3.0系统。开发板主控Hi3861芯片内置WiFi功能&#xff0c;开发板板载资源丰富&#xff0c;包括传感器、执行器、NFC、显示屏等&#xff0c;同时还配套丰富的拓展模块。开发板配套丰富的学习资料&#xff0c;包括全套开发教程…