开发一个智能问答机器人

article/2025/8/28 20:41:00

近期开发了一套基于自然语言处理的问答机器人,之前没有做过python,主要做asp.net,写这篇目的是给想要开发这类智能客服系统的朋友提供一个思路,项目已经上线,但在开发和设计过程中仍然有很多问题没有得到解决,也期望和大家一同讨论学习。

最终的上线效果: 

开发过程大概3阶段,第一阶段 完成基础一问一答功能;第二阶段 加入意图识别,可以进一步区分用户问题,特定意图比如工资查询,将会调用第三方接口;第三阶段 上下文处理,引导用户进行多轮问答;

插一句微软认知服务是云端的较好解决方案,  BOT Framework平台集成了多种对接方式,无需自己开发。LUIS的配置和发布也非常方便,特别的如果使用场景真的非常简单(一问一答),可以仅用QnAMaker。

but... 基于业务数据暴露和其他安全性考虑,有时需要将服务部署在本地(内网),我主要想说的就是本地开发搭建的问答服务。

1 基础问答实现

1.1选型

能够做基础问答的开源项目非常多chatterbot,rasa_core等等。我选用的是chatterbot(0.7.6)

1.2开发

在搭建完开发环境后chatterbot可以直接使用,默认算法是编辑距离,所以理论上支持任何语言,包括中文。

我主要修改了chatterbot算法模块,适配器模块和输入输出模块,最终输出格式如下

复制代码
{"text": "三方协议一式三方,三方盖完章后,学校,公司,学生本人各留一份。","in_response_to": [{"text": "三方协议如何存档?","created_at": "2017-11-24T15:11:06.500966","occurrence": 4}],"created_at": "2017-11-24T15:11:06.500","extra_data": {"userid": "1000058"},"question": "三方协议如何存档?","oriquestion": "三方协议","channel": "2","suggestions": [["三方协议如何存档?", 0.62],["三方协议可以他人带签署领取吗?", 0.42],["实习生三方协议上面部门怎么填写?", 0.4]]
}
复制代码

text答案,in_response_to上下文,extra_data附加信息(可以放用户身份标识等),question匹配到的问题,oriquestion用户输入问题,channel词库编号(支持多词库每个词库可能有不同的处理),感兴趣问题列表(匹配度稍低的问题)

chatterbot的adapter本来设计是可以放多个,每个适配器完成自己的功能(解耦),但实际使用时(5000条问答),多适配器是非常缓慢的,由于每个适配器都会循环处理或比对问题,所以建议只放一个adapter实现所有功能

'logic_adapters':['mybot.MyLogicAdapter']

算法

位于comparisons.py中默认的编辑距离算法或杰拉德相似系数算法,都是基于简单的文本比对,无法处理同义词近义词。这里我们引入的word2vec算法

训练数据来自中文维基百科,加入了特定业务文档数据(仅73M,维基百科1.11G...)

使用jieba分词,gensim word2vec训练模型,特征向量400维,大概需要14小时(参考我的吃鸡电脑I7 7700 GTX1080)。

# 装载之前训练好的模型custom_model = Word2Vec.load('data/custom.model')用户输入先通过jieba分词,得到词和词频的数组,例如:查询我的薪资
查询 2
我 5
的 1
薪资 3
# 查询key在模型中向量
vec =custom_model['查询'] # 加权(模型中向量*jieba分词中权重) 
sentvec = sentvec + vec * 2

把句子中词向量相加得到整个句子的向量。

再利用夹角余弦,与业务词库中的问题比较,得到最相似的问题匹配。

此方法,可以处理诸如,皇后->女人 这类的近义问题。从图上可以看到女人与皇后余弦夹角小于皇后与木头余弦夹角,结论为女人与皇后更相似。

 

所以最终的算法:编辑距离+word2vec。

2 意图识别

意图识别属于自然语言理解范围,主流机器学习算法支持向量机、决策树等分类方法。我们使用意图识别主要用来分离出用户的查询意图,再调用对应的第三方接口将数据返回给用户,例如 北京今天天气?识别为天气意图,实体为北京。

2.1选型

我们这里选用开源项目rasa_nlu(11.0.3),这是一个集意图识别,实体提取功能于一体的项目。可以生成如下的数据

复制代码
{"intent": {"name": "weather","confidence": 0.44477984330690684},"entities": [{"entity": "city","value": "大连","start": 0,"end": 2,"extractor": "ner_mitie"},{"entity": "date","value": "后天","start": 2,"end": 4,"extractor": "ner_mitie"}],"intent_ranking": [{"name": "weather","confidence": 0.44477984330690684},{"name": "bookhotel","confidence": 0.37330751883981904},{"name": "map","confidence": 0.18191263785327412}],"text": "大连后天天气怎么样"
}
复制代码

2.2开发

在实际使用中,有时可能仅需要提取实体,所以我额外做了一个流程,仅提取实体。

复制代码
{"entities": [{"entity": "city","value": "大连","start": 0,"end": 2,"extractor": "ner_mitie"}],"text": "大连天气怎么样"
}
复制代码

2.3命名实体提取替换

项目最终使用"pipeline": ["tokenizer_jieba","ner_synonyms","intent_entity_featurizer_regex","intent_featurizer_mitie","intent_classifier_sklearn","ner_corenlp"]之前使用MITIE作为命名实体提取,但MITIE需要自己训练,实际使用时训练语句过少,正确率偏低,改用corenlp,默认支持中文 我截取目标默认可以识别的实体类型
# DATE: type:日期  eg:明天
# LOCATION: type:地点 eg:齐齐哈尔
# MISC: type:其他 eg:怎么样
# MONEY: type:金额
# ORGANIZATION: type:组织
# PERCENT: type:百分比
# PERSON: type:人 eg:特朗普
# TIME: type:时间 eg:下午
# O: type:动词或其他 eg:查询
# COUNTRY: type:国家 eg:中国
# STATE_OR_PROVINCE: type:城市/省会 eg:北京
# CITY: type:城市 eg:西安

 

 

2.0补充

系统缺陷修复,使用rasa_nlu意图分类,基于sklearn-svmcv算法,但是分类后,各意图结果相加始终等于1,我之前的设想(后面有详细说明):设定一个阈值比如0.7,判断最高匹配度的意图是否大于阈值,如果大于则认为明确意图。但这基于问题是意图的前提,

我训练意图用了三个分类weather,bookhotel,map,但我无法将问答的5000个问题训练为other意图,由于5000个问答中涉及多领域,非常多的特征向量会对意图分类造成很大影响,使分类不准确。

目前的解决方案为在意图识别前,加入一个二分类器,也基于sklearn的分类器,用于区分问题还是意图,训练使用18000条生产环境用户问题和6000*3加权的意图问题(等量的训练数据)训练并比较准确率。

用户问题标识(1意图0普通问题)
今天天气如何1
我想预订北京的酒店1
机器人的内部处理流程是怎样的0
公司发展历程0

 

 

 

 

 

生成pkl文件。将pkl文件放入指定位置,替换最准确算法。

当前最高为随机森林算法

******************* NB ********************

accuracy: 90.06%

******************* KNN ******************** 

accuracy: 87.50%

******************* LR ********************

accuracy: 90.91%

******************* RF ********************

accuracy: 96.31%

******************* DT ********************

accuracy: 95.17%

******************* SVM ********************

accuracy: 25.28%

******************* SVMCV ********************

accuracy: 93.75%

******************* GBDT ********************

accuracy: 87.78%

 

3 上下文

看了很多大神基于深度学习算法的帖子还有论文,感觉实在力不从心... 这里使用模板配置的方式,引导用户完成上下文。

JSON数据格式

{
"rule": [{
"intent": "weather",
"entities": [
{"name":"city","type":"city","required":"true","prompts":["请问查询哪里的天气","想查询哪个城市的天气"]},
{"name":"date","type":"date","required":"false","prompts":[]}
]
},
{
"intent": "bookhotel",
"entities": [
{"name":"city","type":"city","required":"true","prompts":["请问预订哪里","想预订哪个城市"]},
{"name":"checkindata","type":"date","required":"true","prompts":["请问何时入住","预订酒店的时间"]},
{"name":"checkoutdata","type":"date","required":"false","prompts":[]}
]
},
{
"intent": "bookticket",
"entities": [
{"name":"fromcity","type":"city","required":"true","prompts":["请提供出发城市","从哪起飞"]},
{"name":"tocity","type":"city","required":"true","prompts":["请提供到达城市","到哪落地"]},
{"name":"date","type":"date","required":"true","prompts":["请问预订机票的时间","想预订哪天的机票"]}
]
}
]
}

这就是上下文的控制流程,主要代码逻辑控制,没有使用机器学习算法。

  

特别的,这里阈值非常的重要,阈值范围0~1,越小越容易被理解为意图,当为1时,等同于关键字匹配。

举个栗子,如果阈值设定非常小,用户的普通提问都会被理解为意图,不会进入chatterbot问答中,如果非常大,则难以进入意图识别,训练data 查询工资,如果用户输入“查询我的工资”可能也不会进入意图查询

阈值我使用梯度下降算法,拟合成二维曲线,找到最高点,0.74

 

后记

项目开发过程大概4个月(第一周,学习python基础语法,主要了解函数,变量赋值逻辑,web api实现,之后开始学习深度学习算法,主要从帖子、论文和视频,MIT、台大、Stanford的教学视频都非常好,可以在B站上看,选型时几乎试用了所有开源的QA项目,一般QA项目都需要训练,准备语料所以耗费了大量时间),独立开发,实际编码时间一个月,最后用asp.net mvc封装了这些接口,做了问答页面和简单的后台语料管理系统(我也想用python...来不及)

我们业务问答5000多条,一共有3个实习生,配合我标注语料,编写测试集和验证集(真正的工作量在这)

最终正确率:68.4%(微软验证集正确率:81.7%)

 

chatterbot 项目主框架

https://github.com/gunthercox/ChatterBot

sklearn 意图问题分类

https://github.com/automl/auto-sklearn

rasa_nlu 意图识别模块

https://github.com/RasaHQ/rasa_nlu

gensim word2vec算法实现

https://github.com/RaRe-Technologies/gensim

word2vec,中文处理

https://github.com/zake7749/word2vec-tutorial

相似度比较-向量余弦夹角

https://github.com/kris2692/Vector-semantics

 

主要问题:

1.正确率太低:如果单用word2vec算法,正确率只有36.2%,单用编辑距离算法正确率59.8%,不知道为何我写word2vec算法正确率如此低,一直没有找到原因。

2.数据分散,用多种语言编写:整个项目一共三部分:chatterbot,rasa_nlu,mvc web,在修改意图时非常麻烦,在管理系统修改意图后,生成json文件,需要手工拷贝到rasa_nlu项目中,再使用cmd命令train,start server。

原文地址:https://www.cnblogs.com/yilanyang/p/8629948.html


http://chatgpt.dhexx.cn/article/mqokaf7R.shtml

相关文章

【原创】聊天机器人与自动问答技术

聊天机器人与自动问答技术 作者:mjs (360电商技术) 引言 最近半年,微软的聊天机器人小冰比较火,有些人对这方面的技术产生了兴趣,恰好之前做过自动问答方面的一些简单工作,这次写一篇应景之作&…

智能问答机器人

1. 前言 问答机器人现在很多场合都有使用,比如:网页智能客服、微信公众号智能回复、淘宝的售后客服,QQ聊天机器人等等。有了这些客户机器人就能帮我们回答很多预置的一些问题,帮助用户解决常见问题,还可以进行自主训练…

智能问答机器人概述

智能问答机器人概述 总览任务机器人FAQ机器人闲聊机器人 总览 处理逻辑: query–>中控逻辑–>response 任务机器人 指特定条件下提供信息或服务的机器人。 任务型机器人核心模块主要包括三部分: 自然语言理解模块 —— Language Understanding …

数仓实时数据同步 debezium

数仓实时数据同步 debezium 背景debezium 简介架构基本概念 例子Router目前遇到的问题 背景 数据湖将源库的数据同步到hive数仓ods层,或直接在kafka中用于后面计算。源库包括mysql、postgresql、sqlserver、oracle,大部分是mysql数据库。当前采用的sqoo…

基于日志的同步数据一致性和实时抽取

宜信技术研发中心架构师 目前就职于宜信技术研发中心,任架构师,负责流式计算和大数据业务产品解决方案。曾任职于Naver china(韩国最大搜索引擎公司)中国研发中心资深工程师,多年从事CUBRID分布式数据库集群开发和CUB…

解析 TiDB 在线数据同步工具 Syncer

TiDB 是一个完全分布式的关系型数据库,从诞生的第一天起,我们就想让它来兼容 MySQL 语法,希望让原有的 MySQL 用户 (不管是单机的 MySQL,还是多机的 MySQL Sharding) 都可以在基本不修改代码的情况下,除了可以保留原有…

服务器与客户端的数据同步

2019独角兽企业重金招聘Python工程师标准>>> 问题 从一个例子说起,我们的客户端从服务器获取数据,这里假定获取文章。第一次使用,我们获取服务器端最新发表的几篇文章。 我们可以每次都重新获取,但这样费时又费流量。好…

数据实时同步或抽取上收的技术分析

原文:http://blog.csdn.net/dsg_gulibin/article/details/1696365 1 实现数据集中的技术手段分析比较 根据业界提供数据同步或抽取的解决方案来看,主要包括以下几大类: l 存储复制技术 l 数据库复制技术 l …

时间同步/集群时间同步/在线/离线

目录 一、能够连接外网 二、集群不能连接外网--同步其它服务器时间 一、能够连接外网 1.介绍ntp时间协议 NTP(Network Time Protocol)网络时间协议,是用来使计算机时间同步的一种协议,它可以使计算机对其服务器或时钟源做同步…

如何实时同步数据到StarRocks

我们知道,是StarRocks基于Doris开发的,它在多表连接查询的性能方面引领OLAP市场,是一个很好用的结构化数据仓库。但是一直没有很好的工具能够实现业务数据库的数据实时同步到StarRocks分布式数据仓库集群中,本文将带领读者一起来通…

文件实时同步

rsync remote sync 远程同步,同步是把数据从缓冲区同步到磁盘上去的、数据在内存缓存区完成之后还没有写入到磁盘中去、所以有时候要同步到磁盘中去的,而rsync说白了跟复制差不多、能将一个文件从一个地方复制到另外一个地方的、但是他也可以实现跨主机复…

系统间通讯实现数据信息实时同步解决方案

项目开发阶段遇到一个需求,描述大致就是同一个用户在A系统数据库保存的数据信息与在B系统数据库保存的数据信息要保持同步。当A系统用户修改了个人信息,A系统后台在将用户修改后的信息入库的同时也会向B系统发送消息,让B系统后台进行自动数据…

一文带你玩转实时数据同步方案

1、概述 1.1、目标 实时数据同步主要实现从源数据库到目标数据库的实时数据同步。源数据主要支持mysql数据库,目标数据包括mysql数据库和hbase数据库。 下面是实时数据同步的数据流转图,mysql的增量订阅数据经过canal和kafka,数据最终实时…

两台服务器同时写文件 怎么做同步,两台服务器做实时数据同步

两台服务器做实时数据同步 内容精选 换一换 DCS Memcached即将下线,部分Region已暂停售卖,建议使用Redis4.0/5.0。本章节主要描述Memcached主备实例。Memcached主备实例在单机实例基础上,增强服务高可用以及数据高可靠性。Memcached主备实例具…

实时数据同步方案

一.Flume收集各数据库日志,准实时抽取到HDFS 安装HDP,包含Flume 方案优点: 1.配置简单,不用编程:只要在flume.conf文件中配置source、channel及sink的相关属性 2.采用普通SQL轮询的方式实现,具有通用性&…

如何实现数据自动化的实时同步?

企业在日常业务中,比如总分支机构之间、数据中心之间、不同节点之间、跨国业务之间等,都需要将文件及时的传输,以供协同使用。所以,很多企业会选择一些同步工具或软件。 谈到文件同步备份大家使用较多的可能是Rsync、同步盘等一些…

像素是什么,一个像素有多大,像素和分辨率的关系

图片的像素和分辨率 对于像素和分辨率这两个词,主要见于图片和显示设备上。只要你用到手机里的照相功能,你都要接触到这两个概念。只是大多数人都是一知半解,而更多的人却根本就不知道,白白浪费了手机里500万、800万像素的摄影头&…

屏幕尺寸、分辨率、DPI、PPI

屏幕尺寸 下面这张图是华为荣耀7的尺寸图,图上写的是5.2英寸。我们所说的这个5.2英寸是手机屏幕对角线的长度。 我们平时是不用英寸这个单位的,我们用的是毫米,厘米,米这些单位。那么英寸和毫米,厘米之间怎样的换算关…

像素(Pixel)、DPI与PPI一看就明白

像素(Pixel)、DPI与PPI 像素(Pixel)DPI 英文全写是(Dots Per Inch,每英寸点数)PPI 英文全写是(Pixels Per Inch,每英寸像素数)比喻来区分应用(这张图熟悉吗)1.分辨率啥意思&#xff…

关于像素、分辨率、PPI、DPI等概念的分析

关于影像图的比例尺和分辨率:https://blog.csdn.net/liliiii/article/details/40261953 当我们说到 像素、分辨率、DPI、PPI等专业术语的时候,一般会涉及到图像、屏幕、打印机等等。 像素(Pixel)为图像显示的基本单位,…