Part 2: 搭建一个简单的问答系统
本次项目的目标是搭建一个基于检索式的简单的问答系统。
通过此项目,你将会有机会掌握以下几个知识点:
- 字符串操作 2. 文本预处理技术(词过滤,标准化) 3. 文本的表示(tf-idf, word2vec) 4. 文本相似度计算 5. 文本高效检索
此项目需要的数据:
- train-v2.0.json: 这个数据包含了问题和答案的pair, 但是以JSON格式存在,需要编写parser来提取出里面的问题和答案。
- glove.6B: 这个文件需要从网上下载,下载地址为:https://nlp.stanford.edu/projects/glove/, 请使用d=100的词向量
检索式的问答系统
问答系统所需要的数据已经提供,对于每一个问题都可以找得到相应的答案,所以可以理解为每一个样本数据是 <问题、答案>。 那系统的核心是当用户输入一个问题的时候,首先要找到跟这个问题最相近的已经存储在库里的问题,然后直接返回相应的答案即可。 举一个简单的例子:
假设我们的库里面已有存在以下几个<问题,答案>: <“人工智能和机器学习的关系什么?”, “其实机器学习是人工智能的一个范畴,很多人工智能的应用要基于机器学习的技术”> <“人工智能最核心的语言是什么?”, “Python”> …
假设一个用户往系统中输入了问题 “机器学习与人工智能有什么关系?”, 那这时候系统先去匹配最相近的“已经存在库里的”问题。 那在这里很显然是 “机器学习与人工智能有什么关系”和“人工智能和机器学习的关系什么”是最相近的。 所以当我们定位到这个问题之后,直接返回它的答案 “其实机器学习是人工智能的一个范畴,很多人工智能的应用要基于机器学习的技术”就可以了。所以这里的核心问题可以归结为计算两个问句(query)之间的相似度。
在本次项目中,你会频繁地使用到sklearn这个机器学习库。具体安装请见:http://scikit-learn.org/stable/install.html sklearn包含了各类机器学习算法和数据处理工具,包括本项目需要使用的词袋模型,均可以在sklearn工具包中找得到。
Part 2.1 第一部分: 读取文件,并把内容分别写到两个list里(一个list对应问题集,另一个list对应答案集)
import json
def read_corpus(file_path):
"""
读取给定的语料库,并把问题列表和答案列表分别写入到 qlist, alist 里面。 在此过程中,不用对字符换做任何的处理(这部分需要在 Part 2.3里处理)
qlist = ["问题1", “问题2”, “问题3” ....]
alist = ["答案1", "答案2", "答案3" ....]
务必要让每一个问题和答案对应起来(下标位置一致)
"""
with open(file_path, 'r') as path:
fileJson = json.load(path)
qlist = []
alist = []
for data_dict in fileJson['data']:
for par_dict in data_dict['paragraphs']:
for qa_dict in par_dict['qas']:
qlist.append(qa_dict['question'])
try:
alist.append(qa_dict['answers'][0]['text'])
except IndexError:
qlist.pop()
assert len(qlist) == len(alist) # 确保长度一样
return qlist, alist
qlist, alist = read_corpus('./data/train-v2.0.json')
Part 2.2 理解数据(可视化分析/统计信息)
对数据的理解是任何AI工作的第一步,需要充分对手上的数据有个更直观的理解。
# TODO: 统计一下在qlist 总共出现了多少个单词? 总共出现了多少个不同的单词?
# 这里需要做简单的分词,对于英文我们根据空格来分词即可,其他过滤暂不考虑(只需分词)
from collections import Counter
word_cnt = Counter()
for text in qlist:
word_cnt.update(text.strip(' .!?').split(' '))
print(sum(word_cnt.values()))
# TODO: 统计一下qlist中每个单词出现的频率,并把这些频率排一下序,然后画成plot. 比如总共出现了总共7个不同单词,而且每个单词出现的频率为 4, 5,10,2, 1, 1,1
# 把频率排序之后就可以得到(从大到小) 10, 5, 4, 2, 1, 1, 1. 然后把这7个数plot即可(从大到小)
# 需要使用matplotlib里的plot函数。y轴是词频
import matplotlib.pyplot as plt
values = []
for item in word_cnt.most_common(100): # 打印前出现频率最高的一百个词
values.append(item[1])
print(word_cnt.most_common(100))
plt.plot(values)
plt.show()
Part 2.3 文本预处理
次部分需要尝试做文本的处理。在这里我们面对的是英文文本,所以任何对英文适合的技术都可以考虑进来。
# TODO: 对于qlist, alist做文本预处理操作。 可

本文介绍如何构建一个基于检索的问答系统,涵盖文本预处理、TF-IDF向量表示、词向量应用及倒排索引优化等关键技术。
最低0.47元/天 解锁文章
7809

被折叠的 条评论
为什么被折叠?



