基于CRF的医疗实体识别baseline

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

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', '
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值