搭建问答系统的步骤:
一 . 首先对问答库进行拆分,将文本分别拆分为问题库和答案库
源码:
import json
from matplotlib import pyplot as plt
import re
import string
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
from nltk.stem.porter import PorterStemmer
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
from queue import PriorityQueue as PQueue
from functools import reduce
def read_corpus():
“”"
读取给定的语料库,并把问题列表和答案列表分别写入到 qlist, alist 里面。 在此过程中,不用对字符换做任何的处理(这部分需要在 Part 2.3里处理)
qlist = [“你多大了?”, “你的性别是?”, “你的妈妈叫什么呢?” …]
alist = [“答案1”, “答案2”, “答案3” …]
务必要让每一个问题和答案对应起来(下标位置一致)
“”"
qlist = []
alist = []
with open(“train-v2.0.json”, ‘r’) as path:
fileJson = json.load(path)
json_list=fileJson[‘data’]
for data_dict in json_list:
for data_key in data_dict:
if data_key==“paragraphs”:
paragraphs_list=data_dict[data_key]
for content_dict in paragraphs_list:
for qas_key in content_dict:
if “qas” == qas_key:
qas_list = content_dict[qas_key]
for q_a_dict in qas_list:
if len(q_a_dict[“answers”]) > 0:
qlist.append(q_a_dict[“question”])
alist.append(q_a_dict[“answers”][0][“text”])
print(qlist)
print(alist)
print(“qlist len:” + str(len(qlist)))
print(“alist len:” + str(len(alist)))
assert len(qlist) == len(alist) # 确保长度一样
return qlist, alist
read_corpus()
语料数据:
train-v2.0.json
问题与答案分开处理结果
[‘When did Beyonce start becoming popular?’]
[‘in the late 1990s’]
[‘When did Beyonce start becoming popular?’, ‘What areas did Beyonce compete in when she was growing up?’]
[‘in the late 1990s’, ‘singing and dancing’]
[‘When did Beyonce start becoming popular?’, ‘What areas did Beyonce compete in when she was growing up?’, “When did Beyonce leave Destiny’s Child and become a solo singer?”]
[‘in the late 1990s’, ‘singing and dancing’, ‘2003’]
二 . 将问题进行文本处理:
1 . 循环遍历问题库里每一个问题
2 . 对每一个问题进行文本处理:
>.首先加载停用词库
>.对问题用nltk分词进行小写化,去停用词,数值归一化后重新加入到一个问题库
*基于规则的中文分词 ,停用词用什么数据结构来存储? 不一样的数据结构会带来完全不一样的效率 去掉出现频率很低的词 找出频率比较高的最,以100分为基准
>.对这个已经处理完的问题库用zipf定律进行词频过滤
3.对输入的问题及进行文本处理
对于用户的输入问题,找到相似度最高的TOP5问题,并把5个潜在的答案做返回
4.将处理好的问题库词向量化(用glove或word2vec,句子词向量化是将词向量相加取平均)后计算问题库向量L2范数
###bert训练词向量这个正在了解中
5.将处理好的输入问题词向量化并计算问题向量L2范数
三 . 建立一个简单的倒排表
利用倒排表的优化。所用到算法也有一个最大的缺点是每一个用户问题都需要跟库里的所有的问题都计算相似度 ,先从库里面找到跟当前的输入类似的问题描述。然后针对于这些candidates问题再做余弦相似度的计算。这样会节省大量的时间。
四 . 利用倒排表计算问题库词向量和输入问题词向量的余弦相似度
五 . 建立优先队列,采用(优先级(余弦相似度),与相似度对应的问题答案下标)(值越小,优先级越大)找出top所对应的答案下标
六 . 根据找出的答案下标到答案库里遍历打印即可