责任说明:本项目为作者的毕设项目,仅供大家参考学习,切勿直接抄袭。
github项目地址:https://github.com/jiqiu123/KG-VAQSystemOnMedical-master
设计总说明
本设计项目旨在开发基于Neo4j的医疗知识图谱可视化系统。近年来,随着医疗数据量的迅速增长,知识图谱作为一种将不同实体和关系关联并可视化的工具,为医学领域的研究和应用提供了新的机会。本项目的任务来源于希望通过知识图谱整合医疗领域的多源数据提供一种直观、交互的方式来探索医疗信息的关联性。为了确保设计质量和系统稳性,本项目遵循以下设计标准:具备扩展能力,能够添加新的实体和关系,支持未来需求的变化;提供直观、易用的可视化界面,帮助用户快速理解知识图谱的结构;具有良好的交互体验,用户可以轻松浏览、搜索和探索知识图谱;保持高效的性能,即使面对大量数据和复杂查询,也应保持响应迅速;系统应确保数据的安全与隐私,防止未经授权的访问和数据泄露。在设计过程中,本项目采用以下原则:系统的设计应分为独立模块,以便于维护和扩展;设计需具备一定的灵活性,能够适应不同的应用场景;界面设计应注重用户体验,确保易用性和可操作性;系统应具备稳健性,确保运行稳定。同时本项目的创新点为将医疗小助手与可视化界面联合起来,而不是使两个系统孤立开来。医疗小助手回答中会将系统中储存的疾病关键词标红,用户可以提供点击任意标红疾病关键词跳转至可视化界面,并直接生成对应的知识图谱。
本项目使用了多种技术和工具,以下是主要的技术资料:Neo4j官方文档,提供了图数据库的使用方法和最佳实践,为知识图谱的构建提供指导;Py2neo库,这是一个与Neo4j交互的Python库,帮助实现节点和关系的创建及查询;Flask框架,一个轻量级的Web框架,用于构建后端服务和API;D3.js库,用于知识图谱的可视化,提供了丰富的交互功能。设计过程主要包括以下步骤:确定系统需要构建哪些实体和关系,明确系统的功能需求;构建系统的总体架构,确定数据库设计和模块划分;定义知识图谱中的实体、关系和属性,并使用Neo4j实现;使用Flask构建后端服务,使用Py2neo与Neo4j交互,前端使用D3.js进行可视化;对系统进行测试,修复错误,确保系统稳定运行;将系统部署到目标环境,制定维护计划。
本项目成功构建了一个完整的医疗知识图谱可视化系统,主要结果如下:在该知识图谱系统中,构建了涵盖疾病、症状、药物、科室等实体,以及实体之间的各种关系;系统提供了基于D3.js的可视化界面,用户可以浏览和探索知识图谱;系统支持多种搜索和查询功能,用户可以搜索实体和关系,进行相关分析;系统在测试中表现良好,能够处理较大规模的数据,保持稳定运行。
本项目通过构建医疗知识图谱可视化系统,为医疗信息管理和研究提供了一种有效工具。尽管在设计过程中遇到了一些挑战,但最终实现了预期目标,为后续研究和应用打下了基础。
1. 知识图谱是什么?
1.1 知识图谱的概念
知识图谱,作为一种技术工具,通过图模型这一形式,深入刻画并构建起了世间万千实体与抽象概念间错综复杂的联系网络。这一图谱的构建基础在于节点与边的精妙结合,其中,节点象征着各式各样的实体,无论是具体的个体如人物、书籍,还是抽象的概念如人工智能、知识图谱等,而边则巧妙地连接着这些实体或概念,揭示出它们之间的内在联系与相互影响。通过这样的方式,知识图谱提供了一种全新的视角。而边则用于表示这些实体或概念之间的属性或关系,比如一个人的姓名、一本书的书名,以及更为复杂的实体间关系,如朋友关系、配偶关系等。这种结构化的表示方法能够清晰、直观地展示世界万物的相互关联,为信息检索、数据分析等任务提供有力的支持。知识图谱的早期理念来自Semantic Web(语义网络),其最初理想是把基于文本链接的万维网落转化为基于实体链接的语义网络。它的核心思想是将大量的信息结构化地组织起来,以便计算机可以理解、推理和利用这些信息,从而实现智能化的数据分析、推荐和决策。
1.2 知识图谱的本体要素介绍
在知识图谱的构建中,实体作为其核心组成部分,代表了现实世界中的具体对象或抽象概念。这些实体既可以是具体的个体,如人物、地点、组织、书籍、电影等,也可以是抽象的概念或联系,如情感状态、哲学思想、学术理论等。对于知识图谱的完整性而言,准确识别和细致分类这些实体是至关重要的第一步。
此外,关系在知识图谱中扮演着至关重要的角色,它们作为连接不同实体的桥梁,揭示了实体之间的相互作用和紧密联系。这些关系不仅描述了实体间的语义关联,如家庭关系、友情纽带、包含关系等,还进一步丰富了知识图谱的内涵。因此,关系的精准识别和分类对于深入理解实体间的互动模式具有不可或缺的意义。
在知识图谱中,属性作为描述实体或关系特征的元数据,提供了关于这些元素更为详尽的信息。无论是实体还是关系,都可以拥有各自的属性。例如,一个人物实体可能具有姓名、年龄、性别等属性,而一个组织实体则可能包含成立时间、总部地点等属性。这些属性不仅丰富了知识图谱的语义层次,还使其更加贴近现实世界的复杂性。
最后,在知识图谱中,概念是对一类相同事物的不同个体的总称。它们类似于面向对象编程中的类(Class)概念,为实体提供了分类和归纳的依据。例如,“水果”就是一个概念,而“苹果”、“香蕉”等则是这一概念下的具体实例。概念在知识图谱中起到了构建层次化知识结构的关键作用,使得知识图谱更加系统化和易于理解。
1.3 知识图谱的分层架构
知识图谱的构建涉及两个关键层次:数据层与模式层。其中,模式层扮演着至关重要的角色,它不仅构成了知识图谱的概念框架和逻辑基石,更定义了图谱中的核心要素,包括概念、关系、属性以及规则。这一层次的设立为数据层提供了明确的规范与约束,确保了知识图谱的严谨性和一致性。这一结构确保了知识图谱的一致性和准确性,为后续的数据分析、信息检索等任务提供了坚实的基础。在知识图谱的构建中,本体(Ontology)通常作为模式层的核心组成部分,它负责界定图谱中的基本概念、关联、特性以及准则。本体不仅为数据层提供了标准化的框架,还确保了图谱的一致性和规范性,对于知识图谱的整体结构具有至关重要的作用。通过本体定义的规则和公理,可以确保知识图谱中的数据在结构和语义上保持一致性和准确性。这种结构化的表示方法有助于提升知识图谱的质量,并为后续的数据分析、信息检索等任务提供坚实的基础。知识图谱亦可被视为本体的一种具体实现或实例化。若其不具备推理能力,则它主要聚焦于数据层的表现,而并未涵盖定义核心概念、关系和规则的模式层。这样的结构虽然侧重于数据的存储与展示,但在逻辑完整性和功能丰富性上可能有所欠缺。在知识图谱的模式层中,节点表示本体概念,边表示概念之间的关系。
在数据层中,事实信息通过“实体-关系-另一实体”或“实体-特定属性-对应属性值”的三元组结构进行存储,构建成一个网络状的知识库。其中,实体作为知识图谱的基础构建单元,涵盖了具体的人名、组织机构名、地理位置、日期以及时间等。关系则代表着两个实体之间所存在的语义联系,是模式层定义关系的具体实现。而属性则是对实体特性的描述,通过实体与属性值之间的映射关系,为实体提供了更为详尽的说明。属性可以被视为实体与属性值之间的hasValue 关系,因此也可以转化为以“实体-关系-实体”的三元组形式存储。在知识图谱的数据层中,节点表示实体,边表示实体之间的关系或实体的属性。
1.4 知识图谱构建流程及应用
本文提出了一种基于自下而上和自上而下两种方法来建立知识图谱。本文介绍了一种基于开放领域的知识图谱,即通过自下向上的方式自动抽取概念和概念间的联系。目前,大多数领域知识图谱都是从上到下建立本体的。一方面,领域知识图谱所涉及的概念和范围相对于开放领域知识图谱而言是固定的的;而领域知识图谱,则要求它的精确度要高一些。自顶向下是先把本体和数据模型定义为知识图谱,然后在知识库中加入实体。
图1-1 知识图谱技术架构图
2. 技术平台关键点介绍
整体框架平台集成开发环境为:
Pycharm+neo4j-community-5.16.0+JDK1.6+Python3.10+Microsoft Edge 124.0.2478.67 (64 位)。
技术平台为:py2neo+json+flask+D3.js+ahocorasick。
2.1 技术路线
数据收集与整合: 首先,需要收集来自多个来源的数据,包括文本数据、结构化数
据和半结构化数据。这些数据来自于公开数据集、网络抓取、API接口等渠道。然后,利
用数据整合技术将这些数据进行处理和整合,构建知识图谱的数层。
本体建模与规范化: 接下来,设计和建立知识图谱的模式层。可以借助本体描述语言(如OWL)来进行本体建模,并严格规范模式层的结构和约束。
知识图谱构建与存储: 利用已经整合和规范化的数据,在构建知识图谱的数据层时,我们选择采用图数据库或三元组存储技术来高效地存储和管理知识图谱的数据。这些技术能够准确捕捉和表示图谱中的节点(代表各种实体或概念)以及它们之间的边(代表关联关系),从而确保知识图谱的完整性和准确性,并保证数据的一致性、完整性和可扩展性。
可视化算法与界面设计: 开发可视化算法和用户界面,支持用户对知识图谱中实体、属性和关系的交互式探索。这涉及到图形布局算法、图形渲染技术等,以及用户界面设计原则和实践。
交互式探索与信息检索: 实现交互式探索功能,使用户可以通过图形界面对知识图
谱进行浏览、搜索和查询。开发多层次的信息筛选和检索功能,支持实体搜索、属性分析、关系探索等。系统集成与部署: 将各个模块整合起来,构建完整的基于知识图谱的可视
化系统。进行系统测试和调试,确保系统稳定性和性能。最后,部署系统到相应的平台上,并提供用户友好的配置管理。
3. 需求分析
3.1 一般性需求分析
集中疾病智能问答,知识图谱可视化,数据库后端管理为一体,为用户提供全面的疾病与医疗数据。
3.2 系统功能描述
表3-1系统功能描述表
功能名称 | 备注 |
主页跳转 | 根据用户需求,进入不同的界面 |
数据库管理 | 进入数据库后台进行数据管理 |
智能医疗助手 | 为用户的疾病相关问题进行回答 |
知识图谱可视化 | 根据用户提供的疾病关键字,生成相关可视化图谱 |
关系边显示 | 根据用户选择关系边选项,显示知识图谱对应关系边 |
节点显示 | 根据用户选项,只显示所有相关节点 |
关系显示 | 根据用户选择,显示或隐藏所有关系 |
3.3 可行性分析
基于对当前系统的初步调查,可以设定新系统的目标,这些目标即为新系统建成后预期达到的运行标准,它们将成为系统开发和评估的基准。新系统应保留现有系统的优势,同时改进其不足之处。此外,新系统的目标应与当前系统的基本功能紧密相连,并可根据实际情况分阶段逐步实现。需要强调的是,新系统的目标在总体规划阶段可能无法详尽设定,而是在后续的开发过程中逐步清晰化和量化。
对基于知识图谱的可视化系统的设计与实现课题进行可行性分析,在正式着手实现前是十分重要的。而在新系统的目标确定后,就可以通过对以下三方面来对能否实现新系统目标进行可行性分析:
1.技术可行性:当前,图数据库、可视化算法、前端开发技术等方面的技术已经相对成熟,并且有许多现成的工具和库可供使用,如Neo4j、D3.js等。因此,在技术上实现这样一个系统是可行的。
2.数据可行性:获取和整合多源数据可能是一个挑战,但是随着互联网和开放数据源的不断增加,可以获得大量的结构化和半结构化数据,用于构建知识图谱。此外,许多数据集和API都提供了开放的访问接口,便于数据的获取和整合。
3.用户需求可行性:在知识管理、智能问答系统等领域,对于可视化系统的需求日益增长。构建一个基于知识图谱的可视化系统,能够为用户提供直观、全面的知识视图,满足用户对于知识探索和理解的需求。
4. 概要设计
4.1 系统模块设计
本方案主要包括四个核心模块:数据整合和知识图谱构建、可视化算法和界面开发、多层次信息筛选和检索功能、以及部署和使用工具。
图4-1 任务驱动的知识图谱构建框架
4.2 项目设计
本项目主要用于疾病学术类研究或非学术类简单的疾病问题咨询。该项目主要通过知识图谱可视化功能和智能问答功能,来达到多层次的信息筛选和检索功能,以满足不同用户需求,从学术研究者到普通用户。提高知识图谱的可用性,使知识更容易被利用,从而推动知识管理和智能应用领域的发展。
4.3 设计目标
具体实现目标如下:
1.数据整合和知识图谱构建:从多源数据中构建知识图谱数据库,包括文本、结构化数据和半结构化数据。这将涵盖实体、属性和关系的多维信息。
2.可视化算法和界面开发:设计和实现可视化算法,以呈现知识图谱中的实体、属性和关系,同时开发用户友好的界面,支持交互式探索。
3.多层次信息筛选和检索功能:实现信息筛选和检索功能,以满足不同用户需求,包括实体搜索、属性分析、关系探索等。
4.部署和使用工具:集成用户友好的工具,使知识图谱可视化系统易于部署和使用,包括配置管理、权限控制等功能。
4.4 数据库设计
本系统依托Neo4j数据库来存储和管理数据。数据的保存和安全性是数据库的核心职责,因此,底层引擎以维护数据的完整性和有效性为首要任务至关重要。这要求关系数据库管理系统(RDBMS)必须实施严格的检查机制,以防止任何无效数据未经审查即进入数据库,从而在数据库层面确保数据完整性的强制执行。本系统所使用的数据集medical.json为网上开源疾病数据集而其中的数据爬取于寻医问药网站资讯,保证了数据的可靠度。数据库系统名为neo4j,数据库中将数据集转化为知识图谱各个类型表如下:
表4-1知识图谱实体类型
实体类型 | 中文含义 | 实体数量 | 举例 |
Check | 诊断检查项目 | 3,353 | 肝胆动态显像;胎儿体重预测 |
Department | 医疗科目 | 54 | 心理科;妇科耳;鼻喉科 |
Disease | 疾病 | 8,807 | 短暂性脑缺血发作;心脏病;间歇性斜视 |
Drug | 药品 | 3,828 | 藿香正气水;上清丸 |
Food | 食品 | 4,870 | 豌豆苗;茄子海米汤;发菜香菇酸辣汤 |
Producer | 在售药品 | 17,201 | 广东彼迪胶体果胶铋胶囊;立益注射用门冬酰胺酶 |
Symptom | 疾病症状 | 5,998 | 血压偏低;假日心脏综合征 |
Total | 总计 | 44,111 | 约4.4万实体量级 |
表4-2 知识图谱实体关系类型
表4-3 知识图谱属性类型
感冒 | ||
5. 详细设计
5.1 系统总体分析
5.1.1 系统工作流程分析
系统的工作流程可以分为数据整合、知识图谱构建、可视化展示、交互式探索和部署运维几个关键步骤。以下是系统的总体工作流程:
数据整合:从多源数据中提取信息。本系统将从medical.json数据集中对数据进行清洗、格式转换,最后分类成相应的txt文件。
知识图谱构建:运用提取的数据所分类的txt文件,构建知识图谱,包含实体、属性和关系。这一步通常涉及图数据库或其他结构的运用。
可视化展现:采用了前沿的可视化算法技术,旨在为用户提供一个直观且易于理解的展示形式。为实现这一目标,设计了用户界面,并融入了丰富的交互功能,确保用户能够迅速、准确地理解和操作这一知识图谱,从而更有效地挖掘和利用其中的信息与资源。这种设计不仅提升了用户体验,也极大地提高了知识图谱的实用价值。
交互式探索:用用户能够借助精心设计的界面与知识图谱进行深度互动。这一过程中,用户不仅能进行实体的精确搜索,还能深入探索实体间的关系网络,并进行详尽的属性分析。这种多层次的交互方式,为用户提供了更为全面和细致的知识图谱体验。
智能问答:用户通过可视化界面与智能医疗助手提问互动,得到所需答案。
5.1.2 系统总体架构
数据集成层:负责数据收集和整合。该层提供数据源接口和数据处理逻辑,其中知识图谱的基本单元是由不同来源的数据转换而来。
知识图谱构建层:支持实体、属性和关系的多维度关联,将处理后的数据构建为知识图谱。
可视化层:负责将知识图谱数据可视化,提供交互式界面。该层需要设计良好的用户界面,以便用户操作。
信息检索和分析层:提供搜索和分析工具,支持多层次信息筛选和检索。该层可以支持复杂的查询和关系探索。
部署和运维层:负责系统的部署、配置和维护,确保系统的稳定性和安全性。
5.2 系统模块划分
数据源接口模块:连接和提取来自多源数据的内容,可能涉及文本分析、数据转换等功能。
知识图谱构建模块:根据数据源接口模块提供的数据,构建知识图谱。这可能涉及图数据库的设计与操作。
可视化与交互模块:负责知识图谱的可视化和用户界面的设计,提供交互功能。
信息检索与分析模块:提供信息筛选、检索和分析的功能。该模块与可视化与交互模块协同工作,支持用户的不同需求。
5.3 数据库设计
5.3.1数据库概念设计
在深入探讨了系统的需求并进行详尽的设计之后,现将对本系统中将采用的数据库实体以及它们之间的关联关系进行详细的阐述和介绍。以下是关于这些数据库实体及其关系概念的规划:
1.实体(节点)知识图谱中的实体就是图数据库中的节点,以下是主要的实体类型:
Disease(疾病):其中有疾病名称、描述、预防、原因、治愈概率等。
Symptom(症状):代表与疾病相关的症状表现。
Drug(药物):包含药物的名称及其制造厂商等详细信息。
Food(食物):涉及与疾病管理相关的食物建议,包括适宜摄入、应避免的食物以及推荐的饮食选择。
Department(科室):指的是医疗体系内的各个专业部门,如内科负责内部疾病、外科处理外部创伤、妇科关注女性健康等。
Manufacturer(制造商):指的是药品的制造或生产单位,负责药物的研发和生产流程。
Check(检查):与疾病相关的医疗检查,如血检、X光等。
在知识图谱的构建中,实体间的联系被定义为关系。基于这些实体节点之间的关联性,可以将其归纳为以下几种主要类型的关系:
has_symptom(症状):疾病与症状之间的关系。
recommand_eating(推荐食谱):这一关系描述了疾病与应避免食用的食物之间的联系。
no_eating(忌吃):疾病与忌吃食物之间的关系。
do_eat(宜吃):这指代疾病与推荐食用的食物之间的关联。
belongs_to(属于):此关系涵盖了科室与其上级部门之间的关系,以及疾病与所属科室的联系。
common_drug(常用药品):这一术语描绘了疾病与常规使用的药品之间的关联性。
recommand_drug(好评药品):疾病与好评药品之间的关系。
need_check(诊断检查):疾病与相关检查之间的关系。
accompany_with(并发症):疾病与并发症之间的关系。
5.3.2 数据库逻辑设计
E-R图是实体和关系的概念模型,它可以被看作是一个多关系图,其中包含了多种类型的节点和边,以抽象的方式展现各种信息之间的关联。结合推荐系统,我们可以利用知识图谱来有效地过滤和推荐相关信息,为用户提供更加精准和个性化的服务。因此它比数学中的图论和数据库原理中的E-R图更具应用价值,但为了方便理解,这里还是用E-R图来描述逻辑关系。
而本数据库上述的各个实体之间的逻辑关系,将用E-R图表示如下:
图5-1 各实体节点和关系边E-R图
在这个E-R图中:
Disease是核心实体,代表各种疾病。而其他的实体都是从Disease实体出发,根据不同关系所联系的,这将会作为之后系统实现的关键逻辑依据。
与Disease相关的实体有:Food、Drug、Symptom、Check、Department和Producer。
实体之间的关系类型,包括recommand_eat、no_eat、do_eat、common_drug、has_symptom等。
图中的箭头表示关系的方向,实体之间通过关系链接。
此E-R图示例展示了节点之间的关联,并提供了对知识图谱结构的概念性理解。
6. 系统实现
6.1系统结构实现
基于知识图谱的可视化系统的实现涉及多个模块和技术组件结构:
数据获取与整合模块: 这个模块负责从medical.json数据集中分类出多个txt数据源并将这些txt文件数据整合到知识图谱数据库中。
知识图谱构建模块: 这个模块承载着知识图谱核心架构的创建职责,具体包括构建其数据层和模式层两大组件。在数据层面,它囊括了实体、各类关联关系以及属性信息的存储功能,为此,可以灵活运用图数据库技术(比如Neo4j这样的工具)来高效管理图形化的数据结构。而在模式层方面,它则专注于定义和规范本体的结构,确保知识图谱的逻辑性和一致性,可以使用本体描述语言(如OWL)来定义知识图谱的概念模型和关联关系。
可视化算法与界面模块: 这个模块负责设计和实现知识图谱的可视化算法和界面。可视化算法用于呈现知识图谱中的实体、属性和关系,可以使用D3.js等可视化库来实现图形化展示。界面设计包括用户友好的交互式探索界面,使用户能够自由地浏览和查询知识图谱,并能使用基于知识图谱的智能问答系统。
信息筛选与检索模块: 这个模块负责实现信息的筛选和检索功能,以满足用户不同的需求。
部署与管理模块: 这个模块负责系统的部署和管理,包括配置管理、权限控制、性能优化等。
6.2系统公用代码设计
6.2.1 知识图谱入库脚本
利用Python中的py2neo库函数,将医疗相关数据按照实体与关系的对应导入Neo4j图数据库,以构建一个医疗知识图谱。下面主要介绍入库脚本内容,及部分代码展示。
1. 构建知识图谱
整个脚本的核心目标是构建知识图谱,包括创建节点和关系。主要步骤如下:
读取数据:从medical.json文件读取医疗数据。
创建节点:将数据转化为知识图谱中的节点。
创建关系:根据数据中的信息,创建节点之间的关系。
导出数据:还可以将某些数据导出到文本文件,通过Neo4j图像数据库自带的导出功能。
2. 数据源
数据来自medical.json,存储在脚本所在目录的data文件夹中。每一行都是一个JSON格式的数据,包含有关医疗信息的各类字段,如疾病名称、症状、药品等。
3. Neo4j连接和初始化
通过py2neo库连接Neo4j图数据库。
MedicalGraph类初始化时,建立连接并配置访问权限。这里可以看到Neo4j的连接方式,以及用户名和密码等信息。代码如下所示:
def __init__(self):
cur_dir = '/'.join(os.path.abspath(__file__).split('/')[:-1])
self.data_path = os.path.join(cur_dir, 'data/medical.json')
'''self.g = Graph(
host="127.0.0.1", # neo4j 搭载服务器的ip地址,ifconfig可获取到
http_port=7474, # neo4j 服务器监听的端口号
user="neo4j", # 数据库user name,如果没有更改过,应该是neo4j
password="hzw147536928")'''
self.g=Graph("http://localhost:7474/", auth=("neo4j", "hzw147536928"), name='neo4j')
4. 节点和关系
数据主要涉及以下类型的节点:
药品 (Drug),食物 (Food),检查 (Check),科室 (Department),生产商 (Producer),疾病 (Disease),症状 (Symptom)
脚本从medical.json中读取数据,提取疾病的相关信息,然后将其转换为不同的节点和关系。
5. 创建节点
脚本中定义了两个主要方法用于创建节点:
create_diseases_nodes:根据疾病信息创建Disease节点,并附加相关属性,如描述、预防、原因等。
create_node:用于创建一般节点,传入节点标签和节点集合。
在这两个方法中,脚本使用self.g.create(node)将节点添加到Neo4j数据库中。
'''建立节点'''
def create_node(self, label, nodes):
count = 0
for node_name in nodes:
node = Node(label, name=node_name)
self.g.create(node)
count += 1
print(count, len(nodes))
return
'''创建知识图谱中心疾病的节点'''
def create_diseases_nodes(self, disease_infos):
count = 0
for disease_dict in disease_infos:
node = Node("Disease", name=disease_dict['name'], desc=disease_dict['desc'],
prevent=disease_dict['prevent'] ,cause=disease_dict['cause'],
easy_get=disease_dict['easy_get'],cure_lasttime=disease_dict['cure_lasttime'],
cure_department=disease_dict['cure_department']
,cure_way=disease_dict['cure_way'] , cured_prob=disease_dict['cured_prob'])
self.g.create(node)
count += 1
print(count)
return
'''创建知识图谱实体节点类型schema'''
def create_graphnodes(self):
Drugs, Foods, Checks, Departments, Producers, Symptoms, Diseases, disease_infos,rels_check, rels_recommandeat, rels_noteat, rels_doeat, rels_department, rels_commonddrug, rels_drug_producer, rels_recommanddrug,rels_symptom, rels_acompany, rels_category = self.read_nodes()
self.create_diseases_nodes(disease_infos)
self.create_node('Drug', Drugs)
print(len(Drugs))
self.create_node('Food', Foods)
print(len(Foods))
self.create_node('Check', Checks)
print(len(Checks))
self.create_node('Department', Departments)
print(len(Departments))
self.create_node('Producer', Producers)
print(len(Producers))
self.create_node('Symptom', Symptoms)
return
6. 创建关系
脚本使用create_relationship方法创建节点之间的关系。主要步骤包括:
根据关系数据,提取起始节点和结束节点的名称。
构建Cypher查询语句,使用match找到对应的节点,并创建关系。
处理可能的异常,确保脚本执行过程中不会因错误中断。代码如下:
'''创建实体关联边'''
def create_relationship(self, start_node, end_node, edges, rel_type, rel_name):
count = 0
# 去重处理
set_edges = []
for edge in edges:
set_edges.append('###'.join(edge))
all = len(set(set_edges))
for edge in set(set_edges):
edge = edge.split('###')
p = edge[0]
q = edge[1]
query = "match(p:%s),(q:%s) where p.name='%s'and q.name='%s' create (p)-[rel:%s{name:'%s'}]->(q)" % (
start_node, end_node, p, q, rel_type, rel_name)
try:
self.g.run(query)
count += 1
print(rel_type, count, all)
except Exception as e:
print(e)
return
7. 数据导出
该脚本中设置了从数据库中读出的数据导出为一个文本文件的export_data函数,用于调试或进一步分析。
8. 脚本的执行流程
脚本的执行流程主要包括:
初始化:将网页后端与neo4j数据库连接起来。
创建节点:使用create_graphnodes方法创建知识图谱中的各类节点实体。
创建关系:使用create_graphrels方法创建节点之间的关系类型。
9.入库成功后,登录neo4j数据库查看效果如下图:
6.3系统功能实现
系统整体模块及功能操作设计,首先后端连接至neo4j数据库,前端由三个网页构成。其中可以通过项目主页面选择跳转至智能问答界面和可视化界面两个子页面,两个子网页有其对应的功能,功能介绍详情请见第7章系统测试,整体模块如图所示:
系统整体操作图
6.3.1 数据库连接
首先安装好neo4j数据库(关于neo4j数据库的下载与配置参考以下文章neo4j详细安装教程(附下载地址)本文不再赘述)并配置环境,启动验证数据库是否安装成功。如图6-6所示:
neo4j的启动
然后在python中通过下述代码连接至neo4j数据库。
# 连接到Neo4j数据库
uri = "bolt://localhost:7687"
username = "neo4j"
password = "hzw147536928"
graph = Graph(uri, auth=(username, password))
6.3.2首页
首页界面简单明了,当用户进入首页后可以通过首页界面中的‘可视化界面’和‘智能问答系统’两个链接,根据自己的需求进行跳转。
6.3.3可视化界面
当用户在主页面点击‘可视化界面’链接后将跳转到可视化界面网页页面,如下图所示:
可视化界面
在该界面中,会根据用户输入的疾病关键词去neo4j数据库搜素对应的相关节点,进一步检索关系边。以下是对疾病关键词的非递归检索的逻辑代码:
def non_recursive_query(source, n, links):
stack = [(source, n)]
visited = set() # 记录已经访问过的节点
while stack:
current_node, depth = stack.pop()
# 如果当前节点已经访问过或者达到了指定的深度,直接跳过
if current_node in visited or depth <= 0:
continue
# 执行查询
query = f"""
MATCH (n {{name: '{current_node}'}})-[r]->(m)
RETURN n.name AS source, type(r) AS rela, m.name AS target
"""
result = graph.run(query)
# 将当前节点标记为已访问
visited.add(current_node)
for record in result:
if len(links) >= Max_num:
break # 达到最大节点数,跳出循环
target = record["target"]
links.append({
"source": current_node,
"rela": record["rela"],
"target": target
})
stack.append((target, depth - 1))
return links
6.3.4 智能问答系统
用户在首页点击‘智能问答系统’链接后跳转到智能问答系统网页,如图6-9所示。
智能问答系统界面
智能问答系统框架图如下:
智能问答系统框架
在该系统中,会先对用户输入的内容进行问句过滤,并构造actree加速过滤,构造actree代码,如下所示:
'''构造actree,加速过滤'''
def build_actree(self, wordlist):
actree = ahocorasick.Automaton()
for index, word in enumerate(wordlist):
actree.add_word(word, (index, word))
actree.make_automaton()
return actree
接着收集问句中所涉及到的实体类型,例如对疾病类分类:
'''分类主函数'''
def classify(self, question):
data = {}
medical_dict = self.check_medical(question)
if not medical_dict:
return {}
data['args'] = medical_dict if medical_dict else {}
#收集问句当中所涉及到的实体类型
types = []
for type_ in medical_dict.values():
types += type_
question_type = 'others'
question_types = []
# 症状
if self.check_words(self.symptom_qwds, question) and ('disease' in types):
question_type = 'disease_symptom'
question_types.append(question_type)
if self.check_words(self.symptom_qwds, question) and ('symptom' in types):
question_type = 'symptom_disease'
question_types.append(question_type)
# 原因
if self.check_words(self.cause_qwds, question) and ('disease' in types):
question_type = 'disease_cause'
question_types.append(question_type)
# 并发症
if self.check_words(self.acompany_qwds, question) and ('disease' in types):
question_type = 'disease_acompany'
question_types.append(question_type)
# 推荐食品
if self.check_words(self.food_qwds, question) and 'disease' in types:
deny_status = self.check_words(self.deny_words, question)
if deny_status:
question_type = 'disease_not_food'
else:
question_type = 'disease_do_food'
question_types.append(question_type)
#已知食物找疾病
if self.check_words(self.food_qwds+self.cure_qwds, question) and 'food' in types:
deny_status = self.check_words(self.deny_words, question)
if deny_status:
question_type = 'food_not_disease'
else:
question_type = 'food_do_disease'
question_types.append(question_type)
# 推荐药品
if self.check_words(self.drug_qwds, question) and 'disease' in types:
question_type = 'disease_drug'
question_types.append(question_type)
# 药品治啥病
if self.check_words(self.cure_qwds, question) and 'drug' in types:
question_type = 'drug_disease'
question_types.append(question_type)
# 疾病接受检查项目
if self.check_words(self.check_qwds, question) and 'disease' in types:
question_type = 'disease_check'
question_types.append(question_type)
# 已知检查项目查相应疾病
if self.check_words(self.check_qwds+self.cure_qwds, question) and 'check' in types:
question_type = 'check_disease'
question_types.append(question_type)
# 症状防御
if self.check_words(self.prevent_qwds, question) and 'disease' in types:
question_type = 'disease_prevent'
question_types.append(question_type)
# 疾病医疗周期
if self.check_words(self.lasttime_qwds, question) and 'disease' in types:
question_type = 'disease_lasttime'
question_types.append(question_type)
# 疾病治疗方式
if self.check_words(self.cureway_qwds, question) and 'disease' in types:
question_type = 'disease_cureway'
question_types.append(question_type)
# 疾病治愈可能性
if self.check_words(self.cureprob_qwds, question) and 'disease' in types:
question_type = 'disease_cureprob'
question_types.append(question_type)
# 疾病易感染人群
if self.check_words(self.easyget_qwds, question) and 'disease' in types :
question_type = 'disease_easyget'
question_types.append(question_type)
# 若没有查到相关的外部查询信息,那么则将该疾病的描述信息返回
if question_types == [] and 'disease' in types:
question_types = ['disease_desc']
# 若没有查到相关的外部查询信息,那么则将该疾病的描述信息返回
if question_types == [] and 'symptom' in types:
question_types = ['symptom_disease']
# 将多个分类结果进行合并处理,组装成一个字典
data['question_types'] = question_types
return data
接下来的实体类型以此类推。下表为部分问答的类型实例:
表6-1 支持问答类型
最近老流鼻涕怎么办? 最近老流鼻涕怎么办? | ||
疾病病因接着收集问句中所涉及到的实体类型,例如对疾病类分类: | 为什么有的人会失眠? 为什么有的人会失眠? 为什么有的人会失眠? | |
Disease_accompany | ||
肝病要吃啥药? 鹅肉有什么好处? 肝病要吃啥药? | ||
药品能治啥病 药品能治啥病 药品能治啥病 | ||
高血压 |
7. 测试背景及方法
项目名称:基于知识图谱可视化系统的设计与实现。
软件系统以Python为开发工具,选择Neo4j图形数据库来支撑其后端数据的存储与处理。 在测试计划的制定阶段:详细规划了测试的进度安排。
进入测试设计阶段:我们严格依据程序设计文档,采用一套标准化的流程来划分软件结构,并基于此精心构造测试用例,旨在保障测试活动的有效性和精确性。
在测试执行环节:输入了先前设计的测试用例,并获得了相应的测试结果。
在测试总结阶段:将实际测试结果与代码的预期输出进行了对比,对任何差异进行了深入剖析,以识别错误的根源,并采取适当措施来定位并修复这些错误。
7.1 测试过程
7.1.1 测试首页跳转功能
测试系统首页跳转功能,即点击对应链接能跳转对应网页页面。效果可见前图6-4,6-5所示,可以正常跳转功能正常。
7.2 测试过程
7.2.1 测试首页跳转功能
测试系统首页跳转功能,即点击对应链接能跳转对应网页页面。效果可见前图6-4,6-5所示,可以正常跳转功能正常。
7.2.2 智能问答系统模块测试
测试系统的智能问答系统,就是看系统能否对用户提出的问答做出正确的反馈。即对用户的问题如果能够回答,给出对应回答。如果无法回答,则依然给出无法回答的反馈。
同时本项目的创新点为将医疗小助手与可视化界面联合起来,而不是使两个系统孤立开来。医疗小助手回答中会将系统中储存的疾病关键词标红,用户可以提供点击任意标红疾病超链接跳转至可视化界面,并直接生成对应的知识图谱。
测试的输入和输出举例。
表7-1 智能问答测试用例设计
案例 | 应产生行为 | 结果 |
输入问题:肾虚吃什么好 | 给出正确的反馈,即回答肾虚吃什么好 | 成功 |
输入问题:头疼 | 问题不详细,无法回答,给出无法回答的反馈 | 成功 |
输入问题:小儿血清病 | 给出正确反馈,即介绍小儿血清病是什么 | 成功 |
输入问题:维生素C注射液能治啥病? | 介绍维生素C注射液能治的疾病 | 成功 |
1)输入--肾虚吃什么好。输出--肾虚宜食的食物包括有:鹌鹑蛋;鸡心;芝麻;鹿肉 推荐食谱包括有:红烧五花肉;猪肉青菜粥;小白菜猪肉饺;百合炒西兰花;香卤鹌鹑蛋;腰果西兰花;鸳鸯鹌鹑蛋;卤五花肉。测试结果如图7-1所示。
2)输入--头疼。输出--您好,我是医药智能助理,希望可以帮到您。如果没答上来,可以试着将问题提问更详细一些。祝您身体棒棒!测试结果如图7-2所示。
3)输入--小儿血清病。输出--小儿血清病,小儿血清病宜食的食物包括有:腰果;鸡肉;芝麻;南瓜子仁 推荐食谱包括有:猕猴桃西米粥;木瓜鲜奶饮;草莓菠菜汁;草莓西瓜汁;猕猴桃西芹汁;木瓜胡萝卜玉米粥;双菇番茄黄瓜紫菜汤;紫菜芙蓉汤,测试结果如图7-3所示。
4)输入--维生素C注射液能治啥病?输出--维生素C注射液主治的疾病有烧伤休克;酸碱
灼伤;眼内异物;小儿烧伤;眼酸碱化学伤;克山病;眼球破裂伤;铁中毒;眼烧伤;头
皮及颅骨烧伤;眼球内陷;心源性休克;爆裂性眼眶骨折;晶体脱位;紫外线伤;咽喉烧
伤及化学伤;眼外肌外伤;咽部灼伤;眼异物伤;眼眶血肿,可以试试。
图7-1 测试结果
图7-2 测试结果
图7-3 测试结果
图7-4 测试结果
在图7-4结果中,点击咽喉痛疾病关键词将打开一个以咽喉痛为疾病关键词所生成的知识图谱。
如图7-5所示。
图7-5 测试结果
图7-5-1 细节图
关于其中可视化界面知识图谱的操作将在下一个小结详细介绍。
7.2.3 可视化界面模块测试
测试系统的可视化界面,就是看系统能否对用户所输入的关键词生成相对应的知识图谱。可视化界面对疾病关键词的应用不仅可以通过智能医疗小助手回答中的超链接部分生成相应的知识图谱,也可以直接在该界面搜索框输入疾病关键词生成。同时,知识图谱中所有的节点都可以进行单击,双击,拖拽的互动。
测试系统的可视化界面,就是看系统能否对用户所输入的关键词生成相对应的知识图谱。可视化界面对疾病关键词的应用不仅可以通过智能医疗小助手回答中的超链接部分生成相应的知识图谱,也可以直接在该界面搜索框输入疾病关键词生成。同时,知识图谱中所有的节点都可以进行单击,双击,拖拽的互动。
图7-6 搜索框及可操作关系按钮展示
测试的输入和输出举例,如下表所示:
表7-2 可视化界面测试用例设计
案例 | 应产生行为 | 结果 |
在‘输入疾病搜素词’框输入感冒 | 生成与感冒相应的知识图谱 | 成功 |
‘输入疾病搜素词’框输入为空 | 系统提示‘请填写此字段’ | 成功 |
生成对应知识图谱后,选择‘acompany_with’关系按钮,显示其对应关系边 | 正确显示‘acompany_with’关系边,并隐藏其他关系边及无关节点。 | 成功 |
生成对应知识图谱后,选择‘belong_to’关系按钮,显示其对应关系边 | 正确显示‘belong_to’关系边,并隐藏其他关系边及无关节点。 | 成功 |
生成对应知识图谱后,选择‘do_eat’关系按钮,显示其对应关系边 | 正确显示‘do_eat’关系边,并隐藏其他关系边及无关节点。 | 成功 |
单击‘感冒’节点,将鼠标光标至于‘感冒’节点上,然后双击该节点 | 单击‘感冒’节点后将会标红与该节点直接相连的关系边;鼠标光标置于‘感冒’节点上将会提示悬浮窗‘双击了解详情’;双击后将跳转至‘感冒’的百科介绍。 | 成功 |
- 输入--感冒。输出--显示‘感冒’对应的知识图谱。且右上角实时显示当前知识图谱中的节点数量和关系边数量,为了网页的使用效果及用户的体验,本项目将展示的最大关系边数设置为200,超出200的部分将不再显示。测试结果如图7-7所示。
- 输入--空。输出--显示‘请填写此字段’。测试结果如图7-8所示。
- 点击‘acompany_with’关系按钮。显示‘acompany_with’关系边,并隐藏其他关系边与无关的节点。测试结果如图7-9所示。
- 点击‘belong_to’关系按钮。显示‘belong_to’关系边,并隐藏其他关系边与无关的节点。测试结果如图7-10所示。
- 点击‘do_eat’关系按钮。显示‘do_eat’关系边,并隐藏其他关系边与无关的节点,其他关系按钮效果可参考上述的测试结果,在此不再一一展示。测试结果如图7-11所示。
- 单击‘感冒’节点后将会标红与该节点直接相连的关系边;鼠标光标置于‘感冒’节点上将会提示悬浮窗‘双击了解详情’;双击后将跳转至‘感冒’的百科介绍。测试结果下图所示,百科资料如图7-12所示。
图7-7
图7-8
图7-9
图7-10
图7-11
图7-12 双击‘感冒’节点结果
7.2.4 导航栏功能模块测试
1)智能问答系统导航栏返回主页测试,点击后跳转回主页面。测试结果如图6-1所示。
2)智能问答系统导航栏登录数据库测试,点击后转到neo4j后端数据库界面,登录后可对后端数据进行操作。测试结果如图7-13所示。
图7-13 数据库
3)智能问答系统导航栏关于栏测试,点击后弹窗关于系统的介绍。测试结果如图7-14所示。
图7-14 关于
4)在可视化界面的导航栏部分,所设计的测试用例与智能问答系统导航栏的测试用例在结构和目的上具有一定的相似性。因此,在进行具体测试时,建议参考智能问答系统导航栏的测试用例,以确保测试的全面性和准确性。
图7-15 特点