1 导包
# please run pip install sklearn-crfsuite in your environment
#导入数据分析所需的基础包
import pandas as pd
import numpy as np
import os
#包tqdm是用来对可迭代对象执行时生成一个进度条用以监视程序运行过程
from tqdm import tqdm
#导入训练集测试集划分的包
from sklearn.model_selection import train_test_split
#导入CRF模型所需的包
from sklearn_crfsuite import CRF
#导入模型评估所需的包
from sklearn_crfsuite import metrics
2 读取数据
数据保存在data/目录下,data/目录下共有四个文件夹,分别对应四种医学情景:出院情况、病史特点、诊疗过程和一般项目。每个文件夹下保存了该情景下的电子病历。包括两类文件:‘xxx-yyy.txtoriginal.txt’和’xxx-yyy.txt’。'xxx-yyy.txtoriginal.txt’保存了xxx情境下第yyy号病历的病历文本,保存在txt的第一行中。'xxx-yyy.txt’为其对应的标签数据。
数据中共包含5种实体:治疗、身体部位、疾病和诊断、症状和体征、检查和检验。
#读取一个病历文本数据,并查看其内容。
with open('data/一般项目/一般项目-1.txtoriginal.txt') as f:
content = f.read().strip()
print(content)
女性,88岁,农民,双滦区应营子村人,主因右髋部摔伤后疼痛肿胀,活动受限5小时于2016-10-29;11:12入院。
#读取上述病历对应的标签数据
with open('data/一般项目/一般项目-1.txt') as f:
content_label = f.read().strip()
print(content_label)
右髋部 21 23 身体部位
疼痛 27 28 症状和体征
肿胀 29 30 症状和体征
可以看出,标签文件的数据格式为每行对应一个实体,每行格式为“实体内容 实体在文本中的开始位置 实体在文本中的结束位置 实体类别”。如第一行表示content[21:24]对应的便是’右髋部’,为身体部位实体类别。
3 数据标注
实体识别的数据标注方式主要有BIOES和BIO两种,详细的介绍参考实验手册。这里为使标注类别不至于太多,决定采用BIO方式。即将实体部分的第一个汉字标注为B,实体的其他部分的汉字标注为I,非实体部分标注为O。
将5种实体类别治疗、身体部位、疾病和诊断、症状和体征、检查和检验分别标记为TREATMENT、BODY、DISEASES、SIGNS、EXAMINATIONS。
则标记时,如:若为治疗类别的实体的第一个汉字,则将其标注为B-TREATMENT,该实体其他字标记为I-TREATMENT。
label_dict = {
'治疗':'TREATMENT',
'身体部位':'BODY',
'疾病和诊断':'DISEASES',
'症状和体征':'SIGNS',
'检查和检验':'EXAMINATIONS'}
def sentence2BIOlabel(sentence,label_from_file):
'''
返回句子sentence的BIO标注列表
入参:
sentence:一个句子,字符串类别
label_from_file:该句子对应的标签,格式为直接从txt文件中读出的格式,形如上文中的content_label
出参:
sentence_label:该句子的BIO标签。一个列表,列表的第i项为第i个汉字对应的标签
'''
# 初始的sentence_label每个标签均定义为'O'。之后会修改其中实体部分的标签。
sentence_label = ['O']*len(sentence)
if label_from_file=='':
return sentence_label
# line为label_from_file中每一行的数据,对应一个实体的信息。格式为“实体内容 实体在文本中的开始位置 实体在文本中的结束位置 实体类别”
for line in label_from_file.split('\n'):
# entity_info中保存了单个实体的信息
entity_info = line.strip().split('\t')
start_index = int(entity_info[1]) #实体在文本中的开始位置
end_index = int(entity_info[2]) #实体在文本中的结束位置
entity_label = label_dict[entity_info[3]] #实体标签类别
# 为实体的第一个汉字标记为B-xx
sentence_label[start_index] = 'B-'+entity_label
# 为实体中的其他汉字标记为I-xx
for i in range(start_index+1,end_index+1):
sentence_label[i] = 'I-'+entity_label
return sentence_label
# 以上文中的content和content_label为例查看sentence2BIOlabel函数的使用方法
# 返回上文中content对应的BIO标签并输出
sentence_label_tmp = sentence2BIOlabel(content,content_label)
print(sentence_label_tmp)
['O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'O', 'B-BODY', 'I-BODY', 'I-BODY', 'O', 'O', 'O', 'B-SIGNS', 'I-SIGNS', 'B-SIGNS', 'I-SIGNS', 'O', 'O', 'O', 'O', 'O', '

本文介绍了如何通过CRF和BiLSTM-CRF模型对医疗领域的文本进行实体标注,包括数据预处理、特征工程、模型搭建与评估,展示了模型在识别治疗、身体部位等5种类别实体上的性能。
最低0.47元/天 解锁文章
1227





