Giter VIP home page Giter VIP logo

bert-embedding-frequently-asked-question's Introduction

BEFAQ

BEFAQ(BERT-based Embedding Frequently Asked Question) 开源项目是好好住面向多领域FAQ集合的问答系统框架。

我们将Sentence BERT模型应用到FAQ问答系统中。开发者可以使用BEFAQ系统快速构建和定制适用于特定业务场景的FAQ问答系统。

BEFAQ的优点有:


(1)使用了Elasticsearch、Faiss、Annoy 作为召回引擎

(2)使用了Sentence BERT 语义向量(Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks)

(3)对同义问题有很好的支持

(4)支持多领域语料(保证了召回的数据是对应领域的,即使是同样的问题,也可以得到不同的答案。)

(5)提供了根据当前输入提示联想问题(suggest)功能的接口

BEFAQ的框架结构如下图

image

如何使用

1、通过docker的方式使用(docker中已经安装Es7.6.1、kibana、IK分词器和同义词功能,BEFAQ的代码也已经包含在docker中。)

我们提倡通过docker的方式快速上手,启动方式请参考根目录下的docker文件夹中的README.md

2、通过非docker的方式使用

2.1、在本机安装Es7.6.1和配套的kibana,配置Es的IK分词器和同义词功能

请参考博客[ES(Elasticsearch)7.6.1安装教程](https://blog.csdn.net/weixin_37792714/article/details/108025200)进行安装。如何已经配置过Es、IK分词器和同义词功能,可以略过这一步。但是记得把同义词同步到你的Es中。为了方便大家。相关文件的下载,都放在了百度网盘中,欢迎大家使用。链接:https://pan.baidu.com/s/1PxgINf6Q1UZBtcsYw6FU0w  密码:4q9h

在BEFAQ中,为了方便大家的使用,我们提供两种Elasticsearch的连接方式:使用用户名和密码的方式与不使用用户名密码的方式。如何修改请参看项目根目录下config文件夹的es.ini 配置文件中的说明。在我们的博客中,我们提供了Elasticsearch配置用户名和密码的方式。

2.2、下载项目代码并创建BEFAQ的虚拟环境

conda create -n befaq python=3.6 -y
source activate befaq
git clone https://github.com/hhzrd/BERT-Embedding-Frequently-Asked-Question.git
进入BEFAQ的根目录,然后
pip install -r requirements.txt

2.3、sentence-transformers 多语言预训练模型的下载

首先进入到项目的根目录,然后
cd model
wget https://public.ukp.informatik.tu-darmstadt.de/reimers/sentence-transformers/v0.2/distiluse-base-multilingual-cased.zip
unzip distiluse-base-multilingual-cased.zip
请将模型文件都直接放在model文件夹下。
如果使用最新的模型报错(并且sentence_transformers==0.3.0),请到百度网盘中下载老版本的模型(适配sentence_transformers==0.3.0,transformers==3.0.2)。目前BEFAQ使用的sentence_transformers已经升级到1.2.0版本号。

2.4、excel数据格式

如果你想要先跑通代码尝试一下。可以先不配置自己的数据。

excel表格请放置在项目根目录下的 data/文件下,例如目前是示例文件名为“线上用户反馈回复.xls” excel数据是QA数据的来源,其中的数据会被写入到Es中。大家下载源码后,可以打开这个文件具体看一下数据示例。

sheet的名称表示不同的领域,比如,我的第一个领域,叫做“领域1”。其中,第一列是“数据填写人姓名”,可以为空。第二列是“答案”,不允许为空。第三列是“原始问题”,不允许为空。第三列以后是“同义问题”,同义问题的数量没有限制。可以有很多同义问题,也可以一个同义问题都没有。一行一条数据。

sheet名为“词典”的,放置的是用户词典。比如,我不想让“好好住”这个词在分词的过程中被切开。就把这个词放置在词典中。一行一条数据。程序会自动读取到指定位置(用于jieba分词),但是Es中IK分词器的自定义词典需要自己添加
sheet名为“停用词”的,放置的是停用词词典。一行一条数据。程序会自动读取到指定位置。
sheet名为“同义词”的,是放置同义词的sheet。第一列是原义词,第二列及其之后是同义词。比如,番茄和西红柿是同义词。第一行列放番茄,第二列放西红柿。一行一条数据。同义词的数据需要自己写到Es的同义词表中,具体参看我上边提到ES(Elasticsearch)7.6.1安装教程的博客。因为你当下的服务器未必是Es的服务器,所以这里并没有用程序直接写入。

同义词,词典,停用词。多个领域共用。词典,停用词是给BEFAQ的jieba分词使用的。同义词是给Es使用的。

你可以在Excel中写上很多领域的数据,但是具体读取哪些领域的数据,项目根目录下config文件夹的sheetname.conf中可以配置。

2.5、修改BEFAQ的配置文件

项目根目录下的data/线上用户反馈回复.xls 是QA数据的来源,其中的数据会被写入到Es中。如果你想要先跑通代码尝试一下。可以先不配置自己的数据。
项目根目录下的config文件夹下sheetname.conf 是读取Excel文档数据的配置文件。如果你想要先跑通代码尝试一下。可以先不修改这里的配置。
项目根目录下的config文件夹的es.ini 是BEFAQ关于ES的配置文件。这个配置文件即使是想要先跑通代码尝试一下,也是需要修改的。这个配置文件里需要配置Es的IP(域名)和端口号,Es的登陆的用户名和密码。一定要根据自己的Es的配置进行修改,才能让BEFAQ连接上你的Es。
项目根目录下的config文件夹的befaq_conf.ini 是BEFAQ的配置文件。如果你想要先跑通代码尝试一下。可以先不修改这里的配置。

2.6、如何开启BEFAQ服务

进入项目的根目录,然后
source activate befaq
cd es

将数据从excel中的数据写到Es 
python write_data2es.py

将问题处理成Sentence BERT 向量,保存到bin类型文件中,便于后期读取问题的向量。
python write_vecs2bin.py

训练Faiss和Annoy模型
python train_search_model.py

启动BEFAQ服务 (如果数据没有发生变化,后期启动服务只需要进行这一步)
进入项目的根目录(cd ..),然后
cd src
启动BEFAQ服务
python main_faq.py
或者在后台中启动
nohup python -u main_faq.py > "../logs/log_$(date +"%Y-%m-%d-%H").txt" 2>&1 &

查看项目运行状态
ps -ef|grep main_faq.py

在终端中测试BEFAQ。BEFAQ的服务是post请求。(将127.0.0.1替换成自己的ip)

curl -d "question=如何评价设计师&get_num=3&threshold=0.5&owner_name=领域1"   http://127.0.0.1:8129/BEFAQ

接口url:
http://127.0.0.1:8129/BEFAQ
接口参数说明
question:用户的问题。必需
get_num:接口最多返回几条数据。非必需,默认为3
threshold:阈值,相似度高于或等于这个阈值的数据才会被接口返回。非必需,默认为0.5
owner_name:数据所有者的名称,也就是excel中每个领域的数据对应的sheet name。用来区分多领域数据。必需

返回的数据格式:
[
    {
        "q_id": 2,
        "specific_q_id": 3,
        "question": "如何评价设计师",
        "answer": "你好。点击认证设计师头像,进入TA的个人主页,点击左下角「评价」即可进行评价。此外,设计师的荣耀值是根据设计师的站内数据综合计算,无法直接打分的哦。感谢你的支持。",
        "confidence": 1.0
    },
    {
        "q_id": 6,
        "specific_q_id": 7,
        "question": "怎样把个人设计师转成机构设计师",
        "answer": "你好,可以登录好好住官网,再次点击提交设计师认证资料,即可重新修改哟;",
        "confidence": 0.6
    }
]

2.7、如何开启BEFAQ的联想词接口服务

如果想要启动根据当前输入联想问题的功能。
进入项目根目录,然后
cd src
python associative_questions_server.py
或者在后台中启动
nohup python -u associative_questions_server.py >/dev/null 2>&1 &

查看项目运行状态
ps -ef|grep associative_questions_server.py


在终端中测试联想功能。服务是post请求。(如果不是本机,请将127.0.0.1替换成自己的ip)
curl -d "current_question=设计师&limit_num=3&owner_name=领域1&if_middle=1"  http://127.0.0.1:8128/associative_questions

接口url:
http://127.0.0.1:8128/associative_questions
接口参数说明
current_question:
limit_num:接口最多返回几条数据。必需
owner_name:数据所有者的名称,用来区分多领域数据。必需
if_middle:是否允许用户当前输入的内容在中间的位置。非必需。默认为1,1为允许,0为不允许。

返回的数据格式:
{
    "code": "1",
    "msg": "OK",
    "data": {
        "message": [
            "按地区找设计师",
            "设计师可以选择同城吗",
            "怎样把个人设计师转成机构设计师"
        ]
    }
}

Authors


该项目的主要贡献者有:

参考文献:


[1] 百度AnyQ

[2] sentence-transformers

[3] Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks

Copyright and License

BEFAQ is provided under the Apache-2.0 license.

bert-embedding-frequently-asked-question's People

Contributors

xiaoyichao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

bert-embedding-frequently-asked-question's Issues

python3.6.16 docker中各种报编码问题

读es.ini , 读sheetname.conf ,读excel文件,中文文件名都的报unicode错误,前两个我在读配置文件时候指定编码是utf-8解决了,excel这个指定编码都不行,最后是把文件改名了才解决

分词查询问题

你好,我想问下,搜索查询的时候使用的结巴对query进行分词、去停用词,然后match处理过的process_question,但是es的分词用的是IK,这样是不是有问题的呀?

使用ES7.10.1召回时报错

Traceback (most recent call last):
File "/Users/cgxw/miniconda3/envs/faq/lib/python3.7/site-packages/sanic/app.py", line 937, in handle_request
response = await response
File "/Users/cgxw/PycharmProjects/pythonProject1/FAQ/BEFAQ/faq/main_faq.py", line 93, in myfaq
owner_name=owner_name, question=orgin_query, query_word_list=query_word_list, use_faiss=use_faiss, use_annoy=use_annoy, engine_limit_num=engine_num, ES_limit_num=ES_num, use_other_when_es_none=use_other_when_es_none)
File "/Users/cgxw/PycharmProjects/pythonProject1/FAQ/BEFAQ/faq/retrieval_es.py", line 200, in search_merge
owner_name=owner_name, query_word_list=query_word_list, ES_limit_num=ES_limit_num)
File "/Users/cgxw/PycharmProjects/pythonProject1/FAQ/BEFAQ/faq/retrieval_es.py", line 63, in search_es
index_name=index_name, owner_name=owner_name, query_word_list=query_word_list, limit_num=ES_limit_num)
File "/Users/cgxw/PycharmProjects/pythonProject1/FAQ/BEFAQ/es/es_operate.py", line 332, in search_data
index=index_name, body=doc)
File "/Users/cgxw/miniconda3/envs/faq/lib/python3.7/site-packages/elasticsearch/client/utils.py", line 92, in _wrapped
return func(*args, params=params, headers=headers, **kwargs)
File "/Users/cgxw/miniconda3/envs/faq/lib/python3.7/site-packages/elasticsearch/client/init.py", line 1627, in search
body=body,
File "/Users/cgxw/miniconda3/envs/faq/lib/python3.7/site-packages/elasticsearch/transport.py", line 362, in perform_request
timeout=timeout,
File "/Users/cgxw/miniconda3/envs/faq/lib/python3.7/site-packages/elasticsearch/connection/http_urllib3.py", line 248, in perform_request
self._raise_error(response.status, raw_data)
File "/Users/cgxw/miniconda3/envs/faq/lib/python3.7/site-packages/elasticsearch/connection/base.py", line 244, in _raise_error
status_code, error_message, additional_info
elasticsearch.exceptions.RequestError: RequestError(400, 'x_content_parse_exception', '[1:27] [bool] failed to parse field [must]')
INFO:sanic.access:

最新的版本上有一些 error code

def search_annoy(self, owner_name, question, num=5):
    '''
    Author: xiaoyichao
    param {type}
    Description: 使用Annoy 召回
    '''
    sentences = read_vec2bin.read_bert_sents(owner_name=owner_name)
    annoy_index_path = os.path.join(
        dir_name, '../es/search_model/%s_annoy.index' % owner_name)
    **encodearrary = self.sentenceBERT.get_bert([question])**
    tc_index = AnnoyIndex(f=512, metric='angular')
    tc_index.load(annoy_index_path)
    items = tc_index.get_nns_by_vector(
        encodearrary[0], num, include_distances=True)
    sim_questions = [sentences[num_annoy] for num_annoy in items[0]]
    # sims = items[1]
    # index_nums = items[0]
    return sim_questions

def search_faiss(self, owner_name, question, num=5):
    '''
    Author: xiaoyichao
    param {type}
    Description: 使用Faiss 召回
    '''
    sentences = read_vec2bin.read_bert_sents(owner_name=owner_name)
    faiss_index_path = os.path.join(
        dir_name, '../es/search_model/%s_faiss.index' % owner_name)
    index = faiss.read_index(faiss_index_path)
    **question_vec = np.array(bc.encode([question])).astype('float32')**
    index.nprobe = 1
    sims, index_nums = index.search(question_vec, num)
    sim_questions = [sentences[num_faiss] for num_faiss in index_nums[0]]
    # index_nums = index_nums[0].tolist()
    # sims = sims[0].tolist()
    return sim_questions

大佬 这是不是我 es的问题 没有连接上

想要删除的索引 index_faq_1 不存在
Traceback (most recent call last):
File "/Users/hellozhang/Desktop/BEFAQ/es/write_data2es.py", line 90, in
es_faq.create_index(index_name=new_index)
File "/Users/hellozhang/Desktop/BEFAQ/es/es_operate.py", line 253, in create_index
self.es.indices.create(index=index_name, body=mappings_cn)
File "/Users/hellozhang/opt/anaconda3/envs/fqa/lib/python3.6/site-packages/elasticsearch/client/utils.py", line 92, in _wrapped
return func(*args, params=params, headers=headers, **kwargs)
File "/Users/hellozhang/opt/anaconda3/envs/fqa/lib/python3.6/site-packages/elasticsearch/client/indices.py", line 103, in create
"PUT", _make_path(index), params=params, headers=headers, body=body
File "/Users/hellozhang/opt/anaconda3/envs/fqa/lib/python3.6/site-packages/elasticsearch/transport.py", line 362, in perform_request
timeout=timeout,
File "/Users/hellozhang/opt/anaconda3/envs/fqa/lib/python3.6/site-packages/elasticsearch/connection/http_urllib3.py", line 252, in perform_request
self._raise_error(response.status, raw_data)
File "/Users/hellozhang/opt/anaconda3/envs/fqa/lib/python3.6/site-packages/elasticsearch/connection/base.py", line 282, in _raise_error
status_code, error_message, additional_info
elasticsearch.exceptions.RequestError: RequestError(400, 'illegal_argument_exception', 'Custom Analyzer [text_ik] failed to find tokenizer under name [ik_smart]')

如何增量更新?

假如问答数据有几十万条,每次训练都需要执行很长的时间,是否可以增量更新,增量训练?

sentence-bert

请问sentence-bert 用在 BEFAQ的架构图里面的那一部分?

sentense-bert如何应用

请问您是如何利用sentense-bert生成词向量的?是在自己的问答对(正例、反例)数据集上进行微调后保存model,接着再用生成的模型生成词向量的吗?

docker中无法启动main_faq.py

进入docker后 cd 进入 src 文件夹下,
nohup python -u main_faq.py > "logs/log$(date +"%Y-%m-%d-%H").txt" 2>&1 &
会显示如下错误
image

但是associative_questions_server.py这个服务可以正常启动,调用接口也正常
image

请问有可能是什么导致main_faq无法启动呢?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.