MIMIC-III-Ext-Notes — 150 份护理记录的概念标注

150 份护理记录 / 2,288 个概念 / 三问判定

来源 https://physionet.org/content/mimic-iii-ext-notes/发布时间: 2026-10-28最后更新: 2026-10-31 阅读 16
MIMIC-III-Ext-Notes — 150 份护理记录的概念标注

信息速览

数据集名称MIMIC-III-Ext-Notes — 150 份护理记录的概念标注
数据类型人工标注,文本语料,元数据
规模150 份护理记录(MIMIC-III v1.4 随机抽样),患者数与住院数官方未披露
接入方式https://physionet.org/content/mimic-iii-ext-notes/

临床自然语言处理的瓶颈很少是文本不够。MIMIC-III 里有超过两百万条临床文本,覆盖十余种文书类型,任何人下载之后都能立刻训练一个语言模型。真正稀缺的是另一种东西:有人在这段文本上认真做过判断,并且把判断留成了可以对照的标签。一份护理记录里写着「sepsis」,它可能指患者正在因脓毒症治疗,可能只是既往史里的一句交代,也可能出现在「无脓毒症征象」这样的否定句里。三种情况的字符串完全一样,临床含义完全不同。

MIMIC-III-Ext-Notes 就是为这件事做的。它从 MIMIC-III v1.4 里随机取了一百五十份护理记录,用 MetaMap 抽出两千二百八十八个候选临床概念,然后请临床医生对每一个概念回答三个问题:这个概念是否被正确检出、它是否与本次就诊相关、它是否需要被否定。答案写进两列 CSV,与原文一起发布。

它的体积小得不像一个现代数据集,覆盖范围也窄得不像一个通用资源:只有护理文书,只有三类语义类型,只有单一记录内的语境。但正是这种收窄,让它成为少数能把「语境理解」变成可计算指标的资源之一——你拿去评测一个模型,得到的不是「它读了这段话」,而是「它在否定和既往史上错了多少」。一屏速览见下表。

维度 内容
全名 MIMIC-III-Ext-Notes
发布方 PhysioNet(MIT Laboratory for Computational Physiology)
版本 v1.0.0,2026-02-27 首发,此后无修订
版本 DOI 10.13026/9tfx-yx07
最新版 DOI 10.13026/2kv6-1s83
母库 MIMIC-III Clinical Database v1.4(2001–2012,波士顿 BIDMC)
规模 150 份护理记录;2,288 个标注概念
文件 notes.csv(原文)+ labels.csv(标签),两份
关联键 row_id(文件内);subject_id 与 hadm_id(对接主库)
标签维度 检出(二值)、就诊相关性(二值)、否定(三值)
语义类型 dsyn(疾病或综合征)、sosy(体征或症状)、mobd(精神或行为障碍)
标注者 至少两名临床医生独立判断,分歧由医生与护理研究者共识裁定
访问级别 认证访问(Credentialed),需 DUA 与 CITI 培训
许可 PhysioNet Credentialed Health Data License 1.5.0
配套论文 arXiv:2401.13588(2024-01-24),评测三个通用大模型
一句话 把「人在文本上做过的判断」压缩成两份 CSV,用来拷问模型的语境能力

§1 它要解决的具体麻烦

1.1 文本不缺,缺的是人在文本上留下的判断

临床文本的标注成本有一个不对称:抽概念便宜,判语境昂贵。用 MetaMap、cTAKES、scispaCy 这类工具跑一遍,任意规模的语料几小时内就能产出候选实体,成本近乎为零。但候选实体只是「这几个字像医学术语」,它不回答下面这些问题——这句话是在陈述患者的现状,还是在复述入院前的用药史?这个「肺炎」是本次入院的原因,还是三年前的一次住院?这个「无胸痛」是真的排除了,还是只是没提?

这些判断以前由两类资源承担。一类是共享任务语料,例如 i2b2 与 n2c2 系列的断言与否定任务,规模在数百份记录量级,但语料不是 MIMIC,人群与文书风格都不同。另一类是表型标注集,按整份文档给一个「有没有这个表型」的结论,粒度停在文档级。两者之间有一个明显的空档:在 MIMIC 的护理文书上、按概念级给出语境判定的公开资源。这份数据集填的就是这个空档。

理解它的定位,关键是分清「抽取」与「判定」两件事。它不提供金标准的实体边界——边界由 MetaMap 给出,可能切错、可能漏。它提供的是在给定候选之后,人对这个候选的三项判断。所以它是一个判定集,不是一个抽取集。这个区别决定了它能不能用来训练 NER,也决定了评测时该把什么算作误差。

1.2 三条常见的错误期待

第一条:把它当成 MIMIC-III 的全量文本标注版。 名字里有 MIMIC-III,容易让人以为主库的文本都被标了。实际只有一百五十份,而且限定在护理文书这一种类型。主库的出院小结、影像报告、呼吸治疗记录、社工记录都不在其中。如果你的任务语料是出院小结,它连领域适配的价值都有限。

第二条:把它当成训练语料。 两千二百余条标签,用来微调一个现代语言模型基本等于没有信号;即便只做最后的分类头,样本量也撑不起稳定收敛。它的设计意图是评测,官方在论文里也是拿它当考卷用的。拿考卷当教材,得到的分数没有解释力。

第三条:把它当成实体识别数据集。 概念边界来自 MetaMap,不是人工标注的黄金边界。用它算 NER 的精确率与召回率,测的其实是 MetaMap 的表现,不是模型的。它唯一诚实的用法是:给定这些候选,模型能不能判对三项属性。

1.3 它能给到的与给不到的

你的需求 它给的 够不够
评测模型能否识别文本中的否定 概念级的否定判定,三值(是、否、不确定) 够,且是目前少数带 MIMIC 护理文书的公开金标准
评测模型能否区分「本次活动性问题」与「既往史」 就诊相关性判定,二值 够做二分类评估,不够做时间定位
判断模型抽取的实体边界准不准 边界由 MetaMap 给定,非人工金标准 不够,方向不对
训练一个临床 NER 模型 两千余条标签、一百五十份文档 不够,量级差两到三个数量级
做跨文书类型的泛化研究 只有护理文书 不够,出不了这个文书类型
研究药物、操作、检验项的语境 只标了三类语义类型 不够,范围之外
复现一篇已发表的模型横评 论文给了任务定义、提示设计与模型清单 够,但需自行补齐提示细节
做标注指南与仲裁流程的方法学参考 三问设计、双人独立、共识裁定 够,流程写得清楚
直接商用或再分发 认证访问 + DUA,禁止再分发 不够,合规上不可行

1.4 你的处境与它能帮到的事

你的处境 它能帮你什么 下一步该做什么
模型在你的私有语料上表现很好,想知道它在「否定」上是不是真的会 提供一批有人工判定的小样本硬案例 先在同一批候选上跑你的管线,只比三项判定,不比抽取
正在设计一份院内文本标注规范,缺一个可参照的模板 三问的层级设计、双人独立、分歧仲裁都可直接借用 把三问翻成你所在科室的语境,先做五十份试点
要给院内大模型选型做一次内部评审 提供一套小而完整的评测协议与可复现的打分口径 固定候选集与提示模板,只换模型,做配对比较
需要向伦理委员会说明「文本数据可以安全开放」 提供一条从主库到派生标注层的完整脱敏路径 引用其数据说明与母库的去标识化条款
想做临床文本的主动学习研究 提供人工判断的真实分布形态与条件依赖结构 把它当初始种子池,另找大体量未标注语料扩增
想发一篇「LLM 在临床文本上到底行不行」的论文 提供已有的评测框架与对照结论,避免重复劳动 换语料、换语言或换任务维度,不要重复同一实验

1.5 一句话判断

它是一份体积很小、边界很硬、但判断很贵的标注集:不要指望它教会模型读病历,它擅长的是在同一批候选概念上,把「模型懂不懂语境」这件事问出一个可比较的答案。

1.6 不适合谁:四条边界

不适合需要统计功效的人。 一百五十份文档、两千二百余个概念,在概念级做二分类比较时还勉强能给出置信区间,一旦按语义类型、按文书亚类、按否定与否再切分,每个格子就只剩几十条。任何亚组结论都应该当成假设,而不是发现。

不适合跨文书类型外推的人。 护理文书的写法有强烈的地方性:短句、缩写密集、以生命体征与护理措施为主干、大量使用「患者」作主语、行文像勾选表而非叙述。在出院小结上训练的模型迁到这里会掉分,反过来也一样。这个数据集能告诉你模型在护理文书上的表现,不能告诉你它在临床文本上的表现。

不适合需要时间维度的人。 文件里没有文书日期,没有事件时间,也没有住院起止。所谓「就诊相关性」只回答「是否在本次就诊中被处理」,不回答「什么时候」。任何涉及病程演变的建模,都必须回到主库取时间戳,而主库的条级回接本身又受限于缺少 note_id。

不适合把标签当法律或结算依据的人。 官方明确写了标签反映项目自定的标注指南,不主张它是确定的临床金标准。它会存在个体判断差异,也存在指南未覆盖的灰区。把它当成病历质控或费用审核的判据,是把研究工具用到了它没有承诺过的地方。

§2 数据构成与规格

2.1 两个 CSV,一条外键

整个数据集只有两份文件,没有目录层级,没有数据库,没有脚本。notes.csv 一行一份护理记录,labels.csv 一行一个概念判定,两者通过 row_id 关联。row_id 是文件内自增的整数标识,与 MIMIC-III 主库的任何标识都不相同。

这种极简结构带来两个后果。好的一面是接入成本几乎为零:任何能读 CSV 的工具都能在几分钟内把数据装载进来,不需要解析嵌套 JSON,不需要处理时序表,也不需要还原数据库 schema。坏的一面是所有的语义都压在了字段名和取值域上,一旦对某一列的语义理解错位,代码不会报错,结果会安静地错下去。

主库的两个键都保留了下来:subject_id 指患者,hadm_id 指住院。这意味着你可以在住院层面把它与 MIMIC-III 的其它表连起来——把诊断、检验、生命体征挂到同一批住院上,做「文本判定 + 结构化指标」的联合分析。但要注意这是住院级而非记录级的连接:一份住院可能有多份护理记录,连接之后行数会被放大,做统计时必须先去重或在记录级聚合。

2.2 字段完整字典

文件 字段 类型 取值域 含义与注意点
notes.csv row_id 整数 文件内唯一 记录级主键,labels.csv 的外键;与主库 note_id 无关
notes.csv subject_id 整数 主库患者标识 可回接 MIMIC-III 的患者表;同一患者可能有多份记录入样
notes.csv hadm_id 整数 主库住院标识 住院级连接的唯一入口;缺失情况官方未说明
notes.csv text 字符串 自由文本 已去标识的护理记录全文,含换行与缩写
labels.csv row_id 整数 指向 notes.csv 一行标签所属的记录;一记录对应多行
labels.csv trigger_word 字符串 原文片段 触发该概念的文本片段,可能比概念名短
labels.csv concept 字符串 规范化概念名 MetaMap 给出的首选名,可能与触发词字面不同
labels.csv semtypes 字符串 dsyn / sosy / mobd / 空 概念所属语义类型;空值表示未落入三类
labels.csv start 整数 字符下标 触发词起始位置,官方未注明从 0 还是从 1 起算
labels.csv end 整数 字符下标 触发词结束位置,切片方式需自行校验
labels.csv detection 字符串 yes / no 第一问:概念是否被正确检出
labels.csv encounter 字符串 yes / no / 短横线 第二问:是否在本次就诊中被处理;检出为 no 时为短横线
labels.csv negation 字符串 yes / no / unsure / 短横线 第三问:是否需要否定;检出为 no 时为短横线

表里有两处需要单独说明。第一处是 semtypes 的第四个取值——空值。官方给出的取值域里包含空,说明进入 labels.csv 的概念并非全部落在三类语义类型之内,可能存在 MetaMap 判了类型但不在保留范围内、或类型缺失的情形。空值具体由什么构成,官方页面没有展开,使用时不要默认它等于「其它疾病类」。

第二处是 start 与 end 的起算方式。字符下标的 0 基与 1 基在生物医学标注里两种都常见,官方说明没有写。稳妥做法是取原文切片与 trigger_word 做比对:一致则按该口径,不一致则换一种。这个校验只要三行代码,但不做就会在后续的可视化与误差分析里持续错位一格。

2.3 一条记录的完整解剖

把一份护理记录和它的标签摊开看,结构就很清楚了。下面是一份按字段语义构造的示例,用来说明各列如何咬合,不是集内的某条真实记录。

#-- notes.csv 的一行(字段顺序:row_id, subject_id, hadm_id, text)
1042, 31782, 145920, "Pt alert and oriented x3. Hx of sepsis 2019,
  currently on vanc for PNA. Denies chest pain. No signs of sepsis
  at this time. Ambulated in hall with assist."

#-- labels.csv 中该 row_id 的四行(按 start 排序,只列关键列)
row_id | trigger_word     | concept            | semtypes | start | end | detection | encounter | negation
1042   | sepsis           | Sepsis             | dsyn     | 31    | 37  | yes       | no        | no
1042   | PNA              | Pneumonia          | dsyn     | 74    | 77  | yes       | yes       | no
1042   | chest pain       | Chest Pain         | sosy     | 96    | 106 | yes       | no        | yes
1042   | sepsis           | Sepsis             | dsyn     | 128   | 134 | yes       | no        | yes

四行标签里有两个 sepsis,来自同一份记录的不同位置。前者跟在「Hx of」之后,因此在本次就诊中不被处理,判为既往史;后者跟在「No signs of」之后,需要被否定。三列组合起来,才把一个概念在这份记录里的处境说完整。只看 concept 一列,两行完全一样;只看 detection 一列,两行也都对。语境信息全部藏在后面两列里,这也是 §4.3 的案例要展开的地方。

还有一点值得注意:PNA 与 Pneumonia 的字面完全不同。trigger_word 保留了原文的缩写,concept 换成规范化名称。做字符串匹配的管线会在这里漏掉,做概念匹配的管线才接得上。这个设计本身就在提示使用者:这份数据的价值在概念层,不在字面层。

2.4 三问的取值域与条件依赖

问题 字段 取值 判定对象 缺失或占位的含义
概念是否被正确检出 detection yes / no 该次出现的概念本身 无缺失,全部行都有值
是否在本次就诊中被处理 encounter yes / no / 短横线 检出为 yes 的概念 短横线表示上游检出为 no,无判定对象
是否需要否定 negation yes / no / unsure / 短横线 检出为 yes 的概念 短横线同上;unsure 是独立的第三类

这张表是整个数据集最重要的结构约束。它不是三个独立的多标签,而是一条层级链:第一问筛掉错的候选,后两问只在筛过的子集上定义。任何把短横线编码成 0、然后对全表算准确率的做法,都会把「模型没机会答错的题」算成答对。正确做法是先按 detection 分层,第二三问只在 detection 为 yes 的子集上算分母。

第三个问题还有一个容易读反的地方。字段名是 negation,语义是「是否需要否定」。也就是说,negation 为 yes 表示这个概念在文中被否认、被排除、被标注为不存在,而不是「否定判断成立」这种含混表述。一个真正的否定句,在这里标的是 yes。这与许多语料里 isNegated 的写法一致,但与「assertion 为正类」的习惯相反,写代码前必须确认一次。

2.5 与同类标注资源的字段差异

资源 标注单元 标签维度 边界来源 语料来源
本篇 概念的一次出现 检出、就诊相关、否定 MetaMap 候选 MIMIC-III 护理文书
i2b2 与 n2c2 断言任务 实体提及 断言类别(含否定、假设、他人经验) 人工标注 多家机构的出院记录
表型标注集(文档级) 整份文档 表型存在与否 不适用 MIMIC-III 出院小结与护理记录
通用实体标注集 实体提及 实体类型 人工标注 各领域文本
本篇的 LLM 合成近亲 改写后的整份文档 继承母库标签 母库给定 由母库文本改写

差异集中在两点。一是边界:其它资源多数把边界当标注对象,本篇把边界当前置条件。二是维度:其它资源的标签通常是一个类别,本篇是三列组合,组合之后才有语境含义。这两点决定了本篇不是任何一个既有资源的替代品,它补的是「概念级语境判定 + MIMIC 护理文书」这个交叉位置。

§3 核心层 A:身份与谱系

3.1 它不是「MIMIC-III 的笔记版」

名字里的 Ext 容易引起误解。在 PhysioNet 的命名习惯里,Ext 表示由母库派生的扩展资源,派生方式可以是重新组织、重新标注、重新配对,也可以是纯计算生成。所以 Ext 只说明血缘,不说明内容。把它读成「MIMIC-III 的笔记模块」会同时错两件事:一是以为它覆盖主库的全部文本,二是以为它与 MIMIC-IV-Note 那种官方模块同级。

正确的读法是三层:最底层是 MIMIC-III v1.4 的 NOTEEVENTS,提供原始文本与患者、住院标识;中间层是一次随机抽样与一次 MetaMap 抽取,决定了哪些文本、哪些概念进入视野;最上层是临床医生的三项判定,这是唯一新增的信息。三层各自的约束叠在一起,才是这份数据的真实形态。

由此可以推出一条使用原则:凡是要用原始文本的地方,回母库;凡是要用人的判断的地方,用这里。把两者混着用,最容易出现的问题是把抽样偏差当成临床特征——一百五十份记录不是随机人群的代表,它只是随机抽样的文本。

3.2 从 NOTEEVENTS 到 labels.csv 的五步

步骤 操作 决定的因素 留下的边界
一 从主库筛出护理类文书 文书类型限定 出院小结、影像报告不在内
二 随机抽取一百五十份 抽样规模 无分层,患者可重复入样
三 用 MetaMap 生成候选概念 工具的召回与切分 漏检的概念永不出现在标签里
四 限定三类 UMLS 语义类型 概念范围 药物、操作、检验项被排除
五 临床医生三问标注与共识裁定 人的判断 指南灰区与个体差异被固化

五步里第三步最容易被忽视。因为候选由工具生成,这份数据的召回上限等于 MetaMap 的召回上限。如果 MetaMap 没有把某个缩写认出来,那个概念就不会有标签——它不是被判为 no,而是根本不存在。这意味着一件事:不能拿这份数据去评估「模型能否发现所有概念」,只能评估「模型能否在给定候选上判对属性」。这一点在 §1.2 已经提过,在方法学上是它最硬的限制。

3.3 三个名字,三种指称范围

名称 出现场合 指称范围 引用时的注意点
MIMIC-III-Ext-Notes 数据集正式名 整个 v1.0.0 发布包 引用应带版本号
mimic-iii-ext-notes PhysioNet 的 slug 与 URL 同上,但用于定位 出现在链接与检索中,不是学术名称
论文标题中的长描述 arXiv 预印本 方法与评测,不完全等于数据 引用数据与引用论文是两件事

第三个名字值得单独提醒。论文的标题是「在成人重症监护电子病历记录上语境化评估语义概念」,讲的是评测方法与结果,数据只是它的材料。数据集的发布时间是 2026 年 2 月,论文是 2024 年 1 月,两者相隔两年多。这意味着论文里描述的数据形态,与最终发布包之间可能存在细节差异,引用时应当以发布页为准,把论文当方法学参考而不是数据字典。

3.4 Ext 前缀的两种含义

同前缀资源 Ext 的含义 母库 与本篇的关系
本篇 在母库文本上叠加人工判定 MIMIC-III 临床库 本文主体
MIMIC-III-Ext-PPG 从波形库切分出信号片段并打心律标签 MIMIC-III 波形库 同前缀不同母库,无字段重叠
MIMIC-IV 系列 Ext 从 MIMIC-IV 派生任务化子集 MIMIC-IV 代际不同,键不通用

同名前缀带来的检索混淆是实际存在的:搜 Ext-Notes 的人可能想看文本,搜 Ext-PPG 的人想看信号,两者在搜索结果里会挨在一起。判断依据不是前缀,而是母库——母库是临床库还是波形库,决定了它是文本资源还是信号资源。本篇属于前者,且只属于前者。

3.5 三类语义类型的边界在哪

三个缩写对应三种不同的医学表述。dsyn 是疾病与综合征,覆盖诊断名称,如脓毒症、肺炎、心力衰竭;sosy 是体征与症状,覆盖主诉与观察所见,如发热、气促、躁动;mobd 是精神与行为功能障碍,覆盖谵妄、抑郁、意识改变这一类。三者的分界在教科书上是清楚的,落到护理文书的实际写法上却经常模糊,因为同一段文字可以从不同角度命名同一个现象。

文中表述 常见归属 为什么会有两种判法
sepsis dsyn 诊断名称,边界清楚
fever sosy 是症状,但写成 febrile illness 时偏向疾病
意识改变 sosy 或 mobd 作为观察所见是症状,作为综合征是精神功能障碍
谵妄 mobd 或 dsyn 精神科分类里是障碍,内科分类里是综合征
低血压 sosy 是体征,但休克作为病因归入疾病
营养不良 dsyn 或 sosy 取决于是否作为独立诊断下码

这张表的用意不是让人去背归属,而是提醒一件使用上的事:按语义类型切分做亚组分析时,切分本身带噪声。同一个临床现象可能落在不同类型里,亚组之间的差异有一部分来自分类习惯而非模型能力。要在亚组上做结论,先看该组的概念构成是否稳定,再看差异。

被排除在外的类别同样值得说清。药物、操作、检验、解剖结构、患者人群都不在保留范围内,它们的语境判定需要另一套问题:用药是现用还是既往、操作是计划还是已完成、检验是结果还是医嘱。三问的框架套不到这些类别上,硬套只会得到语义含混的标签。这也是它不能替代药物抽取或操作抽取资源的根本原因,而不是标注量不够。

§4 核心层 B:质量与特色

4.1 三个问题为什么这样设计

三个问题不是随手凑的,它们对应临床文本理解里三个递进的失败模式。第一问管「是不是这个病」——模型可能把缩写认错,把「MS」认成多发性硬化而实际是 morphine sulfate,把「PT」认成凝血酶原时间而实际是物理治疗。第二问管「跟这次住院有没有关系」——这是临床决策最关心的一层,因为只有本次活动性问题才影响当下的处置。第三问管「是不是被排除了」——这是否定检测的经典难题,也是临床 NLP 里错误率最高的环节之一。

三问的顺序也有讲究。先问检出,是因为检出错了后面全错,没有讨论价值;再问就诊相关,是因为既往史与活动性问题在临床上的权重完全不同;最后问否定,是因为否定是在前两者成立之后才需要判断的语义修饰。这个顺序让标注者可以逐层收敛,也让评测者可以分层归因:模型到底错在认字、错在语境、还是错在否定。

值得对照的是论文里的表述。论文摘要谈的是「识别概念的时间性与否定」,而数据说明页谈的是「检出、就诊相关性、否定」。两个口径不完全一致:时间性(temporality)与就诊相关性(encounter relevance)在临床上相关但并不等价——前者问「什么时候」,后者问「这次住院管不管」。这个差异不是错误,更像是同一套标注在论文写作与数据发布两个场景下的不同抽象层级。使用者需要知道存在这两个口径,并按自己要做的事选一个。

4.2 标注者、分歧与仲裁

官方说明给出的流程是:每个概念至少由两名临床医生标注三个问题;所有标注者意见不一致的概念,由一名医生和一名护理研究者共同复核并讨论,得出最终裁定。论文给出的执行细节是九名临床医生参与标注。

这个设计有两个值得借鉴的地方。第一是双人独立,避免了单人标注的系统性漂移;第二是仲裁者跨专业——医生加护理研究者,而不是两名医生。跨专业在护理文书上尤其重要,因为文书作者是护士,缩写习惯、记录重点、隐语都与医生文书不同,只有护理背景的人才能判断某个写法在护理语境里到底指什么。

官方没有公布标注者间一致性的具体数值。这在使用上是一个空白:无法知道哪些标签更可信、哪些维度争议更大。替代做法是把 unsure 的存在当成一致性线索——否定维度设了三值而不是二值,本身就说明设计者预期到会有难以判定的情形。做误差分析时,把 unsure 单独作为一个类别看,往往比强行二值化更有信息量。

4.3 案例:sepsis 在一份护理记录里的三次出场

回到 §2.3 的那份示例记录。同一份文本里 sepsis 出现了两次,加上一个近义的 pneumonia,构成了三种完全不同的语境。这个案例之所以值得反复引用,是因为它把三列标签的分工演示得非常干净。

第一次出场在「Hx of sepsis 2019」里。检出为 yes——这确实是脓毒症这个概念;就诊相关为 no——2019 年的病史与本次住院的肺炎治疗无关;否定为 no——它不是被否认的,只是被推到了过去。如果模型只看字面,会把它当成当前诊断,于是把一个三年前的病史读成了本次的合并症。这类错误在临床文本抽取里极为常见,而且不会体现在实体识别的指标上。

第二次出场在「No signs of sepsis at this time」里。检出为 yes,就诊相关为 no,否定为 yes。三个标签的组合说明:概念是对的,但它被明确排除了,而且排除的范围限定在「此刻」。注意「at this time」这个限定语,它让否定变成了有时限的否定——过去可能有、将来可能有,现在没有。这种细腻程度是规则系统最难处理的部分,也是这份数据最有价值的地方。

第三次是 PNA 对 Pneumonia。字面完全不同,概念相同,检出为 yes,就诊相关为 yes——因为「on vanc for PNA」说明正在针对性治疗。这一条把「缩写归一」这个问题摆到了台面上:如果管线按字面匹配,PNA 会被当成一个未知实体;如果按概念匹配,它才接得上。§2.3 已经展示过这个例子,这里再提一次是因为它和三列判定共同构成了完整的语境画像。

把三次出场放在一起,可以得到一条实践结论:在这份数据上做评测,单看任何一列都会得出过于乐观的结论。检出接近满分是常态,因为候选本来就是对的;真正的区分度全部来自后两列。§4.3 的案例在 §7.3 讨论偏差时还会再出现一次,因为它同时说明了标签的价值与标注指南的边界。

4.4 质量的三条可核对线索

线索 观察方式 说明什么 说明不了什么
层级一致性 检查 detection 为 no 的行,后两列是否全为短横线 标注是否严格按层级执行 后两列的判断质量
切片一致性 用 start 与 end 切原文,与 trigger_word 比对 下标口径与文本编码是否可靠 概念切分是否正确
语义类型一致性 检查 semtypes 空值行与 concept 的对应 三类语义类型的边界是否严格 空值以外的类型是否都判对了

这三条都是结构性的自检,不需要任何外部参照,几分钟就能跑完。它们不能告诉你标签有多准,但能告诉你数据有没有被正确读入——而在实践中,绝大多数「这份数据有问题」的结论,最后都追到了读入错误上。特别是切片一致性这一条:一份含非 ASCII 字符的文本,如果在读入时编码判断错了,start 与 end 会整体偏移,而所有下游统计都不会报错。

4.5 为什么它适合当评测集而不适合当训练集

评测集需要的是难度分布合理、标签可信、规模可控;训练集需要的是覆盖广、量大、噪声可容忍。这份数据在前三项上做得不错,在第四项上先天不足。两百余条否定标签对于一个分类头来说太少,一百五十份文档对于预训练来说等于零。

更关键的是候选依赖。因为概念由 MetaMap 给定,模型的输入天然带了「正确答案的一部分」——它不需要自己找到概念,只需要判断属性。这种设定下训练出来的模型,一旦放到没有候选的真实场景里就会失效。把它当评测集,这个限制是可接受的,因为评测的本来就是一个受控子任务;把它当训练集,这个限制会变成系统性缺陷。

§5 核心层 C:取数

5.1 三道门:认证、DUA、CITI

环节 要求 常见卡点 大致耗时
账号 注册 PhysioNet 账户并完成邮箱验证 机构邮箱被拦 当天
培训 完成 CITI「Data or Specimens Only Research」课程 课程平台与 PhysioNet 账户未绑定 数小时至一天
认证 提交 credentialed 申请,说明机构与用途 用途描述过于笼统被退回 数个工作日
签署 在线签署数据使用协议 1.5.0 未读条款导致后续用途越界 即时
下载 通过后可取文件,禁止再分发 在共享盘或代码仓库里误传 即时

三道门里最容易被低估的是培训。CITI 课程需要单独注册、单独完成、单独把证书关联回 PhysioNet 账户,任一环节断掉都会让申请停在「材料不全」。认证本身通常不慢,慢的是材料来回。

还有一点必须说明:受限数据在部分网络环境下会显示区域限制提示,文件区不可见。这不是数据集被下架,而是平台对不同地区采取的访问策略。判断数据集是否仍可用,应当看项目页的版本与 DOI 是否正常,而不是看文件区是否可下载。

5.2 拿到之后先做什么

步一是装载与结构核对。不要急着建模,先把两份文件读进来,确认行数、键的唯一性、外键的完整性。这一步能挡掉后面八成的莫名错误。

#-- 载入与结构核对;依赖 pandas
import pandas as pd

notes = pd.read_csv("notes.csv")
labels = pd.read_csv("labels.csv")

print(notes.shape, labels.shape)
print("row_id 唯一(notes):", notes["row_id"].is_unique)
print("labels 指向的记录是否都存在:", labels["row_id"].isin(notes["row_id"]).all())
print("每条记录的标签数分布是否覆盖全部记录:",
      labels["row_id"].nunique() == notes["row_id"].nunique())

#-- 取值域核对:任何越界取值都先停下来看
print(labels["detection"].value_counts(dropna=False))
print(labels["encounter"].value_counts(dropna=False))
print(labels["negation"].value_counts(dropna=False))
print(labels["semtypes"].value_counts(dropna=False))

取值域的输出会直接暴露两个问题:一是短横线的实际写法(可能是 ASCII 连字符,也可能是全角破折号,还可能是空串),二是 semtypes 的空值是真空还是字符串 “null”。这两个问题在官方说明里都没有细化到字符层面,只能靠读入后核对。写解析代码时,用集合判断而不是逐字符比较,能省掉一轮返工。

5.3 连接与切片校验

下一步是把标签切回原文,确认下标口径。这一步只做一次,但必须做,因为它决定了后面所有误差分析能不能定位到具体字串。

#-- 切片校验:自动判断 start/end 是 0 基还是 1 基
def check_offsets(notes, labels):
    text_of = dict(zip(notes["row_id"], notes["text"]))
    hit0 = hit1 = 0
    total = 0
    for r in labels.itertuples():
        t = text_of.get(r.row_id)
        if not isinstance(t, str):
            continue
        total += 1
        if t[r.start:r.end] == r.trigger_word:
            hit0 += 1
        if t[r.start - 1:r.end - 1] == r.trigger_word:
            hit1 += 1
    print(f"0 基命中 {hit0}/{total},1 基命中 {hit1}/{total}")
    return "0-based" if hit0 >= hit1 else "1-based"

mode = check_offsets(notes, labels)
print("判定口径:", mode)

如果两种口径的命中都不高,通常是文本编码或换行被改写导致的。pandas 默认按 UTF-8 读取,若原文含特殊空白字符,切片位置会漂移。稳妥做法是把 text 列按原始字节读入后再解码,并保持换行符不做统一转换。这个细节听起来琐碎,但它决定了 start 与 end 到底还可不可用。

5.4 三种任务表的构造

三问是层级式的,所以三张任务表的构造方式不同。第一张覆盖全部行,后两张只取上游为 yes 的子集,且要保留短横线以外的第三类。

#-- 构造三个任务表;注意分母不同
import pandas as pd

lab = pd.read_csv("labels.csv")

#-- 任务一:检出,全量行
task_det = lab[["row_id", "start", "end", "concept", "semtypes", "detection"]].copy()
task_det["y"] = (task_det["detection"] == "yes").astype(int)

#-- 任务二:就诊相关,只在检出为 yes 上有定义
sub = lab[lab["detection"] == "yes"].copy()
task_enc = sub[sub["encounter"].isin(["yes", "no"])].copy()
task_enc["y"] = (task_enc["encounter"] == "yes").astype(int)

#-- 任务三:否定,三值;先把 unsure 单列出来,不强行二值化
task_neg = sub[sub["negation"].isin(["yes", "no", "unsure"])].copy()
task_neg["y"] = task_neg["negation"].map({"no": 0, "yes": 1})

print(len(task_det), len(task_enc), len(task_neg))
print(task_neg["negation"].value_counts())

三个长度会明显不同,这是正常的,也是必须记录在论文里的。任何跨任务比较都必须说明各自的分母,否则无法判断差异来自模型还是来自样本。

5.5 打分口径

打分的关键是别让占位符混进分母。下面这段给出一个最小但正确的评估函数,附带按概念分组的自助法置信区间——小样本下,点估计几乎没有意义,区间才是结论。

#-- 正确口径的二分类评估 + 按记录分组自助法
import numpy as np
from sklearn.metrics import f1_score, precision_score, recall_score

def bootstrap_ci(y, p, groups, n_boot=2000, seed=7):
    rng = np.random.default_rng(seed)
    uniq = np.unique(groups)
    idx_of = {g: np.where(groups == g)[0] for g in uniq}
    scores = []
    for _ in range(n_boot):
        pick = rng.choice(uniq, size=len(uniq), replace=True)
        idx = np.concatenate([idx_of[g] for g in pick])
        scores.append(f1_score(y[idx], p[idx], zero_division=0))
    return float(np.percentile(scores, 2.5)), float(np.percentile(scores, 97.5))

def report(y, p, groups, name):
    lo, hi = bootstrap_ci(y, p, groups)
    print(f"{name}: F1={f1_score(y, p, zero_division=0):.3f} "
          f"[{lo:.3f}, {hi:.3f}] "
          f"P={precision_score(y, p, zero_division=0):.3f} "
          f"R={recall_score(y, p, zero_division=0):.3f}")

y = task_neg["y"].to_numpy()
p = (np.asarray([0.5] * len(y)) < 0.5).astype(int)   #-- 占位预测,换成模型输出
report(y, p, task_neg["row_id"].to_numpy(), "negation")

分组重抽样必须按 row_id 而不是按标签行。同一份记录里的标签高度相关,按行重抽样会把相关性当成独立信息,得出过窄的区间。这个错误在小样本标注集上非常普遍,也是很多「模型显著更好」的结论经不起复核的原因。

5.6 复现论文的评测

要素 论文的做法 复现时的注意点
输入 护理记录原文加 MetaMap 候选概念 候选必须用同一份,不能重新跑工具
任务 判断概念的时间性与否定 与发布页的「就诊相关」口径不完全一致
提示 面向不同模型设计多套提示 提示差异会显著改变结论,需固定并公开
模型 三个通用大模型对照 版本会漂移,需记录调用日期与快照名
结论 其中一个模型整体领先,另两个在合适提示下改善 小样本,需配对检验而非独立比较

复现这件事最大的障碍不是算力,是模型版本。通用模型的接口在不通知的情况下更新,同一段提示隔三个月跑出来的结果可能不同。做法是把调用日期、模型快照名、提示原文、温度参数全部记录下来,并把原始输出存档。没有这四样,任何对比都不可复现。

§6 与库内词条的关系

6.1 MIMIC 家族关系表

词条 在家族中的位置 与本文的关系
mimiciii(MIMIC-III 主库) 母库,26 张表,两百余万条临床文本 本文的全部正文与两个键都来自这里
mimic-iii 同主库的另一篇词条 同一份数据的两种写法,不构成互替
mimiciii-demo 主库的一百人演示子集 可零门槛下载,但不含本文的标注层
mimic3wdb(波形库) 另一条支线,床旁波形 母库不同,键不通用,无文本
mimic3wdb-matched 波形与临床的匹配子集 提供波形侧关联,与文本标注无关
mimic-iii-ext-ppg 从波形库切分的脉搏波基准 同前缀不同母库,最易混淆
phenotype-annotations-mimic 主库护理与出院文书的表型标注 同为 MIMIC-III 文本标注,粒度与体系不同
mimic-patient-json 主库五百例住院的逐患者 JSON 面向问答与患者模拟,非概念级判定
mimic-ext-synnotes 用大模型改写主库全部笔记 文本是合成的,标签继承自母库
mimiciv(MIMIC-IV 主库) 下一代主库 代际不同,subject_id 不可跨库拼接
mimic-iv-ed MIMIC-IV 的急诊模块 结构化事件表,无文本标注
mimic-iv-ecg 十二导联心电波形库 信号资源,与文本无关
mimic-cxr-jpg 胸片与结构化标签 影像资源,与文本无关
mimic-iv-ext-22mcts 从 MIMIC-IV 出院小结抽事件与时间 同为文本派生,但代际、文书、任务全不同
mimic-iv-ext-pe 从 MIMIC-IV 影像报告抽肺栓塞标签 单病种弱监督标注,粒度是报告级
本篇 主库护理文书上的概念级语境判定 家族里唯一的「三问概念判定」层

这张表的读法是先看母库,再看派生层。母库是 MIMIC-III 的有三条支线:临床表、波形、文本标注;本篇在第三条支线上,与表型标注集并列,但粒度更细——表型标注给整份文档一个结论,本篇给每个概念一个结论。

6.2 三个近邻的分工

第一个近邻是表型标注集。它同样来自 MIMIC-III 的文本,同样由临床人员标注,同样面向临床 NLP。区别在标注单元:它按整份文档判断十余个高上下文表型是否存在,本篇按概念判断三项属性。做文档级分类用它,做概念级断言用本篇。两者的护理文书可能有重叠,但标注体系不兼容,不能互相替代。

第二个近邻是合成笔记集。它把主库的全部笔记用大模型改写了一遍,规模是本文的万倍以上,但标签是从母库继承的,没有新增人工判断。用它做预训练或隐私研究,用本篇做评测,两者的分工很清楚:一个提供量,一个提供判断。

第三个近邻是 MIMIC-IV 的事件抽取集。它从出院小结里抽「临床事件 + 相对小时」,规模同样远大于本篇。区别有三层:代际不同(IV 对 III)、文书不同(出院小结对护理记录)、任务不同(时间定位对属性判定)。名字里都带「文本派生」,但除了这一点几乎没有交集。

6.3 检索路径

你想找的东西 该去哪个词条 判据
MIMIC-III 的表结构与字段 主库词条 需要 26 张表的字典
MIMIC-III 的文本在哪里 主库词条的文本表 需要全量文书
护理文书的表型标签 表型标注集词条 需要文档级结论
概念级的否定与就诊判定 本篇 需要三列判定
文本改写与合成语料 合成笔记集词条 需要规模
事件与时间抽取 MIMIC-IV 事件抽取词条 需要时间轴
波形与生理信号 波形库系列词条 需要信号
零门槛体验 MIMIC 演示子集词条 需要免申请

§7 质量评估与局限性

7.0 阅读本节前的一个前置校正

评估这份数据时,最容易发生的误判是把「小」读成「差」。一百五十份文档、两千二百余个概念,放在今天的数据集版图里确实微不足道,但它的体量是任务性质决定的:概念级语境判定必须由临床医生逐条做,一个人的一天大概只能处理数百条,要做到十万条就需要以年计的人力。规模小不是采集失败,是这类标注的固有成本。

第二个容易发生的误判是把「窄」读成「偏」。只覆盖护理文书、只覆盖三类语义类型,看起来像是抽样不严,实际是刻意收窄:文书类型统一,标注者才可能形成稳定的判断标准;语义类型限定,三问才有明确的对象。放宽范围不会让它变好,只会让它变贵且更难一致。

做完这两个校正,剩下的评估才有意义。下面的五维评分与 DAIMS 二十四项,都是在「它想做成一个小而准的判定集」这个前提下打的分。如果按「通用临床 NLP 资源」的标准评,几乎每一项都会不及格——但那个标准本来就不是它的目标。

7.1 五维评分

维度 得分 依据
文档完备度 4.0 / 5 字段说明、标注流程、局限性都写了;标注一致性数值未公布
结构规整度 4.5 / 5 两份 CSV、单一外键、取值域封闭,接入几乎零成本
标签可信度 4.0 / 5 双人独立加跨专业仲裁;但指南自定、无外部金标准复核
分析就绪度 3.5 / 5 可直接读入,但层级分母、下标口径、占位符都要自行处理
许可与可及性 2.5 / 5 认证访问加 DUA,禁止再分发,复现门槛明显高于开放集
综合 3.7 / 5 判断质量是它最强的部分,可及性是它最弱的部分

7.2 DAIMS 二十四项评估

DAIMS 是千方医数集用于评估数据 AI 就绪度的框架,八个维度各三项,每项按 0、0.5、1 三档打分,满分 24。

维度 检查项 得分
文档 字段字典完整且可对上列名 1
文档 标注流程与仲裁机制交代清楚 1
文档 版本与变更记录可追溯 1
机读 单一表格结构、无需解析嵌套 1
机读 字段类型一致、取值域封闭 1
机读 主键明确、外键可校验 1
标签 三个判定维度的定义明确 1
标签 关键标签有外部核验 0.5
标签 标注一致性数值公开 0
可访问 无需申请即可下载 0
可访问 提供校验和与清单 0.5
可访问 提供多种获取方式 0.5
许可 许可明确且机器可读 1
许可 允许商用 0
许可 允许再分发 0
格式 通用格式、无私有编码 1
格式 字符下标口径自解释 0
格式 字符编码与换行规范 0.5
评测 有官方基线或参考分析 1
评测 有划分建议 0
评测 有公开排行榜 0
生态 有配套代码 0.5
生态 有第三方二次使用 0.5
生态 有活跃维护 0.5
合计 — 14.5 / 24

十四点五分里,扣分集中在三块:可及性(认证加 DUA,不可商用不可再分发)、格式细节(下标口径与编码未写明)、评测基础设施(无划分、无排行榜)。这三块恰好都不是判断质量问题——标签本身是该框架里少数拿满分的地方。换句话说,这份数据的短板在工程与合规,不在医学内容。

7.3 已知的、可枚举的偏差

偏差 机制 把结论推向哪边
候选偏差 概念只来自 MetaMap 的召回 低估模型发现新概念的能力
文书偏差 只取护理文书 结论不能平移到出院小结与影像报告
语义类型偏差 只保留三类 药物与操作相关的语境错误完全测不到
单记录偏差 只判单一记录内语境 跨就诊的病程演变测不到
抽样偏差 随机抽一百五十份,未分层 少见文书亚型的代表性未知
指南偏差 标签按项目自定指南 换一套指南,灰区标签可能翻转
占位符偏差 上游为否时后两列为短横线 误当阴性类会系统性高估表现
规模偏差 概念数百量级 亚组比较的区间很宽,易过解读

八条里有五条是结构性的,无法用统计手段消除:候选、文书、语义类型、单记录、占位符,这些都是设计选择。另外三条可以在使用层面缓解——抽样偏差靠报告样本构成缓解,指南偏差靠公开标注细则缓解,规模偏差靠分组自助法与配对检验缓解。§4.3 的案例就是指南偏差的典型现场:「at this time」这种限定语到底算不算否定,不同指南可能给出不同答案。

7.4 外部验证矩阵

验证方向 可用参照 能验证什么 不能验证什么
否定检测的难度量级 公开的断言任务结果 任务是否处在合理难度区间 具体模型在本集上的分数
概念抽取的召回上限 同类工具在护理文书上的报告 MetaMap 的召回是否够用 漏检概念的临床重要性
文书风格 主库的护理文书抽样 文本是否与主库一致 标注判断是否与临床共识一致
标签语义 公开的标注指南文献 三问的定义是否与领域习惯兼容 本集执行得是否严格
评测结论 论文的模型横评 方向性结论是否可复现 数值是否逐位一致

这张矩阵的读法是:能被验证的几乎都在「任务与结构对不对」,不在「标签准不准」。唯一能部分触及标签质量的是最后一行——如果换一个模型、换一套提示,仍然得出「通用模型在否定上明显弱于检出」的结论,那么这个结论就比较稳;如果结论随提示剧烈摆动,说明问题可能出在评测设计而非模型能力。

7.5 它为何能持续:把人的判断固定在最小可复用的体积里

标注数据有两种命运。一种是越用越旧,随着模型能力提升迅速失去区分度;另一种是越用越像基础设施,因为它固化的是「人怎么看」而不是「模型怎么答」。这份数据属于后者,原因有三。

第一,它记录的是判断而非答案。三项判定的具体内容会随指南演变,但「一个概念在一份记录里有检出、归属、极性三个维度」这个结构不会过时。任何新的模型、新的提示、新的评测框架,都可以在这套结构上重跑,而不需要重新标注。

第二,它的体积刚好适合当复核样本。一百五十份文档小到可以人工全查,大到足以暴露系统性问题。当团队要决定「这个模型能不能上线」时,需要的正是这种能在一两天内被人复核一遍的样本,而不是几十万条只能靠指标说话的语料。

第三,它的访问门槛反过来保护了它。认证加 DUA 让它不能随意扩散,也就不会像完全开放的数据那样被反复重采样、逐渐泄漏进预训练语料。对于一个评测集来说,未被污染比广泛流传更重要——这也是它在设计上无意中获得的优势。

§8 生态位与历史

8.1 一条从论文到数据集的时间线

时间 事件 意义
2024-01-24 评测论文提交预印本 方法与结论先行公开,数据尚未发布
2024 年 论文在临床 NLP 与重症信息学圈内被引用 建立了「三问评测」的问题意识
2026-02-27 数据集 v1.0.0 在 PhysioNet 发布 标注本体首次可申请获取
2026 年 版本 DOI 与最新版 DOI 并存 引用时需区分版本

这条时间线里最值得注意的是顺序:论文比数据早两年多。这在生物医学数据里并不罕见——论文写的是方法,数据发布要过认证与伦理流程。但对使用者有一个实际影响:论文里描述的数据形态是当时的,发布包可能有细微调整,两者冲突时以发布页为准。

8.2 与共享任务语料的分工

维度 共享任务语料 本篇
语料来源 多机构,非 MIMIC 单一机构,MIMIC-III
标注单元 实体提及 概念的一次出现
标注维度 断言类别 检出、就诊相关、否定
获取方式 通常需注册或签署协议 认证加 DUA
规模 数百份文档 一百五十份文档
主要用途 竞赛与基准 内部评测与复核

两者不能互相替代,但可以互补。共享任务语料适合做跨机构泛化,本篇适合做单一机构内的深度语境评估。如果要做「模型在不同机构文书上的稳定性」,两者放一起用才有意义。

8.3 与表型级标注的分工

表型级标注回答的是「这份文档里有没有这个表型」,本篇回答的是「这个概念在这里是什么状态」。前者适合做队列筛选与弱监督,后者适合做断言与否定模块的评测。一个典型的组合用法是:先用表型标签扩增队列,再用概念级判定检查模型在边界样本上的表现。两者的护理文书可能重叠,但标签不可互换。

8.4 小样本标注集的生存空间

过去几年,数据集的规模军备竞赛让「小」变成了一个需要辩护的属性。但评测这件事的逻辑与训练相反:训练需要覆盖,评测需要区分。一份十万条的语料,如果九万九千条都是模型已经答对的简单样本,它的区分度还不如一份两千条、每条都卡在灰区的标注集。

这个小样本标注集的价值,正在于它把人力集中投在了灰区上:否定、既往史、缩写归一、限定时态。这些都是模型最容易出错、也最容易被大规模语料淹没的地方。它的生存空间不是「替代大语料」,而是「在没有更好的判断来源时,提供一个可信的参照点」。

§9 使用指引

9.1 三种角色的路径

角色 最短路径 主要产出 需要避开
模型评测者 申请访问 → 装载 → 构造三张任务表 → 固定提示跑分 → 分组自助法给区间 一份带置信区间的模型横评 把占位符当阴性类;不固定提示
标注规范设计者 读字段说明与论文方法 → 复用三问层级 → 在自己语料上试点五十份 一份可执行的标注手册 直接照搬语义类型范围
临床信息学研究者 用 hadm_id 连接主库结构化表 → 做文本判定与指标的联合分析 文本与结构化数据的关联研究 在记录级连接后忘记去重

三条路径的共同前提是拿到数据。认证流程不复杂,但需要预留时间,不建议在项目截止前一周才开始申请。

9.2 一条最短的可用流程

从零到第一个可信数字,最短可以压到半小时以内,前提是数据已经到手。

#-- 目录约定;两份 CSV 放在 data 下
mkdir -p work/mimic-iii-ext-notes/data
cp notes.csv labels.csv work/mimic-iii-ext-notes/data/
cd work/mimic-iii-ext-notes
python3 -c "import pandas, sklearn; print(pandas.__version__, sklearn.__version__)"
#-- 端到端最小流程:装载、校验、构表、打分
import pandas as pd, numpy as np
from sklearn.metrics import f1_score

d = "data/"
notes = pd.read_csv(d + "notes.csv")
labels = pd.read_csv(d + "labels.csv")

#-- 1 结构校验
assert notes["row_id"].is_unique
assert labels["row_id"].isin(notes["row_id"]).all()

#-- 2 下标口径
t0 = dict(zip(notes["row_id"], notes["text"]))
sample = labels.sample(n=50, random_state=1)
ok = sum(t0[r.row_id][r.start:r.end] == r.trigger_word for r in sample.itertuples())
print("0 基切片命中率:", ok / len(sample))

#-- 3 三张任务表
sub = labels[labels["detection"] == "yes"]
neg = sub[sub["negation"].isin(["yes", "no"])].copy()
neg["y"] = (neg["negation"] == "yes").astype(int)

#-- 4 基线:全部判为否
base = np.zeros(len(neg), dtype=int)
print("全否基线 F1:", round(f1_score(neg["y"], base, zero_division=0), 3))
print("样本量:", len(neg))

最后那行基线数字很重要。在小样本、类别不平衡的否定任务上,「全判否」往往能拿到一个看起来不低的分数。任何模型如果不超过这条线,就没有讨论价值。先算基线,再谈模型,是这类评测的基本纪律。

9.3 引用方式

数据集引用应带版本号与 DOI,作者列表按官方页面给出的十二人顺序。如果同时使用了论文的方法与结论,需要把论文单独列一条——数据与论文是两份不同的作品,只引其中一个都会造成溯源缺口。

若使用 PhysioNet 平台本身的服务,按平台要求还需引用平台标准文献。BibTeX 的条目类型用 article,note 字段写版本号,doi 字段写版本 DOI 而不是最新版 DOI,这样复现时才能定位到具体发布包。

9.4 上手前的十项检查

拿到数据到出第一个可信数字之间,有十个地方会安静地出错。它们不会抛异常,只会让结果偏一点,而且偏得很难被发现。下表按检查成本从低到高排。

检查项 不查会怎样 做法
两份文件的行数与键 外键悬空,标签挂不到记录上 校验 row_id 是否全在 notes 内
取值域的字符形态 短横线写成全角、空值写成字符串 用集合判断,不逐字符比较
下标起算方式 全部切片错位一格 取若干行切片与触发词比对
文本编码 含非 ASCII 时下标整体漂移 按原始字节读入再解码
层级链完整性 占位符混进分母 检查检出为否的行后两列是否全为占位
语义类型空值 误把空值当第四类结论 先看空值行的概念构成
否定极性 把 yes 读成断言成立 用一句明确的否定句验一次
分母口径 三个任务混用一个分母 每张任务表单独记录样本量
分组重抽样 区间过窄,显著性虚高 按记录而不是按标签行抽样
基线 把「全判否」误当模型能力 先算常数基线再谈提升

十项里有七项是结构检查,只有最后三项涉及统计。这个比例说明一件事:在这类小样本标注集上,错误的主要来源不是模型选得不好,而是数据读得不对。把前七项固化成一段启动脚本,后面所有实验都会省一次返工。

§10 AI 使用声明

项目 声明
可用于训练 概念级属性分类器的评测与校准、否定检测的错误分析、标注一致性研究
不建议用于训练 从零训练语言模型、训练实体边界识别、任何需要万级以上样本的任务
标签来源 临床医生双人独立判定加跨专业共识裁定,无外部金标准复核
人群代表性 来自单一机构的成人重症患者,护理文书作者为床旁护士,不代表全人群
伦理约束 原数据在 IRB 批准下创建并按 HIPAA 口径去标识,禁止任何重新识别尝试
许可义务 认证访问加 DUA 1.5.0,禁止再分发,禁止商业使用,衍生物需遵守同一协议
失效场景 跨文书类型、跨机构、跨代际(MIMIC-IV)、需要时间定位或需要药物操作类概念的任务
责任边界 基于本集训练或评测的模型不得直接用于临床决策

常见误读(避坑清单)

说法 实际 证据
这是 MIMIC-III 的全量文本标注 只有一百五十份护理记录 数据说明页写明随机抽样一百五十份
标签是人工标的实体边界 边界来自 MetaMap,人只判三问 字段含 trigger_word 与 start/end,概念名由工具规范化
两千多条标签可以微调模型 规模只够做评测,不够训练 官方定位为评测资源,论文用它做模型横评
negation 为 yes 表示概念成立 表示该概念需要被否定 官方问题原文为「是否需要否定」
短横线是阴性类 是上游检出为否时的占位 官方说明短横线表示检出标签为否
可以用 note_id 回接主库 文件里没有 note_id 字段仅有 row_id、subject_id、hadm_id、text
有日期可以做病程时序 没有文书日期,只有住院标识 字段表无 chartdate 或 storetime
三类语义类型之外没有概念 semtypes 存在空值 取值域含空,说明并非全部落入三类
这是外部采集的新队列 完全来自母库,无新患者数据 页面注明未采集任何新患者数据
标签是确定的临床金标准 官方明确声明不是 局限性一节写明反映项目自定指南

FAQ

Q1:这份数据是 MIMIC-III 的子集还是外部补充?

是子集派生的标注层。正文全部来自 MIMIC-III v1.4 的护理文书,没有采集任何新患者数据,也没有引入外部机构的语料。新增的信息只有一项:临床医生在原文上做出的判断。所以它既不是独立队列,也不是主库的简单子表,而是叠在母库文本上的一层人工注记。

Q2:两千二百多个概念是怎样选出来的?

先用 MetaMap 在护理记录上生成候选,再限定三类 UMLS 语义类型,剩下的候选全部交给临床医生逐条判定。这个流程意味着两件事:概念的范围由工具与类型双重限定,漏检的概念不会有任何标签。它不是人工自由标注的实体清单,而是工具候选的判定结果。

Q3:negation 为 yes 到底表示什么?

表示该概念在文中需要被否定,也就是被否认、被排除、被标注为不存在。字段名与常见的 isNegated 同义,但语序容易读反——不要理解成「否定判断成立」。一个写着「无胸痛」的句子,这里的 negation 应当是 yes。

Q4:为什么 encounter 与 negation 有大量短横线?

因为三问是层级式的。检出为 no 的概念,后两问没有判定对象,官方以短横线占位。这些行不是「判为否」,而是「没有被问」。把短横线编码成 0 并对全表算准确率,会系统性高估模型表现,这是这份数据最容易被误用的地方。

Q5:能不能直接用 note_id 回接 MIMIC-III 主库?

不能。notes.csv 只给 row_id、subject_id 与 hadm_id,没有 note_id,也没有文书日期。可以在住院层面做关联,把结构化指标挂到同一批住院上;要做条级回接,只能靠文本匹配,而匹配的可靠性无法保证。

Q6:一千多字的护理记录里为什么会有这么多概念?

护理文书记录密集,一份里同时出现症状、体征、既往诊断、护理措施与评估结论是常态。概念数多不代表记录长,而代表记录里可被判定的医学表述密集。这也是护理文书适合做概念级标注的原因之一。

Q7:标注一致性有多高?

官方没有公布标注者间一致性的具体数值。可用的替代线索是否定维度设了三值——yes、no、unsure,说明设计者预期到会有难以判定的情形。做误差分析时把 unsure 单列,比强行二值化更有信息量。

Q8:这份数据能用来做否定检测的基准吗?

可以,而且是它最合适的用途之一。但要注意两条:一是候选由工具给定,测的是判定不是发现;二是样本量小,亚组比较要给区间。如果你的目标是「模型能不能从零找出被否定的实体」,需要另找标注了边界的语料。

Q9:论文结论说某个模型整体领先,这个结论可靠吗?

方向性结论可以参考,数值不要照搬。三个原因:样本量小,点估计的区间很宽;模型版本会漂移,同一条接口隔几个月结果可能不同;提示设计对结果影响很大,而提示细节难以完整复现。把它当作「通用模型在语境判定上仍有明显缺口」的证据,比当作排行榜更合适。

Q10:许可允许商用吗?

不允许。许可为 PhysioNet 认证健康数据许可 1.5.0,配数据使用协议 1.5.0,明确禁止再分发,商业使用需另行获得授权。任何把它打包进商业产品、或在公开仓库里附带样本的做法都违反协议。

Q11:如果我只想要 MIMIC 的文本,需要申请这份数据吗?

不需要。文本本身在主库,主库有自己的认证流程。这份数据的价值只在标签,如果你不需要三项判定,直接申请主库更省事,也能拿到 full 的文书类型与时间戳。

Q12:它和 MIMIC-IV 的文本资源能拼起来用吗?

不能按个体拼接。MIMIC-III 与 MIMIC-IV 的患者标识体系不同,跨代际不可连接,即便是同一家医院、时间上有重叠,也没有可靠的跨库主键。能做的是分布层面的对照,或者把两者当作两个独立的评测集分别报告。

术语表

术语 含义
MIMIC-III 伯斯以色列女执事医疗中心 2001 至 2012 年的重症监护临床数据库
NOTEEVENTS 主库中存放临床文书的表,按类型区分出院小结、护理记录、影像报告等
护理文书 由床旁护士撰写的记录,短句多、缩写密、以评估与措施为主干
MetaMap 美国国立医学图书馆开发的生物医学概念抽取工具,输出映射到 UMLS
UMLS 统一医学语言系统,提供概念、术语与语义类型的对照
语义类型 UMLS 对概念的分类标签,如疾病或综合征、体征或症状
dsyn Disease or Syndrome 的缩写,疾病或综合征
sosy Sign or Symptom 的缩写,体征或症状
mobd Mental or Behavioral Dysfunction 的缩写,精神或行为功能障碍
候选概念 工具生成的、尚未经人工判断的概念出现
触发词 原文中引发概念识别的那段字串,可能是缩写
检出 第一问,判断候选概念是否被正确识别
就诊相关性 第二问,判断概念是否在本次住院中被处理
否定 第三问,判断概念是否需要被否认或排除
断言 文本中关于某个实体状态的判断,包括肯定、否定、假设、他人经验等
占位符 上游为否时后两问填入的短横线,不表示阴性
字符下标 start 与 end,标出触发词在原文中的位置
分层分母 按上游判定切分后各自计算的分母,避免占位符混入
分组自助法 按记录而非按标签行重抽样的区间估计方法
认证访问 PhysioNet 的受限访问级别,需培训、申请与签署协议
DUA 数据使用协议,规定用途、禁止再分发等义务
CITI 培训 研究伦理与数据保护课程,认证访问的前置条件
标注一致性 多个标注者对同一对象判断的一致程度
共识裁定 分歧由第三方复核后确定最终标签的机制
DAIMS 千方医数集的数据 AI 就绪度评估框架,八维二十四项

附录 A:核心数字核对表

项 值 来源 来源层级
记录数 150 数据说明页 官方页面
概念数 2,288 数据说明页 官方页面
文件数 2 数据说明页 官方页面
语义类型数 3(另含空值) 字段取值域 官方页面
标注者规模 至少两人逐概念,共九人参与 页面与论文 官方页面 + 论文
首版日期 2026-02-27 版本页 官方页面
版本 DOI 10.13026/9tfx-yx07 版本页 官方页面
最新版 DOI 10.13026/2kv6-1s83 项目页 官方页面
许可 Credentialed Health Data License 1.5.0 许可页 官方页面
访问级别 认证访问 项目页 官方页面
母库 MIMIC-III v1.4 派生关系 官方页面
论文 arXiv:2401.13588 引用区 官方页面
论文日期 2024-01-24 预印本页 论文摘要
评测模型数 3 论文摘要 论文摘要
文书类型 护理文书 数据说明页 官方页面
标注一致性的数值 未公布 无 未核实

附录 B:数字的来源分层

第一层:官方页面。 记录数、概念数、文件构成、字段与取值域、版本日期、两个 DOI、许可与访问级别、母库关系、文书类型、标注流程,全部来自 PhysioNet 项目页与版本页的正文。这一层可以直接引用。

第二层:论文摘要。 标注者人数、评测的模型数量与方向性结论、任务的时间性与否定表述,来自预印本摘要。摘要能确认方法与结论,但具体数字仍以官方页面为准。两者在任务口径上存在差异时,正文已注明两个口径并存,不做孰对孰错的判断。

第三层:未核实。 标注者间一致性的具体数值、semtypes 空值的构成、start 与 end 的起算方式、short dash 的字符写法、患者与住院的实际数量,这些在公开材料里没有给出,数据也只对认证用户可见。凡正文出现「官方未注明」「未公布」的表述,都属于这一层,不应用推测填补。

附录 C:完整参考文献

  1. Liu D, Bouvier M, Bold D, Jabaley C, Young M, Zhang W, Wainwright M, Rosenthal E, Dimisko L, Park S, Clermont G, Hu X. MIMIC-III-Ext-Notes, version 1.0.0. PhysioNet. 2026-02-27. DOI: 10.13026/9tfx-yx07.
  2. Liu D, Ding C, Bold D, Bouvier M, Lu J, Shickel B, Jabaley CS, Zhang W, Park S, Young MJ, Wainwright MS, Clermont G, Rashidi P, Rosenthal ES, Dimisko L, Xiao R, Yoon JH, Yang C, Hu X. Evaluation of General Large Language Models in Contextually Assessing Semantic Concepts Extracted from Adult Critical Care Electronic Health Record Notes. arXiv:2401.13588. 2024.
  3. Johnson AEW, Pollard TJ, Mark R. MIMIC-III Clinical Database, version 1.4. PhysioNet. 2016. DOI: 10.13026/C2XW26.
  4. Pollard T, Moody BE, Lehman L, Gow B, Fernandes C, Xie C, Johnson A, Mark RG, Heldt T. PhysioNet as a global platform for biomedical research. Nature Health. 2026.
  5. 本集数据使用协议 1.5.0 与许可 1.5.0 全文,用于确认用途边界与再分发限制。
  6. UMLS 语义类型参考文档,用于核对 dsyn、sosy、mobd 三类缩写的准确含义。
  7. MetaMap 官方说明,用于理解候选概念的生成方式与召回边界。

附录 D:任务代码

#-- 三种任务的统一评估器;输入为模型输出与金标准表
import numpy as np, pandas as pd
from sklearn.metrics import f1_score

def evaluate(gold, pred, task, group_col="row_id", n_boot=2000, seed=11):
    #-- gold 与 pred 必须是等长同序的序列
    gold = np.asarray(gold).astype(int)
    pred = np.asarray(pred).astype(int)
    rng = np.random.default_rng(seed)
    groups = np.asarray(group_col if not isinstance(group_col, str) else gold)
    uniq = np.unique(groups)
    idx_of = {g: np.where(groups == g)[0] for g in uniq}

    scores = []
    for _ in range(n_boot):
        pick = rng.choice(uniq, size=len(uniq), replace=True)
        idx = np.concatenate([idx_of[g] for g in pick])
        scores.append(f1_score(gold[idx], pred[idx], zero_division=0))

    point = f1_score(gold, pred, zero_division=0)
    lo, hi = np.percentile(scores, [2.5, 97.5])
    return {"task": task, "n": len(gold), "f1": round(float(point), 3),
            "ci_low": round(float(lo), 3), "ci_high": round(float(hi), 3)}

#-- 用法示意:三张任务表各自传入,不要合并
#-- results = [evaluate(t["y"], t["pred"], name) for name, t in tasks.items()]
#-- print(pd.DataFrame(results))
#-- 占位符审计:确认层级链是否严格执行
import pandas as pd

lab = pd.read_csv("labels.csv")
mask = lab["detection"] == "no"
viol_enc = lab.loc[mask, "encounter"].isin(["yes", "no"]).sum()
viol_neg = lab.loc[mask, "negation"].isin(["yes", "no", "unsure"]).sum()
print("检出为否但后两问有判定值的行数:", int(viol_enc), int(viol_neg))
print("检出为否的行数:", int(mask.sum()))

这两段代码的作用不同:前一段给出可信的区间,后一段确认数据本身没有破坏层级。第二段的输出理想情况下是零,如果不是零,说明标注或导出环节存在例外,需要在下游按行排除,而不是默默接受。

附录 E:如果只记五件事

  1. 它是 MIMIC-III 护理文书上的一层人工判定,不是新队列,也不是全量文本标注。
  2. 三项判定是层级链:检出、就诊相关、否定;后两问只在第一问为是时有定义。
  3. 否定为「是」表示概念被否定,短横线表示没问过,两者都不是阴性类。
  4. 概念边界由 MetaMap 给定,只能测判定,不能测发现。
  5. 认证访问加 DUA,禁止再分发与商用;引用要带版本 DOI。

需要更高工程化程度或合规出域的商业版本?

当前展示的公开版本适用于学术研究与原型验证。千方医数集依托三甲医院直采网络,提供经专家标注、符合伦理合规的专病数据集交易服务。

前往商城查看可交易产品 →
返回 AI-Ready 数据集