基于倒排表的图书馆参考咨询问答系统的设计与实现
2021-09-29柴源
柴源
(西安航空学院 图书馆, 陕西 西安 710077)
0 引言
问答系统是接收用户的自然语言问题,向用户返回答案的对话系统[1],能够提升规律性情景交互效率。图书馆参考咨询业务具有极强的重复性和规律性,问答系统在该场景下能够提升咨询服务的效能。
1 图书馆参考咨询问答系统面临的问题及倒排表
1.1 图书馆参考咨询问答系统面临的问题
1.1.1 图书馆参考咨询数据繁多
随着课程支持、学习支持、科研支持等的不断出现,传统参考咨询服务的内容不断细化。加之,现代信息技术的发展,QQ、微信等逐渐成为主要的咨询渠道,参考咨询服务的即时性和个性化要求越来越高。此背景下,具有重复性和规律性的参考咨询数据越来越多。
1.1.2 传统问答系统的不足
传统问答系统是基于正向索引模式,即当读者在搜索某一关键词时,系统就需要扫描索引库中的所有文档,找出所有包含相关关键词的文档,再根据打分模型进行打分,排出名次后呈现给用户[2]。大数据时代,文档的数目越来越多,这样的索引结构无法满足实时返回排名结果的要求。
1.2 倒排表及优势
在问答系统实际的应用中,为了通过关键词的某些值查找记录,就必须按照关键词建立索引,称作倒排索引[3]。带有倒排索引的文件称作倒排索引文件(也称倒排文件),倒排文件中的次关键字索引称作倒排表[4],如图1所示。
图1 倒排表
在处理复杂得多关键词查询时,可在倒排表中先完成查询的交、并等逻辑运算,得到结果后再对记录进行存取。这样不必对每个记录随机存取,把对记录的查询转换为地址集合的运算,从而提高查找效率。
2 基于倒排表的图书馆知识问答系统设计
2.1 系统设计
基于倒排表的图书馆知识问答系统总体设计主要包括语料库数据预处理,形成倒排表;用户数据预处理,与倒排表进行匹配,找到所有问题ID;将用户所提问题和找到的问题进行相似度计算,并输出结果,如图2所示。
图2 系统结构图
2.2 详细设计
2.2.1 语料库收集与预处理
信息技术智能化、需求个性化,造成图书馆参考咨询数据日益繁多,通过各种手段收集、整理并形成语料库是最基础、最重要的任务。对于电话、面对面等形式的咨询,可以通过建立咨询服务清单,及时将数据进行分类归档;对于微信、QQ等新媒体数据,可以通过编写网络爬虫进行抓取。语料库一般由问题、答案两部分组成,以列表的形式存储。
语料库预处理中,综合《中文停用词表》《哈工大停用词表》《百度停用词表》《四川大学机器智能实验室停用词库》建立停用词表(stopwords);根据各图书馆的实际情况,建立用户词典(userdict)。基于此,应用jieba分词工具进行分词,并过滤掉标点符号、单字词等。
2.2.2 建立倒排表
在语料库数据预处理的基础上,形成原始索引,如{‘问题1ID’:[关键词1,关键词2…],‘问题2ID’:[关键词2,关键词3…]…}。其中,ID为问题1所在的行数,即问题1为第一个问题,ID为1。因为需要将用户提出的问题和库里的问题进行相似度计算,然后返回相似度高的问题答案。如果遍历库里的每一个问题,然后和用户提出的问题做相似度计算,数据量大,时间成本太大。因此,处理后的倒排索引为{‘关键词1’:[问题1ID],‘关键词2’:[问题1ID,问题2ID…}。
2.2.3 用户数据预处理及问题匹配
对用户提的问题,首先分词,找到问题的关键词。然后根据关键词,找到包含该关键词的所有问题ID。
2.2.4 相似度计算及结果输出
余弦相似度是通过计算两个向量的夹角余弦值来评估他们的相似度[5],对于两个向量,即空间中从原点([0, 0,…])出发,指向不同方向的两条线段,两条线段之间形成一个夹角:如果夹角为0度,则意味着方向相同、线段重合;如果夹角为90度,意味着形成直角,方向完全不相似;如果夹角为180度,意味着方向正好相反。因此,可以通过夹角的大小,来判断向量的相似程度。夹角越小,就代表越相似。对n维向量A,B,假设A=[A1,A2,…,An],B=[B1,B2,…,Bn],则A与B的夹角θ的余弦等于式(1)。
(1)
余弦值的范围在[-1,1]之间,值越趋近于1,代表两个向量的方向越接近;越趋近于-1,他们的方向越相反;接近于0,表示两个向量近乎于正交[6]。一般情况下,相似度都是归一化到[0,1]区间内,因此余弦相似度表示为cosine_similarity=0.5cosθ+0.5。
研究中,将包含用户问题关键词的问题和2.2.3中的问题当作两个向量,进行相似度计算,并输出相似度最高的2个问题答案。
3 基于倒排表的图书馆知识问答系统的实现——以西安航空学院图书馆为例
3.1 语料库收集与预处理
3.1.1 语料库收集
西安航空学院图书馆参考咨询数据主要来自规章制度、微信、QQ、日常参考咨询服务清单。文章利用Python编写网络爬虫工具,抓取微信、QQ等工具中的问答数据,日常参考咨询服务清单、规章制度的数据可直接应用,分析发现,主要包括学习类、科研类、教学类和生活类。部分实验数据(file_text)如表1所示。
3.1.2 数据预处理
文章根据西安航空学院图书馆日常工作需要,建立用户词典,包括阅读学分、通借通还、文献传递、新书库等296个词语;定义函数,删除除字母、数字、汉字以外的所有符号和单字词;加载2.2.1节中的停用词表,过滤停用词。应用jieba工具对表1的“问题”进行分词,形成“cut_review”文件,部分结果如表2所示。
3.2 建立倒排表
将表2中的数据进行重新排序,即将含有同一关键词的问题归为一组,形成{<关键词>,<文档1编号,文档2编号,文档3编号…….>}的倒排表,执行程序如下。
result={}
for i in range(len(file_txt)):
left, rights = i,file_txt.iloc[i]['cut_review'].split()
for right in rights:
if right in result.keys():
result[right].append(left)
else:
result[right] = [left]
部分执行结果如下。
{'沣惠': [0], '校区': [0, 1, 3, 4], '图书馆': [0, 1], '地址': [0, 1], '阎良': [1, 3, 4], '咨询电话': [2], '开放': [3, 4], '时间': [3, 4], '书库': [4]}。其中,0,1,2,3……为文档编号。例如,'阎良': [1, 3, 4]表示在第1、3、4个文档中都含有“阎良”这个词语。
3.3 用户问题数据处理
对用户输入的问题进行分词,过滤停用词,提取关键词,并在倒排表中匹配到的所有问题ID,执行程序如下。
User_Q="用户问题"
clean_reviewyonghu=remove_punctuation(User_Q)
cut_reviewyonghu=[w for w in list(jieba.cut(clean_re-viewyonghu)) if w not in stopwords and len(w)>1]
Problem_Id=[]
for j in cut_reviewyonghu:
if j in result.keys():
Problem_Id.extend(result[j])
id=(list(set(Problem_Id)))
print(id)
表1 实验语料库(部分)
表2 数据预处理结果(部分)
第一行表示载入用户问题User_Q;第二到四行表示对User_Q进行数据清洗,包括除标点、分词、去掉停用词及单字词等,形成cut_reviewyonghu集合;五到九行表示遍历cut_reviewyonghu和倒排表result,匹配到所有问题ID。例如,当用户输入即User_Q=“图书丢啦怎么办”时,执行程序,结果为[17,13,14,15],表示用户的问题包含在第17、13、14、15文档中。
3.4 相似度计算并输出结果
定义函数,对用户所提问题分别与3.3节的执行结果进行相似度计算,并输出相似度最高的两个问题的答案,执行程序如下。
def cosine_similarity(sentence1: str, sentence2: str)-> float:
seg1 = [word for word in jieba.cut(sentence1) if word not in stopwords]
seg2 = [word for word in jieba.cut(sentence2) if word not in stopwords]
word_list = list(set([word for word in seg1 + seg2]))
word_count_vec_1 = []
word_count_vec_2 = []
for word in word_list:
word_count_vec_1.append(seg1.count(word))
word_count_vec_2.append(seg2.count(word))
vec_1 = np.array(word_count_vec_1)
vec_2 = np.array(word_count_vec_2)
num = vec_1.dot(vec_2.T)
denom = np.linalg.norm(vec_1) * np.linalg.norm(vec_2)
cos = num / denom
sim = 0.5 + 0.5 * cos
return sim
str1=sentence
similarity={}
if len(id)==0:
print('数据库里没有该问题,请重新提问')
else:
for i in id:
str2 = file_txt.iloc[i]['问题']
sim1 = cosine_similarity(str1, str2)
print('用户所提问题和问题{0}的相似度是{1}'.format(i, sim1))
similarity[i] = sim1
print(similarity)
word_list用于分词后建立词库,word_count_*统计在词典里出现词的次数。当User_Q=“图书丢啦怎么办”时,执行结果如下。
用户所提问题和问题17的相似度是0.644 337 567 297 406 4
用户所提问题和问题13的相似度是0.704 124 145 231 931 5
用户所提问题和问题14的相似度是0.704 124 145 231 931 5
用户所提问题和问题15的相似度是0.704 124 145 231 931 5
经过计算机的排序计算,输出相似度较高的两个问题的答案,形式如图3所示。
图3 实验结果
4 总结
本文对基于倒排表的图书馆参考咨询问答系统的现状进行了详细分析,然后进行了系统设计和详细设计,并以西安航空学院图书馆参考咨询为例,实现了相关功能。本文所设计的问答系统能够满足图书馆参考咨询的使用需求,语料库的不断更新与完善将是未来的研究重点。