前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >医用NER+L

医用NER+L

作者头像
磐创AI
发布2021-11-12 15:41:20
7070
发布2021-11-12 15:41:20
举报


磐创AI分享

作者 | Zeljko

编译 | VK 来源 | Towards Data Science

生物医学NER+L致力于从电子健康记录(EHR)中的文本中提取概念,并将其链接到大型生物医学数据库,如SNOMED-CT和UMLS。

医学概念注释工具包(MedCAT)使用基于Word2Ve来检测和消除生物医学概念的歧义。这种方法给了我们:

1)无监督的训练;

2) 有可能发现数百万个概念;

3) 训练速度快,所需资源少;

4) 能够从正面的例子中学习;

对于一些我们有足够训练示例的用例,基于Transformer的监督学习方法(例如BERT)可能更适合。

在这项工作中,我们展示了我们是如何集成的。我们使用MedCAT的数据集/ Transformers ,或者更准确地说,我们展示了如何将MedCATtrainer导出(手动注释的项目)转换为 数据集和Transformer模型。

先决条件:

  • 熟悉MedCAT(TDS教程)、MedCATtrainer、Hugging Face Transformers和数据集

Jupyter笔记本可在MedCAT存储库中找到:https://github.com/CogStack/MedCAT/blob/master/notebooks/BERT%20for%20NER.ipynb。

数据准备

MedCATtrainer用于为任何生物医学概念(如SNOMED或UMLS)的文本文档添加注释。注释过程完成后,可以以.json格式导出项目,如下所示:

{'projects': [{'name': '<something>', 
               'documents': [{'text': '<some text>', 
                              'annotations': [{'start': 23,
                                               'end': 32,
                                               'cui': <label>},
                                              ...]}]}]}

在Transformer模型中,我们将JSON输出转换为数据集。我们只保留JSON中的重要特征,而放弃其余特征:

features=datasets.Features(
{
"id": datasets.Value("int32"),
"text": datasets.Value("string"),
"ent_starts": datasets.Sequence(datasets.Value("int32")),
"ent_ends": datasets.Sequence(datasets.Value("int32")),
"ent_cuis": datasets.Sequence(datasets.Value("string")),
}),

这里,id是文档的id, text是文本,ent_starts是文档中手动注释的所有实体的开始字符位置列表,ent_ends是结束字符的位置,ent_cuis是标签。

注意,MedCATtrainer使用在线学习,虽然用户有能力创建新的实体,但大多数实体都由MedCAT预先注释,并由用户简单验证(正确/错误)。

因此,当在数据集类中生成示例时,我们只保留正确的示例和手动创建的示例,即由用户添加的示例:

for entity in document['annotations']:
    if entity.get('correct', True) or entity.get('manually_created', False):
        # 使用注释
        ...

加载.json文件现在非常简单:

import os
import datasets
from medcat.datasets import medcat_ner
DATA_PATH = '<path to my .json export from medcattrainer>'
dataset=datasets.load_dataset(os.path.abspath(medcat_ner.__file__), 
                              data_files=DATA_PATH, 
                              split=datasets.Split.TRAIN)

加载数据集后,我们需要将其转换为正确的格式,以便Transformer模型处理。我们使用tokenizer进行分词:

from medcat.datasets.tokenizer_ner import TokenizerNER
from transformers import AutoTokenizer

hf_tokenizer = AutoTokenizer.from_pretrained('<name>')
id2type = {}
for i in range(hf_tokenizer.vocab_size):
    id2type[i] = 'sub' if hf_tokenizer.convert_ids_to_tokens(i).startswith("##") else 'start'
tokenizer = TokenizerNER(hf_tokenizer, id2type=id2type)

使用新的tokenizer,我们可以将数据集转换为所需的格式:

encoded_dataset = dataset.map(
 lambda examples: tokenizer.encode(examples, ignore_subwords=True),
 batched=True,
 remove_columns=['ent_cuis', 'ent_ends', 'ent_starts', 'text'])

数据集现在如下所示:

Dataset({
    features: ['id', 'input_ids', 'labels'],
    num_rows: 4935
})

训练Transformer模型

如果我们的用例具有相对较少数量的单词,那么我们可以使用 TokenClassification

# 设置num_labels很重要, 这是唯一概念的数量
model = AutoModelForTokenClassification.from_pretrained("emilyalsentzer/Bio_ClinicalBERT", num_labels=len(tokenizer.label_map))

为了在需要的地方批处理数据和填充,我们使用MedCAT.dataset中的CollateAndPadNER,对于度量,我们编写了一个简单的函数来打印token分类报告。现在一切都准备好了,我们进行训练:

trainer = Trainer(
    model=model,                         
    args=training_args,                 
    train_dataset=encoded_dataset['train'],       
    eval_dataset=encoded_dataset['test'],     
    compute_metrics=metrics,
    data_collator=collate_fn,
    tokenizer=None # 分词
)
trainer.train()

结果

我们在 MedMentions (MM) 上测试性能,因为它是一个具有大量注释的相当完整的数据集(它不是完美的,因为注释者有一些不同意见,但它已经足够好了)。

该模型在三个不同版本的MM上进行了测试:

1)整个数据集;

2) 仅限频率高于300的概念;

3) 只有频率在1000以上。

完整MM数据集(测试集中13069个概念)

BERT的最坏用例是大量概念,其中大多数概念的出现次数小于10次。可以看出,BERT根本不能处理这个用例——至少不能以这种形式处理。所有分数均为宏平均值。

  • MedCAT (无监督): F1=0.67, P=0.80, R=0.69
  • BERT: F1=0.0, R=0.01, P=0.0
仅频率>300的概念(测试集中有107个概念)

这个用例在医疗领域是相当标准的,有大量的概念和不同数量的注释。有趣的是,2者的性能几乎是一样的。

  • MedCAT (监督): P=0.50, R=0.44, F1=0.43
  • BERT: P=0.47, R=0.46, F1=0.43
仅频率>1000的概念(测试集中有12个概念)

这个用例应该最适合于BERT,因为我们只关注具有大量训练数据的概念。像这样的用例是非常罕见的。

  • MedCAT (监督): F1=0.34, P=0.24, R=0.70
  • BERT: F1=0.59, P=0.60, R=0.59

结论

生物医学NER+L是一项艰巨的任务,与其他所有任务一样,一个模型并不适合所有用例。

我们表明,对于训练示例数量有限的用例,基于Word2Vec的浅层神经网络是一个更好的选择。

但如果我们有大量的训练示例,基于BERT的模型表现更好。

最后,这两种方法现在都是MedCAT的一部分。

原文链接:https://towardsdatascience.com/integrating-transformers-with-medcat-for-biomedical-ner-l-8869c76762a

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 磐创AI 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 完整MM数据集(测试集中13069个概念)
  • 仅频率>300的概念(测试集中有107个概念)
  • 仅频率>1000的概念(测试集中有12个概念)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档