趁熱打鐵,再構建百萬節點關係中醫藥方劑知識圖譜

2022-12-06 18:00:35

趁熱打鐵,再構建百萬節點關係中藥方劑知識圖譜

前文自頂向下構建中藥知識圖譜初探中,已經介紹了知識圖譜和中藥知識圖譜構建的相關基礎概念,本文將研究中藥方劑資料,趁熱打鐵,再構建百萬節點關係中藥方劑知識圖譜。該圖譜能夠讓中醫藥知識圖譜更加完善與全面。詳細內容請看全文。


@


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)5.2萬個處方中10味以內的處方有40596個,佔比78.1%,含有11-15味中藥的處方共計8217個,佔比15.8%。可見,有人說中藥處方用藥超過10味大多是胡扯的論斷也有一定道理,哈哈哈。不過需要說明的是中藥處方與病情發展和醫生經驗密切相關,不可呆板照搬經典,一塵不變的開方治病。
(2)用藥數量最多的方劑是「金仙膏」,一個處方有109味中藥,另一個處方有108味中藥。兩個「金仙膏」的處方圖譜如圖2所示。

圖2 兩個「金仙膏」的處方圖譜
 

兩個「金仙膏」的功能主治圖譜如圖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 中藥方劑知識圖譜資料概述
 

圖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來源關係中藥方劑知識圖譜視覺化結果
 

以上就是本文所構建中藥方劑知識圖譜的部分視覺化結果。
 

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 兩級關係查詢「金仙膏」組方和劑量知識圖譜部分視覺化結果
 

4.2 知識融合問題

如圖6所示,中醫藥資料豐富,有很多來源。當構建一定數量節點關係的圖譜後,會發現同一實體或關係的表達變化多樣,且中醫藥中的用詞有其領域性和特殊性,發掘一種能夠恰到好處的中醫藥知識融合方法將會極大的提升相關知識圖譜的質量。
 

5、總結

本文基於多個來源的中藥方劑資料,構建了一份有21.6w節點和79.4w關係的中藥方劑知識圖譜,並結合知識圖譜對方劑資料進行了簡單的分析與視覺化展示。同時就當前構建過程中發現的問題進行了分析。希冀通過不斷迭代修改,能夠讓中醫藥知識圖譜更加完善與全面,發掘有價值的資訊。



歡迎關注公眾號:實用自然語言處理


主要參考文獻
[1] https://baike.baidu.com/item/中藥方劑/4844485?fr=aladdin



原文首發於微信公眾號:實用自然語言處理