基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统

最近耗时一周,我基于Python+Neo4j ,搭建了一个民航业知识图谱的自动问答系统。

文章目录

    • 环境
    • 运行
    • 1、项目结构
    • 2、数据组织
    • 3、问题预处理
    • 4、问题分类
    • 5、Web APP
    • 源码&技术交流

环境

  • Windows 10 x64

  • Python 3.7

  • Neo4j community 3.5.20

运行

  • 1、确保安装所需依赖
  pip install -r requirements.txt

注:python-Levenshtein 如果安装不成功,则可以下载对其进行离线安装。

  • 2、构建知识图谱

修改const.py文件中连接数据库使用的URI,USERNAME和PASSWORD的值。然后执行:

  python build_cakg.py

运行大约需要2~5分钟。

  • 3、可以使用两种方式运行:

①. 运行命令行端

  python run_cmd.py

普通问题的回答以字符串的形式给出;带有图表的回答,图表会被渲染至results文件夹中。

②. 运行web端(效果图见下文)

  python run_web.py

带有图表的回答和普通回答一样会被渲染至web页面中,同时也被保存至本地results文件夹中。

注1:最好使用谷歌浏览器(Google Chrome);

注2:生成图表的文件夹地址可以在const.py中更改CHART_RENDER_DIR。

  • 4、have fun!

1、项目结构

---------------------------------------  root
   |------data/                        # 数据存放
          |------dicts/                # 存放特征词(运行build_cakg.py后自动生成)
          |------question/             # 存放问句中的疑问词
          |------reference/            # 存放指代词
          |------tail/                 # 存放尾词(后缀词)
          |------data.json             # 从年报中组织出的数据
          |------raw.7z                # 11-19年的年报
   |------demo/                        # 以jupyter-notebook的形式给出了各种问题类型的演示和说明
   |------doc/                         # 存放有关readme的文件
   |------lib/                         # 函数库
   |------results/                     # 存放某些问题生成的图表(会自动生成)
   |------test/                        # 存放一些单元测试
   |------web/                         # web app
   ......
   |------answer_search.py             # 回答组织器
   |------build_cakg.py                # 构建知识图谱
   |------chatbot.py                   # 自动问答器
   |------const.py                     # 常量
   |------question_classifier.py       # 分类器
   |------question_parser.py           # 解析器

2、数据组织

①. 基本构想

通过浏览公报发现:

  • 每一年所涉及的目录大差不差,有时多有时少,或者只是改个名字;

  • 目录中涉及的指标每年都有一定的变动,而且某些指标里面嵌套指标,还有些指标中给出了各地区的组成值;

  • 指标的值有数值类型,也有字符串类型,有的有单位,有些则没有,而且有些单位在某些年份还不同。

基于上述几点,我将知识图谱的构建以年份为中心展开,将各个目录、指标等等实体作为知识图谱的结点。结点与结点之间相连接的关系称为结构关系(详细见下文),那么将每个年份结点到各个指标和地区的关系称为值关系(详细见下文)。

将结构和值两种关系拆开:

  • 从结构关系来看,不用一个年度录入一个年度的所有指标,每个年度中肯定有重复指标,这样避免了数据冗余。若每年的指标位置基本不变,则上述做法直接可行,但实际上指标出现的位置可能每年都飘忽不定,所以若直接按上述做法会出现这种情况:

假设2012年指标C1包含指标A、B,指标C2包含指标C;2013年指标C1包含指标A,指标C2包含指标B、C;则其结构关系为:

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第1张图片

其中橙色的边是2012年特有的,蓝色的则是2013年特有的,而黑色的是它们共有的。但在知识图谱中这些边没有颜色之分,是按上图整个结构存储的,这就造成了一个父子结构关系错乱的问题,比如:我要查找13年指标C1包含的所有指标,则A和B都会被返回,而实际上B不应该被返回。

为了解决上述问题,并且不增加任何额外的关系,我为每个关系引入了一个生命周期属性life。这个属性运用了掩码的思想,每个年份维护自己的掩码(运行构建知识图谱脚本时会被自动生成),在遇到上述问题时,拿来和关系中的life做与运算,若结果不为0,就说明此年份包含此指标,反之则不含。

  • 从值关系来看,问题中也是直接给出年份和指标名称,这样也方便查询。

部分结点间的关系如下图:(橙色为年份,棕色为目录,蓝色为指标)

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第2张图片

部分结点间的关系如下图:(橙色为年份,棕色为目录,蓝色为指标,红色为地区/机场/公司集团,下同)

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第3张图片

②. 知识图谱实体类型

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第4张图片

③. 知识图谱实体关系类型

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第5张图片

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第6张图片

④. 知识图谱属性类型

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第7张图片

3、问题预处理

主要指年份和指标两个角度的预处理,此部分详见lib/complement.py。

①. 年份角度 对问题中的年份进行替换,方便特征词识别,例:

   11-> 2011年
   两千一十一年 -> 201111-15-> 2011,2012,2013,2014,20151315-> 2013,2014,201513年比前年 -> 2013年比201115年比大大前年 -> 2015年比201116年比3年前 -> 2016年比201316年与前三年相比 -> 2016年与2015,2014,2013年相比
   ......

②. 指标角度 对问题中的指标名进行替换,避免因错字漏字而特征词识别不成功。通过Levenshetin算法实现对指标名的模糊查询。例:

   游客周转量 -> 旅客周转量
   ......

4、问题分类

问题的分类是基于特征词的分类,使用ahocorasick算法。

下表给出的是各种问题的类型,更详细的内容请参见项目demo中的demo1~4.ipynb。

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第8张图片

5、Web APP

web端使用Flask构建,采用前后端分离的方式。问答界面较为简洁。但可实现以下功能:

  • 回答带有的图表可以直接渲染至页面;

  • 回答中某些关键词以tooltips的形式进行了解释说明(关键词取自年报的注释部分)。

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第9张图片

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第10张图片

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第11张图片

源码&技术交流

本文项目源码、数据、技术交流提升,均可加交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友

方式①、添加微信号:dkl88191,备注:来自CSDN +研究方向
方式②、微信搜索公众号:Python学习与数据挖掘,后台回复:民航问答系统

基于Python+Neo4j+民航数据 ,我搭建了一个知识图谱的自动问答系统_第12张图片

你可能感兴趣的:(机器学习,知识图谱,neo4j,python)