趁热打铁,再构建百万节点关系中医药方剂知识图谱

趁热打铁,再构建百万节点关系中药方剂知识图谱

前文自顶向下构建中药知识图谱初探中,已经介绍了知识图谱和中药知识图谱构建的相关基础概念,本文将研究中药方剂数据,趁热打铁,再构建百万节点关系中药方剂知识图谱。该图谱能够让中医药知识图谱更加完善与全面。详细内容请看全文。


@


1、中药方剂

每味中药都有自己的功效特色,古人很早就使用单味药物治疗疾病,但是在漫长的实践过程中发现合理应用中药配伍,能够起到事半功倍的良好效果。方剂学是研究中医方剂组成、变化和临床运用规律的一门学科,是中医学的主要基础学科之一,方剂学的内容包括方剂的组成原则、药物的配伍规律、方剂的组成变化、剂型及方剂的用法等。
本文将基于收集的方剂数据,利用自然语言处理技术构建中药方剂知识图谱,并分析中药处方中的一些数据规律。

2、构建中药方剂知识图谱

2.1 中药方剂实体与关系定义

本文主要从中药方剂处方组成和功能主治的角度抽取相关信息,构建知识图谱。具体实体和关系描述如下:
实体定义:方剂(root节点)、方名、来源、别名、处方、中药名、剂量、功能主治。
关系定义:<方剂, include, 方名>、<方名, from, 来源>、<方名, another name, 别名>、<方名, prescription type, 处方_id>、<处方_id, composition, 中药名>、<中药名, dose, 剂量>和<处方_id, functions, 功能主治>。

prescription type关系说明:由于历代诸多医家的研究与发展,方剂存在同名的情况,因此prescription type关系的尾节点利用“处方_id”标识同名的多个处方。如:“当归散”有207个处方,“白术散”有170个处方,“羚羊角散”有169个处方。

说明:该实体和关系的定义旨在学习知识图谱在中医药数据中的应用与处理,仅限自己初步研究,具体应用需根据实际情况调整。

另外,组成方剂的药物可按其在方剂中所起的作用分为君、臣、佐、使;组方存在十八反和十九畏关系;中药有四气五味性状等。因此,后续可在已有方剂知识图谱基础上,继续对方剂数据进行融合处理,构建完善最终的中药方剂知识图谱

2.2 方剂数据获取与分析

本文将基于收集的2.5w组共计5.2w个中药处方数据,主要利用规则和词典抽取2.1节中描述的实体关系三元组,构建中药方剂知识图谱。

方剂与处方个数简单分析结果
(1)单个处方的方剂共计19023组,占比76.1%;含有2个或3个处方的方剂共计3896组,占比15.6;含有4-10个处方的方剂共计1355组,占比5.4%;含有11-30个处方的方剂共计446个,占比1.8%。
(2)含有处方个数最多的10个方剂名分别是:当归散、白术散、羚羊角散、槟榔散、黄耆散、黄耆汤、黄连散、柴胡散、茯苓汤和当归汤。
(3)含有“当归散”的方名有21组,具体图谱如图1所示。
图1 含有“当归散”的方名图谱

图1 含有“当归散”的方名图谱
 

处方与用药数量简单分析结果:
(1)5.2万个处方中10味以内的处方有40596个,占比78.1%,含有11-15味中药的处方共计8217个,占比15.8%。可见,有人说中药处方用药超过10味大多是胡扯的论断也有一定道理,哈哈哈。不过需要说明的是中药处方与病情发展和医生经验密切相关,不可呆板照搬经典,一尘不变的开方治病。
(2)用药数量最多的方剂是“金仙膏”,一个处方有109味中药,另一个处方有108味中药。两个“金仙膏”的处方图谱如图2所示。
图2 两个“金仙膏”的处方图谱

图2 两个“金仙膏”的处方图谱
 

两个“金仙膏”的功能主治图谱如图3所示。
图3 两个“金仙膏”的功能主治图谱

图3 两个“金仙膏”的功能主治图谱
 

感兴趣的可以分析对比这两个处方。
 

2.3 构建中药方剂知识图谱

本文通过py2neo将数据存入neo4j数据库,并进行可视化展示。

demo如下:


import json
from py2neo import Graph, Node, Relationship


def generateGraph_Node(graph, label, name):
    """
        创建知识图谱节点
    :param graph: Graph()
    :param label: 节点label
    :param name: 节点name
    :return:
    """

    node = Node(label, name=name)
    graph.create(node)

    return node


def generateGraph_Relation(graph, node_1, relation, node_2):
    """
        连接知识图谱关系
    :param graph:Graph()
    :param node_1: 头实体节点
    :param relation: 关系
    :param node_2: 尾实体节点
    :return:
    """

    r = Relationship(node_1, relation, node_2)
    graph.create(r)


def create_graph_fangji():
    """
        创建中药方剂知识图谱,在neo4j中进行可视化
    :return:
    """

    # === 连接知识图谱
    connect_graph = Graph("http://localhost:7474", auth=("neo4j", "123456"))

    # === 加载节点数据,创建节点
    # 创建关系时索引节点
    dict_nodes = {}  # key: 节点lable\tname, value:生成的图节点
    with open("./data_fangji/nodes_fangji.txt", "r", encoding="utf-8") as fr_n:
        for line in fr_n.readlines():
            line = line.strip()
            lable, name = line.split("\t")
            # 创建节点
            node = generateGraph_Node(connect_graph, lable, name)
            dict_nodes[line] = node

    # === 加载关系数据
    with open("./data_fangji/relations_fangji.json", "r", encoding="utf-8") as fr_r:
        for ele in json.load(fr_r):
            node_1 = ele["node_1"]
            relation = ele["relation"]
            node_2 = ele["node_2"]
            node_1_g = dict_nodes[node_1]
            node_2_g = dict_nodes[node_2]
            # 创建关系
            generateGraph_Relation(connect_graph, node_1_g, relation, node_2_g)


if __name__ == '__main__':
    create_graph_fangji()
    pass

demo数据和代码地址:
https://github.com/fengxi177/Knowlegde_Graph_TCM

https://gitee.com/fengxi177/Knowlegde_Graph_TCM
 

3、中药方剂知识图谱数据展示

本文共计生成中药方剂节点标签8类215987个,关系类型7类793514个。存入neo4j中的中药知识图谱概况如图4所示。
图4 中药方剂知识图谱数据概述

图4 中药方剂知识图谱数据概述
 

图5 6000关系中药方剂知识图谱局部可视化效果(缩略图)

图5 6000关系中药方剂知识图谱局部可视化效果(缩略图)
 
该图谱svg格式获取地址: https://github.com/fengxi177/Knowlegde_Graph_TCM/blob/main/fangji/img_svg/
 

相较于前文从中药性能和中药功效角度构建的中药知识图谱,方剂知识图谱更加复杂,节点关系呈现的知识也更加丰富。后续对齐两份知识图谱之间的属性关系,将联通中药和方剂知识,呈现更完整的中药知识图谱。特别的,领域数据特别是医疗数据对齐,由于其特殊应用性,更应该关注背景知识,而不能仅仅从nlp视角利用方法对齐。
其他主要关系图谱已在前后文进行展示,此处主要补充100组来源关系中药方剂知识图谱可视化结果如图6。

MATCH p=()-[r:from]->() RETURN p LIMIT 100

图6 100来源关系中药方剂知识图谱可视化结果

图6 100来源关系中药方剂知识图谱可视化结果
 

以上就是本文所构建中药方剂知识图谱的部分可视化结果。
 

4、问题发现

有了数据,完成初步的知识图谱构建是比较便捷的,当然也会发现不少问题。该部分将主要介绍发现的2类问题,以便于后续图谱优化与注意。

4.1 节点关系定义问题

当打算利用2级关系查询“金仙膏”的组方和剂量情况时发现了如图7中的问题,即同一中药包含极多的剂量,这无法确定处方中的具体剂量情况。因此,2.1节中单纯的<中药名, dose, 剂量>关系无法准确表达确定处方的中药与剂量关系。为此,简单的,或许可再增加剂量与处方id之间的关系<处方_id, prescription dose, 剂量>。这样,dose关系能够从剂量角度发现用药情况,prescription dose关系能够确定关联处方的剂量单位。

图7两级关系查询语法如下:

MATCH (n:`处方`)-[r:composition]->(n2:`中药名`) where n.name contains "金仙膏"  with n, r, n2 match (n2:`中药名`)-[r2:dose]->(n3:`剂量`) RETURN n, r, n2, r2, n3 LIMIT 500

图7 两级关系查询“金仙膏”组方和剂量知识图谱部分可视化结果

图7 两级关系查询“金仙膏”组方和剂量知识图谱部分可视化结果
 

4.2 知识融合问题

如图6所示,中医药资料丰富,有很多来源。当构建一定数量节点关系的图谱后,会发现同一实体或关系的表达变化多样,且中医药中的用词有其领域性和特殊性,发掘一种能够恰到好处的中医药知识融合方法将会极大的提升相关知识图谱的质量。
 

5、总结

本文基于多个来源的中药方剂数据,构建了一份有21.6w节点和79.4w关系的中药方剂知识图谱,并结合知识图谱对方剂数据进行了简单的分析与可视化展示。同时就当前构建过程中发现的问题进行了分析。希冀通过不断迭代修改,能够让中医药知识图谱更加完善与全面,发掘有价值的信息。


欢迎关注公众号:实用自然语言处理
欢迎关注公众号:实用自然语言处理


主要参考文献
[1] https://baike.baidu.com/item/中药方剂/4844485?fr=aladdin



原文首发于微信公众号:实用自然语言处理

posted @ 2022-12-06 16:37  风兮177  阅读(807)  评论(0编辑  收藏  举报