基于医疗知识图谱的问答系统思路分析
本文介绍了知识图谱在问答系统和语义搜索领域的应用,并重点阐述了中国科学院软件研究所刘焕勇老师开发的项目QABasedOnMedicaKnowledgeGraph。该项目将知识图谱分为构建和问答两部分:构建部分通过爬取医疗数据并清洗后导入MongoDB和Neo4j进行管理;问答系统则包括问题分类、解析和答案搜索功能。文章强调了知识图谱在人工智能领域的研究热点及其重要性。
知识图谱[
一、项目主体结构
该系统主要包含两个核心功能模块:医疗知识图谱构建以及基于此的知识问答服务。其中具体实现包括:
- 通过Python脚本实现医疗知识图谱的数据构造(build_medicalgraph.py);
- 通过相同的Python脚本实现智能问答系统的初始化(chatbot_graph.py);
同时完整展示项目的整体架构安排。
├── E:\QASystemOnMedicalKG
├── data
├── medical.json
├── dict
├── check.txt
├── deny.txt
├── department.txt
├── disease.txt
├── drug.txt
├── food.txt
├── producer.txt
├── symptom.txt
├── prepare_data
├── build_data.py
├── data_spider.py
├── disease.txt
├── first_name.txt
├── first_name_spider.py
├── max_cut.py
├── answer_search.py
├── build_medicalgraph.py
├── chatbot_graph.py
├── question_classifier.py
├── question_parser.py
├── README.md
二、知识图谱构建
(一)获取以疾病为核心的医疗数据呈现庞大的规模,在一般个人电脑上完成全部数据提取程序所需时间约为24小时,并需将这些信息直接导入非关系型数据库MongoDB进行后续处理,请参阅附录中的data_spider.py文件。图中展示了从MongoDB中导出的原始医疗数据的具体存储格式。

对获取的爬取数据进行清洗整理,并将其清洗后整理为一个符合Neo4j导入格式的节点属性字典形式。随后将清洗整理后得到的数据直接导入MongoDB中作为辅助存储(见附录代码)。需要注意的是,在数据清洗过程中丢失了first_name.txt文件,在项目开发环境中找到相关代码并进行了适当增删以完成first_name.txt文件的提取工作(读者如有需求可参考https://pan.baidu.com/s/1LNMyffgl4Qic1EryFDimkg获取代码包,默认密码为37ul)。
#!/usr/bin/python3
# -*- coding:utf-8 -*-
"""
@Author : heyw
@Contact : he_yuanwen@126.com
@Time : 2020/1/31 21:25
@Software: PyCharm
@FileName: first_name_spider.py
"""
import urllib.request
import urllib.parse
from lxml import etree
'''爬取寻医问药网医生姓名'''
class CrimeSpider:
def __init__(self):
pass
'''根据url,请求html'''
def get_html(self, url):
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
'Chrome/51.0.2704.63 Safari/537.36'}
req = urllib.request.Request(url=url, headers=headers)
res = urllib.request.urlopen(req)
html = res.read().decode('gbk')
return html
'''url解析'''
def url_parser(self, content):
selector = etree.HTML(content)
urls = ['http://www.anliguan.com' + i for i in selector.xpath('//h2[@class="item-title"]/a/@href')]
return urls
'''测试'''
def spider_main(self):
namesList = []
for page in range(1, 11000):
try:
symptom_url = 'http://jib.xywy.com/il_sii/symptom/%s.htm'%page
names = self.name_spider(symptom_url)
namesList.extend(names)
print(page, symptom_url)
except Exception as e:
print(e, page)
self.save_names(namesList)
return
def save_names(self,namesList):
with open('first_name.txt','w',encoding='utf-8') as f:
for name in namesList:
f.write(name + "\n")
'''姓名信息解析'''
def name_spider(self, url):
html = self.get_html(url)
selector = etree.HTML(html)
names = selector.xpath('//span[@class="fr replay-docter"]//a[@class="gre"]/text()')
return names
if __name__ == '__main__':
handler = CrimeSpider()
handler.spider_main()
(三)基于字典形式的数据构建节点;以疾病为核心构建三元组关系;将节点与关联信息导入Neo4j数据库构建知识图谱,请参阅附录中的build_medicalgraph.py文件。附图展示了基于清洗数据生成的知识图谱。

三、问题系统构成
问题系统作为该项目的核心模块主要包含三个关键模块:问句分类、问句解析和答案搜索。
(一)问句分类
该系统最初采用"分步处理"的方法来进行信息抽取工作。具体而言首先利用AC自动机算法识别问题中的关键词并结合预先建立的"实体类型"大型词典判断这些关键词的具体类型。随后系统会基于经验设计了多种疑问句关键词集合并通过检查这些关键词是否存在于当前的问题陈述中来归类不同类型的问句。
(二)答 Anthology
回答生成环节的本质就是在特定的问题类型下动态选择 neo4j 的 match 语式模式。
(三)答案搜索
系统会通过 neo4j 数据库执行 match 语式操作并将查询结果转换为用户易于理解的形式以完成问答流程。
