如何从零实现一个基于问答对的智能问答系统

Python、Java开发者

文章正文

简要概述

文章概述

基于问答对的问答系统,其本质是一种基于检索的问答,其与常规的关键词检索最大区别在于:问答对的问答是从语义角度从数据库中检索答案,而关键词检索仅仅是从关键词的角度进行检索,当用户的搜索表达方式和数据库中存储的表达方式不一致时就无法得到用户所需要的信息

项目概述

本场 Chat 主要做的是一个关于《十万个为什么》的问答,实现当用户输入问题的时候,自动回答问题对应的答案。

鉴于很多大而全的项目让人很难理解的特点,本项目在实现过程中,会先从一个简单的版本入手,以便于更好地理解原理和初衷,然后通过问题的分析引入改良后的版本。

项目的总体流程如下图所示:

  1. 用户输入问题 input_sentence ;
  2. 问答程序将用户问题与问答库中的问题进行相似度匹配,得到与用户问题最相似的问题 mostsimilarsentence ;
  3. 然后返回 mostsimilarsentence 对应的答案给用户,完成一次问答。

问答流程

效果演示

项目的实现效果如下: 问答效果

项目实现

问题分析

根据问答流程,项目将从问答数据的构建、相似度计算和词向量编码三个关键点切入,先初步实现一个最小可用系统。

那为什是这么三个点呢?

首先问答库是问答系统的知识源泉,有知识才能问答,其次,相似度计算是问答系统的决策中枢,决定着用户的问题是否能得到正确的回应,而文本的相似度计算是一个很难的问题,从计算机的角度来说,计算机无法对文本直接进行计算,在很多情况下,都会将文本转为向量,从数学的角度进行计算,这个过程就是词向量编码。

现在我们可以开始定义我们的接口代码:

class QaInterface(object):
    def __init__(self):
        '''
        初始化的时候载入知识库
        '''
        self.questions_and_answers = None

    def encode(self,sentence):
        '''
        将sentence转为词向量
        :return: sentence的词向量
        '''
        pass

    def compute_similarity(self,input_sentence,recall_sentence):
        '''
        计算input_sentence和recall_sentence的相似度
        :param input_sentence:
        :param recall_sentence:
        :return:
        '''
        pass

    def __call__(self, sentence):
        # 将输入语句 sentence 编码为词向量
        # 遍历数据库中的每一个问题 
        # for 问题 in 数据库中的问题:
            # 将每一个 问题 编码成词向量
            # 将 sentence 的词向量 与 问题的词向量 进行相似度计算
            # 找到与 sentence 最相似的问题和答案

        # 如果计算完后发现相似度全都小于 一定的阈值 则返回没有答案

下面说一下问答过程需要解决的三个问题:

  1. 问答库该如何存储?
  2. 问题的相似度如何计算?
  3. 词向量如何编码?

问答库构建

问答库是我们存储问答数据的地方,一般而言问答的存储需要包含两个比较重要的信息,一个是问题,一个是答案,为了唯一区分每一条数据,可以再增加一个属性 id ,数据的原始格式如下:

  {
    "id": 3932,
    "question": "为什么恒星会发光而行星不会发光",
    "answer": "20世纪初,根据伟大的物理学家爱因斯坦的相对论推出了一个质量和能量的关系式,帮助天文学家解决了恒星为什么发光这一问题。原来,恒星内部温度高达1 000万摄氏度,物质处在这样高的温度下会发生热核反应,由较轻的原子核聚变成为较重的原子核,在这个过程中损失一部分质量,同时释放出巨大的能量。于是,这些能量以辐射的方式由内传到外,从恒星表面发射至空间,使它
                        
作者正在撰写中...
隐藏内容 支付可见
内容互动
写评论
加载更多
评论文章
¥9.99 购买
× 订阅 Java 精选频道
¥ 元/月
订阅即可免费阅读所有精选内容