乐趣区

关于人工智能:基于Brat标注数据集的python包network网络构建和搜索

@TOC

一、前言

  在常识图谱的文本标注工作中,须要将数据依照当时决定的标注规定进行人工标注。Brat 是一种比拟驰名的标注工具,然而目前不反对 Windows 零碎,你能够装置虚拟机应用该工具。本文曾经实现了一项基于 Windows、Python3.7 的标注软件制作工作,你能够点击 实体关系文本标注工具 进行查看。

  假使你是应用的 Brat 标注工具, 并且对于 Neo4j 图数据库不是很相熟,那你能够思考应用 Python 中的 network 第三方库,在初步学习阶段实现 demo,在下一篇文章中,将会介绍 Neo4j 的应用案例。

  本文将应用 Brat 工具标注的数据集,利用 network 第三方库构建图网络,并且实现对节点的多级检索。

二、数据筹备

  本文从知网下载了一些对于医学文章的摘要,提前设置了标注规定,例如实体类别、关系等。通过 Brat 工具标注该文本数据并失去输入标注好的后果文件,该文件共有 1314 行,以 T 结尾示意实体,以 R 结尾示意关系,该文件是对网络图构造的文本表述。

三、网络构建

1、筹备好一些必备的包,本文应用的是 python3.7 版本。

import re
import networkx as nx
import matplotlib.pyplot as plt
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei'] #显示中文 

2、读取数据

txtfile = open(r'E:\ 数据 \1-70.ann', 'r', encoding='utf-8').readlines()
# print(txtfile[:3])

3、将文件中的实体、关系辨别开

# 将实体与关系数据离开
entity = []
relation = []
for i in txtfile:
    if i[0] == 'T':
        entity.append(i)
    else:
        relation.append(i)

# print(relation)

#将实体名称、类别与编号提取进去
entity = [i.strip('\n').split('\t') for i in entity]
entity = [[i[0],i[1].split(' ')[0], i[-1]] for i in entity]
# print(entity[:5])
#在实体表中插入数据
# #提取实体名,去重; 须要提前查看数据库已有的实体名称 须要表名称
entitymin = [i[-1] for i in entity]
entitymin = list(set(entitymin))
# print(entitymin[:5])

4、利用辨别开的实体、关系,将三元组提取进去,构建三元组。

# 将三元组提取进去
relation = [re.split("[\tA:' ']",i) for i in relation]
relation = [[i[1],i[4],i[7]] for i in relation]
# print(relation[:5])

dicen = dict([('病症',1),('病名',2),('诊断计划',3),('医治计划',4),('药名',5),('其它',6)])
dicre =  dict([('蕴含',1),('医治',2),('危险因素',3),('辅助诊断',4),('特色',5),('并发',6),('别名',7),('作用',8),('条件',9)])
# print(dicre['蕴含'])

# #将三元组中的实体编号替换成实体名称
for r in relation:
    # r[0] = dicre[r[0]]
    for e in entity:
        if r[1] == e[0]:
            r[1] = e[-1]
            # r.insert(0,e[1])
        if r[-1] == e[0]:
            r[-1] = e[-1]
            # r.append(e[1])
    r.append(r[0])
# print(relation[:5])
relation = [tuple(r[1:]) for r in relation]
# print(relation[:5])
lista = []
for i in relation:
    if i[-1] == '别名':
        lista.append([i[1], i[0], i[-1]])
relation += lista
# print(lista)
# print(relation[:5])

5、利用 network 绘制图网络,并且将图网络保留到本地。

plt.figure(3, figsize=(48, 27)) # 这里管制画布的大小,能够说扭转整张图的布局
plt.subplot(111)
M = nx.DiGraph()
M.add_weighted_edges_from(relation) 
    #传入数据, 格局 [('甲状腺疾病', '甲状腺性能亢进症', '蕴含'), ('甲状腺疾病', '甲状腺性能减退', '蕴含')]
edge_labels = nx.get_edge_attributes(M, 'weight') #取出实体之间的关系
pos =  nx.random_layout(M)
# pos = nx.spring_layout(G, iterations=30) #设置画图的款式
nx.draw(M, pos,edge_color="grey", node_size=80) #设置点的地位
nx.draw_networkx_edge_labels(M,pos, edge_labels=edge_labels, font_size=10) #边的格局设置
nx.draw(M,pos, node_size=120, with_labels=True,font_size = 10) #节点设置
plt.savefig("imag.png")
plt.show()

生成后果,主动保留在本地,须要放大观看:

四、多级节点搜寻

基于下面第 5 步绘制的网络,接下来本文须要从这个网络中,对感兴趣的节点和邻近节点,以及邻近节点的邻近节点到任意深度的节点进行检索。

1、定义查找函数

def get_neigbors(g, node, depth=1):
    output = {}
    output1 = []
    layers = dict(nx.bfs_successors(g, source=node, depth_limit=depth))
    nodes = [node]
    for i in range(1,depth+1):
        output[i] = []
        for x in nodes:
            output[i].extend(layers.get(x,[]))
            output1.extend(layers.get(x,[]))
        nodes = output[i]
    print('这是节点:',output)
    return output1##print(get_neigbors(M, '990', depth = 4))#[23,12,14,23,45,65,78]
def newlist(M, a, alist):
    alist.insert(0,a)
    newlistcon = list()
    for index, name in enumerate(alist[:-1]):
        for name1 in alist[index+1:]:
            if M.get_edge_data(name,name1) != None:
                relation = M.get_edge_data(name,name1)['weight']
                newlistcon.append([name, name1, relation])
    lista = []
    for i in newlistcon:
        if i[-1] == '别名':
            lista.append([i[1], i[0], i[-1]])
    newlistcon += lista
    return newlistcon#print('这是新数据',newlist(M, '990', get_neigbors(M, '990', depth = 4)))

2、设置查找参数,例如:查找以“甲状腺疾病”节点,并且设置深度为 2,返回所有与甲状腺疾病为邻近节点的节点,以及该邻近节点的邻近节点。

node,depth = '甲状腺疾病',2

3、绘图展现和后果输入

liststrnewcon = newlist(M, node, get_neigbors(M, node, depth = depth))
G = nx.DiGraph()
plt.figure(3, figsize=(32,18)) # 这里管制画布的大小,能够说扭转整张图的布局
plt.subplot(111)
G.add_weighted_edges_from(liststrnewcon) #传入数据
edge_labels = nx.get_edge_attributes(G, 'weight') #取出实体之间的关系
# pos = nx.spring_layout(G, iterations=30) #设置画图的款式
pos =  nx.random_layout(G)
# pos = nx.spectral_layout(G)

nx.draw(G, pos,edge_color="grey", node_size=80) #设置点的地位
nx.draw_networkx_edge_labels(G,pos, edge_labels=edge_labels, font_size=15) #边的格局设置
nx.draw(G,pos, node_size=1500,node_color = 'skyblue',node_shape = 's', with_labels=True,font_size = 15,edge_color = 'red') #节点设置
plt.savefig("imag_jia1.png")
plt.show()

对检索后果生成网络图,主动保留本地,不便放大观看:

输入后果:

这是节点:{1: [‘ 甲状腺性能亢进症 ’, ‘ 甲状腺性能减退 ’, ‘ 甲状腺炎 ’, ‘ 咽异样感觉 ’, ‘ 脏器 ’, ‘Graves 病 ’, ‘ 桥本甲状腺炎 ’, ‘ 甲状腺性能减退症 ’, ‘ 本身免疫性甲状腺疾病 ’, ‘ 许特莱细胞瘤 ’, ‘ 甲状腺腺瘤 ’, ‘ 结节性甲状腺肿 ’, ‘ 甲状腺囊性变病 ’, ‘ 甲状腺性能 ’, ‘ 甲状腺过氧化物酶抗体 ’, ‘TPOAb’, ‘ 甲状腺球蛋白抗体 ’, ‘TGAb’, ‘ 甲状腺瘤 ’, ‘ 原发性甲状腺机能亢进症 ’, ‘ 甲状腺癌 ’, ‘ 甲状腺良性疾病 ’, ‘ 咽异感症 ’, ‘TRAb’, ‘TMAb’, ‘ 桥本病 ’, ‘ 甲亢 ’, ‘ 桥本 ’, ‘ 甲减 ’, ‘ 早期妇女 ’, ‘ 妊娠中 ’, ‘ 孕中晚期 ’, ‘ 桥本氏甲状腺炎 ’, ‘ 单纯性甲状腺肿 ’, ‘ 甲状腺乳头状癌 ’, ‘ 甲状腺恶性肿瘤 ’, ‘ 重症肌无力 ’, ‘MG’], 2: [‘ 急性化脓性甲状腺炎 ’, ‘ 亚急性甲状腺炎 ’, ‘ 慢性淋巴细胞性甲状腺炎 ’, ‘ 甲状腺上皮细胞 ’, ‘AITD’, ‘ 钙化 ’, ‘ 砂粒体 ’, ‘ 肿瘤样病变 ’, ‘ 甲状腺性能异样 ’, ‘TPO-Ab’, ‘ 原发性甲减 ’, ‘ 甲状腺结节 ’, ‘ 多灶性癌 ’, ‘ 乳头状腺癌 ’, ‘ 滤泡癌 ’, ‘ 未分化和癌髓样癌 ’, ‘ 乳头状癌 ’, ‘TSH 受体抗体 ’, ‘ 甲状腺微粒体抗体 ’, ‘ 特异性抗体 ’, ‘ 病率较高 ’, ‘TSH’, ‘FT3’, ‘FT4’, ‘LP(a)’, ‘ 血脂 ’, ‘CHO’, ‘LDL’, ‘ApoB’, ‘ 亚临床甲亢 ’, ‘ 甲状腺性能亢进 ’, ‘ 亚临床甲减 ’, ‘ 腺瘤 ’, ‘ 渺小乳头状癌 ’]}

五、残缺我的项目数据和代码

以下形式均可:
1、私信留言、文末评论你的邮箱,博主定期回复。
2、点击:GitHub-network 进行下载(或者拜访:https://github.com/chenyiadam/network.git)

本文由 mdnice 多平台公布

退出移动版