简单的检索式问答系统

本文介绍了一个基于文本的问答系统构建过程,涵盖了数据预处理、文本表示、相似度计算及高效检索等关键技术。通过实际项目,详细讲解了从数据读取、统计分析到文本预处理、TF-IDF向量化、倒排索引优化以及词向量应用的全流程。

这是我之前做的一个小项目,趁现在有时间就把它拿出来记录一下。

通过此项目,能够掌握以下几个知识点:

  1. 字符串操作 2. 文本预处理技术(词过滤,标准化) 3. 文本的表示(tf-idf, word2vec) 4. 文本相似度计算 5. 文本高效检索

简单的检索式的问答系统

问答系统所需要的数据已经提供,对于每一个问题都可以找得到相应的答案,所以可以理解为每一个样本数据是 <问题、答案>。 那系统的核心是当用户输入一个问题的时候,首先要找到跟这个问题最相近的已经存储在库里的问题,然后直接返回相应的答案即可。

此项目需要的数据:

  1. dev-v2.0.json: 这个数据包含了问题和答案的pair, 但是以JSON格式存在,需要编写parser来提取出里面的问题和答案。
  2. glove.6B: 这个文件需要从网上下载,下载地址为:https://nlp.stanford.edu/projects/glove/, 请使用d=100的词向量

问题答案对数据已上传:https://download.csdn.net/my

Part 1:读取文件,并把内容分别写到两个list里(一个list对应问题集,另一个list对应答案集)

def read_corpus():
    """
    读取给定的语料库,并把问题列表和答案列表分别写入到 qlist, alist 里面。 在此过程中,不用对字符换做任何的处理(这部分需要在 Part 2.3里处理)
    qlist = ["问题1", “问题2”, “问题3” ....]
    alist = ["答案1", "答案2", "答案3" ....]
    务必要让每一个问题和答案对应起来(下标位置一致)
    """
    import json
    
    path = "./data/train-v2.0.json"
    with open(path,'r',encoding="utf8") as f:
        all_data = json.loads(f.read())
    data = all_data["data"]
    qlist = []
    alist = []
    
    for dic in data:
        paragraphs = dic["paragraphs"]
        for para in paragraphs:
            qas = para["qas"]
            for qa in qas:
                if qa["answers"] != []:
                    answer = qa["answers"][0]["text"]
                    alist.append(answer)
                    question = qa["question"]
                    qlist.append(question)
    assert len(qlist) == len(alist)  # 确保长度一样
    return qlist, alist

Part 2: 理解数据(可视化分析/统计信息)

对数据的理解是任何AI工作的第一步,需要充分对手上的数据有个更直观的理解。

# TODO: 统计一下在qlist 总共出现了多少个单词? 总共出现了多少个不同的单词?
#       这里需要做简单的分词,对于英文我们根据空格来分词即可,其他过滤暂不考虑(只需分词)
import string
import re

# 去标点符号,分词,得到词-词频字典
def segmentWords(lst):
    total = 0
    word_dict = {}
    for line in lst:
        pattern = re.compile('[{}]'.format(re.escape(string.punctuation)))
        sentence = pattern.sub("", line)
        words = sentence.split()
        for word in words:
            word_dict[word] = word_dict.get(word, 0) + 1
            total += 1
    return total,word_dict

qlist, alist = read_corpus()
word_total,q_dict = segmentWords(qlist)
total_diff_word = len(q_dict.keys())
print("总共 %d 个单词" % word_total)
print("总共 %d 个不同的单词" % total_diff_word)
# 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

word_sorted = sorted(q_dict.items(),key=lambda k:k[1],reverse=True) #按词频排序
word_freq = []
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值