概述
faq的问答系统是目前用的比较广泛的问答系统,由于它落地简单,并且大部分场景都需要,构建一个faq问答系统可以作为一个baseline快速应用到实际场景中。下面就介绍如何快速构建一个faq问答的baseline。
一、环境的搭建
faq的核心技术是信息检索,信息检索的常用工具则是es,es既可以对faq知识库存储,又可以快速查询文本。同时也有配套的可视化工具kibana,方便数据查询和管理。此外,es的社区也很活跃,文档和讨论的问题也方便使用。
elasticsearch+kibana安装
使用docker容器拉取镜像文件,注意elasticsearch和kibana的版本要一致,本人使用的版本均为7.8.1的版本。
启动容器,根据官网的教程启动docker容器,选用单个节点
docker run -p 9200:9200 -p 9300:9300 --name es7.8
-e "discovery.type=single-node"
-e ES_JAVA_OPS="-Xms512m -Xmx512m"
-d elasticsearch:7.8.1
如果是中文检索,需要安装中文分词器,先到GitHub - medcl/elasticsearch-analysis-ik: The IK Analysis plugin integrates Lucene IK analyzer into elasticsearch, support customized dictionary.上下载对应版本的ik分词器,然后进入容器解压到对应文件夹。
安装完es后再安装kibana
docker run --link es7.8.1:elasticsearch -p 5601:5601 -d kibana:7.8.1
二、python操作es
创建索引
es = Elasticsearch('http://127.0.0.1:9200')
base_info_index_mappings = {
"settings":{
"index.analysis.analyzer.default.type": "ik_max_word"
},
"mappings":{
"properties": {
"id": {
"type": "keyword"
},
"standard_question": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"sim_question": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"answer": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
},
"query_vector": {
"type": "dense_vector",
"dims": 768
},
"update_date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
},
"create_time": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd"
},
}
}
}
批量插入数据
def insert_data(index_name, items, batch_size=100):
'''
批量插入数据到索引中
:param index_name:
:param items:
:param batch_size:
:return:
'''
batch = []
err_count = 0
for i, columns in enumerate(items):
[sim_question, std_question, answer, vector] = columns
id = uuid.uuid1()
update_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
create_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
try:
body = {
'_index': index_name,
'_source': {
'id': id,
'standard_question': std_question,
'sim_question': sim_question,
'answer': answer,
'query_vector': vector,
'update_time': update_time,
'create_time': create_time
}
}
except Exception as e:
err_count += 1
print(e)
if len(batch)<batch_size:
batch.append(body)
cur_id = id
else:
helpers.bulk(es, batch)
print('总共有{}条数据,存储到第{}条数据'.format(len(batch), i))
if len(batch)>0:
helpers.bulk(es, batch)
print('最终id是{}'.format(cur_id))
print('err_count:{}'.format(err_count))
return '插入数据完成'
其中的query_vector通过bert模型提前计算出768维向量并存入es的dense_vector格式数据字段中。关于bert向量计算可参考下部分代码
def extract_vectors(self, model, text):
'''
抽取句子向量
:param text:
:return:
'''
batch_token_ids, batch_segment_ids, batch_mask = [], [], []
word_ids, segment_ids, word_mask = encode(text)
batch_token_ids.append(word_ids)
batch_segment_ids.append(segment_ids)
batch_mask.append(word_mask)
inputs = dict(
input_word_ids=batch_token_ids,
input_mask=batch_mask,
input_type_ids=batch_segment_ids,
)
infer_input = {
"input_word_ids": tf.convert_to_tensor(inputs['input_word_ids']),
"input_mask": tf.convert_to_tensor(inputs['input_mask']),
"input_type_ids": tf.convert_to_tensor(inputs['input_type_ids']),
}
outputs = model(infer_input)
encoder_outputs = outputs[0]
last_encoder = encoder_outputs[-1]
mean_vecor = tf.reduce_mean(last_encoder[:, 1:len(text) + 1, :], axis=1)
print(mean_vecor.shape)
mean_vecor_norm = tf.norm(mean_vecor, ord=2, axis=0)
mean_vecor = mean_vecor / mean_vecor_norm
print(mean_vecor.numpy()[0].shape)
return mean_vecor.numpy()[0].tolist()
三、查询
es可以计算向量的余弦相似度,通过向量检索的形式可以找出最相近的问题,检索代码如下:
script_query = {
"script_score": {
"query": {
"match_all": {
},
},
"script": {
"source": "cosineSimilarity(params.query_vector, 'query_vector') + 1.0",
"params": {"query_vector": query_vector}
}
}
}
body = {
"_source": ["standard_question", "sim_question", "answer"],
"size": 5,
"query": script_query,
}
res = search_data_by_body('faq_test_index', body)
其中query_vector为实时用bert抽取的查询文本向量。该方法速度很快,满足上线要求。
四、总结
以上就是一个faq问答系统的baseline,有一个比较重要的步骤是在之前就做好了,就是知识库的构建,需要某一业务场景的常用的faq问题及答案的总结。在baseline的基础上,后续可以不断丰富知识库,也可以通过精排、意图分类等方法提高查询的准确率。
最后
以上就是爱笑花生为你收集整理的基于bert特征提取的FAQ问答系统构建的全部内容,希望文章能够帮你解决基于bert特征提取的FAQ问答系统构建所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复