EHRSQL — 电子健康记录 Text-to-SQL 基准 AI-Ready Wikipedia

222 名医院人员问卷驱动的可信语义解析基准:24,411 问答对、230 模板、93.2% 时间敏感、含不可答问题

来源 KAIST EdLab(KAIST AI 研究生院)联合 Konyang University Hospital、Seoul Women's University url: https://github.com/glee4810/EHRSQL发布时间: 2026-09-28最后更新: 2026-09-28 阅读 21
EHRSQL — 电子健康记录 Text-to-SQL 基准 AI-Ready Wikipedia

信息速览

数据集名称EHRSQL — 电子健康记录 Text-to-SQL 基准 AI-Ready Wikipedia
数据类型24,411 问答对,230 问题模板,95MB+102MB SQLite,CC BY 4.0,JSON 源文件
规模222 名医院人员受访者(底层为 MIMIC-III 与 eICU 患者)
接入方式KAIST EdLab(KAIST AI 研究生院)联合 Konyang University Hospital、Seoul Women's University url: https://github.com/glee4810/EHRSQL
AI 就绪度

INFOBOX

数据集名称 EHRSQL
英文全称 EHRSQL: A Practical Text-to-SQL Benchmark for Electronic Health Records
别名/简称 EHRSQL、EHRSQL-2022、EHRSQL-ST、EHRSQL 2024(衍生共享任务版)
疾病分类 重症监护全疾病谱(ICD-11:1G4Z 脓毒症 / CB4Z 心力衰竭 / CA4Z 肺炎 / 8B6Z 急性肾损伤等;基准本身不按疾病划分,问题覆盖患者人口学、生命体征、实验室检验、用药、手术、费用与生存率)
SNOMED CT 133834002 Critical care medicine (procedure) / 309841001 患者病历查阅 / 409063005 Counselling(问题语义以结构化检索为主,非诊断编码任务)
数据模态 自然语言文本(英文问题)+ SQL 查询文本 + 关系型表结构(结构化 EHR)
AI 任务类型 Text-to-SQL / 语义解析、可信问答(拒答判定)、时间表达式理解、schema linking、Text-to-SQL 基准评测
样本总数 24,411 个问答对(22.5K 可答 + 1.9K 不可答,数据卡口径);当前公开发布 22,505 条可执行 SQL
数据大小 约 13 MB(仓库整体);预处理 SQLite:MIMIC-III 版 95 MB + eICU 版 102 MB
数据格式 JSON(问答对与表结构)/ SQLite(可直接执行查询的预处理库)
许可证 CC BY 4.0(数据集);底层数据库另受 PhysioNet 凭证化协议约束
访问级别 开放(数据集 JSON 公开直链);重建数据库需 PhysioNet 凭证化申请
DUO 标签 GRU, HMB, PUB
语言 英文(问题与 SQL 均为英文)
首发日期 2022-12-06(NeurIPS 2022 Datasets and Benchmarks 会议)
最后更新 2026-04-28(v.1.5.1,问题文本微调;SQL 标注未变)
发布机构 KAIST Kim Jaechul Graduate School of AI(EdLab)
官方主页 https://github.com/glee4810/EHRSQL
下载地址 https://github.com/glee4810/EHRSQL/tree/main/dataset/ehrsql
DOI 10.48550/arXiv.2301.07695(arXiv v6)
引用次数 110+(Google Scholar,截至 2026-09);51(Scopus)
AI 就绪度评分 ⭐⭐⭐⭐(4/5)— 有官方 train/valid/test 划分、可执行 SQLite 与完整评测脚本;扣分项:test 划分口径多变、底层库重建需 PhysioNet 凭证、不可答问题仅覆盖两类
页面状态 published

§0 E-E-A-T 信任声明与免责声明

医学审核者:千方病案医学编辑部交叉审核:§2 医学背景(重症监护病种、ICD-11 与 SNOMED CT 映射、临床检索任务定义)、§7 偏倚分析。

数据工程审核者:千方病案医学编辑部交叉审核:医疗 AI 数据工程师,审核范围:§4 DAIMS 数据字典、§5 数据划分策略、§6 预处理 Pipeline 和坑点。

审核日期:2026-09-05

审核方式:交叉审核

利益冲突声明:千方病案医数集与 KAIST、Konyang University Hospital、PhysioNet 及 MIMIC-III/eICU 的维护方无任何商业利益关联。本页面不销售 EHRSQL 数据集本身,仅提供 AI 就绪指南与学术信息服务。编辑者未接受上述机构的任何形式资助。

医疗免责声明:本页面提供的医学信息仅供研究和教育目的,不构成医疗建议、诊断或治疗方案。数据集的医学描述基于公开发表的文献,未经逐一临床验证。任何基于该数据集训练的 AI 模型在应用于临床决策前,必须经过独立的临床验证和监管审批。

技术免责声明:本页面的代码示例、预处理建议和基准性能数据基于公开资料整理,不保证在特定环境下的准确性和适用性。使用者应自行验证代码安全性和数据预处理流程的正确性。千方病案医数集不对因使用本页面信息而导致的任何直接或间接损失承担责任。

数据使用合规:使用本页面描述的数据集前,请务必阅读并遵守数据集原始许可协议。数据集本体采用 CC BY 4.0;其 SQL 标注所依赖的 MIMIC-III 与 eICU 数据库要求用户完成 CITI Program 的 “Data or Specimens Only Research” 培训并通过 PhysioNet 凭证化申请、签署数据使用协议(DUA)。DUO 标签仅供参考,具体使用限制以数据集官方协议为准。


§1 数据集概览

§1.0 30 秒速览

这是什么? EHRSQL 不是一份病历数据库,而是一套"提问—查库"的对照答案册:222 名医院工作人员被问"你平时最想从系统里查到什么",他们把真实问法写下来,研究者再把这些问法整理成 230 条模板、扩充为 24,411 个问答对,并为每一个问题人工写出能在 MIMIC-III 或 eICU 数据库上直接跑出答案的 SQL 语句。换句话说,它把"医生护士会怎么问"和"该用什么 SQL 去查"这两端对齐了。

为什么重要? 医疗数据大多躺在关系型数据库里,而临床人员不会写 SQL。Text-to-SQL(文本转 SQL)模型承诺解决这道鸿沟,但此前的医疗基准要么问题太简单(MIMICSQL 只涉及 5 张表且句式重复),要么根本不是真实提问。EHRSQL 用问卷把"真实提问习惯"引入数据集:93.2% 的查询带时间条件,平均跨 13.5 张表,还专门收录了一批数据库根本答不上来的问题——模型必须学会说"我不知道",而不是硬编一条 SQL 去查出一堆错数据。

我能用它做什么? 三件事:一是训练和评测医疗领域的语义解析模型;二是研究"拒答"——当问题超出数据库能力时,模型多大的不确定性阈值才合适;三是拿它做真实部署前的压力测试,因为它把"平均嵌套 2.7 层"“时间表达三类型”"跨库同问不同 SQL"这些工程细节都显式标了出来。数据集本体采用 CC BY 4.0,JSON 部分直接在 GitHub 公开可下。

§1.1 摘要

EHRSQL 的构建逻辑可以概括为"先收问题、再造数据、最后标注 SQL"三步。第一步是真实提问采集:2021 年 2 月,团队在韩国大田的 Konyang University Hospital 通过 SurveyMonkey 发起问卷,请医院人员"像对着 AI 音箱提问一样,写下你经常需要从结构化 EHR 里查的东西",同时给出反面示例(需要外部知识、含糊、问临床决策理由的问题),最终回收 1,742 条语句、222 名有效受访者。第二步是模板化与扩增:把语义重复的表述合并为 230 条问题模板(174 条可答 + 56 条不可答),每条模板带槽位(如 {patient_id}、{drug_name}),再通过"操作值采样 → 时间模板采样 → 条件值采样"三级流水线把模板炸开成成千上万个具体问题。为保证语言多样性,人工先做平均 21 条/模板的改写,再用 T5 改写器与多语言回译生成机器释义,经 RoBERTa-large 去重、GPT-Neo 困惑度排序,最后交由众包公司 Selectstar 的三组标注员全票通过,剩下平均 47 条机器释义/模板。

第三步是 SQL 标注。四名研究生耗时五个月、多轮修订,为 MIMIC-III v1.4 与 eICU-CRD v2.0 两个库逐条标注 SQL。这里有一个反直觉的设计选择:刻意回避 JOIN,改用嵌套子查询。原因在于 MIMIC-III 的 chartevents 表有约 3.3 亿行,多个表超过一亿行,把大表全连起来效率极低;而临床提问往往先定位到某个患者或某次住院,再逐层下钻——嵌套结构恰好匹配 EHR 的层级组织方式,实测某些场景下比朴素 JOIN 快近四倍。

最终产物是一个三合一基准:宽需求 SQL 生成、时间表达式理解、可答/不可答判别。论文将其命名为"可信语义解析(trustworthy semantic parsing)",并给出 T5-base 基线:在不做拒答阈值处理时,MIMIC-III 验证集上的可执行 F1(F1_exe)为 77.8%;加上基于预测熵的 67 分位阈值后升至 93.8%。这个巨大落差本身就是数据集想要暴露的问题。

§1.2 战略价值

价值一:把"真实提问分布"变成可复用资产。 绝大多数 Text-to-SQL 数据集的问题是"研究者造的问法",Spider 用众包标注员对着 schema 造句,MIMICSQL 用预定义模板自动生成。EHRSQL 的独特之处是问题作者在提问时看不到数据库 schema——问卷受访者只知道"我要查什么",不知道数据里有哪些表哪些列。这一设定把 schema linking(自然语言指代 → 表/列/值的对齐)的难度还原到了真实水平,也让数据集能测出模型"猜表名"的能力边界。论文把这一条作为与 KaggleDBQA、SEDE 并列甚至更进一步的设计(KaggleDBQA 同样是未看 schema 的真实用户提问,EHRSQL 在此之上追加了不可答问题维度)。

价值二:把"拒答"做成一等公民评测维度。 医疗问答系统的失败代价不对称:答错比不答危险得多。EHRSQL 是首个在 Text-to-SQL 语境下把可答与不可答问题一起从真实问卷中收集并组合的尝试。不可答分两类:超出数据库 schema(如"患者下次最早就诊是什么时候"——数据库里没有未来就诊记录)、需要外部领域知识(如"这种药的副作用是什么"——药典不在库里)。评测采用 F1_ans 与 F1_exe 双指标:前者衡量"识别出哪些问题可答",后者只在"答案真的查对了"时才计分——两者的差值直接暴露模型的 schema 能力与 SQL 生成能力之间的鸿沟。

价值三:为"时间敏感查询"提供系统化的标注框架。 论文把时间过滤拆成三类:全局时间过滤([time_filter_global],限定关注的时间总范围)、区间时间过滤([time_filter_within],刻画两个医疗事件之间的时间窗)、精确时间过滤([time_filter_exact],指向"最后一次""首次"或某个具体时刻)。每类再配三个因子:表达类型(绝对 / 相对 / 混合)、时间单位(年/月/日,或医院就诊/ICU 就诊这类任意事件单位)、区间类型(since / until / in)。93.2% 的查询至少用一个时间列——对比之下 Spider 只有 12.7%。这套框架把"医疗提问里的时间到底怎么标"从经验问题变成了可枚举的工程问题,也是后续 EHR 问答基准广泛借用的设计。

§1.3 同类数据集横向对比

论文 Table 4 给出了 EHRSQL 与通用域及医疗域 Text-to-SQL 基准的正面对比。补充说明:emrKBQA 一行在原表中标注"尚未公开发布",MIMICSQL 的"10K"为论文引用其规模时的口径。

数据集 样本数 库数 表数/库 行数/表 表数/查询 嵌套层/查询 含时间列查询占比 提问者未看 schema 含不可答问题
Spider † 8K 160 5.1 2K 1.6 1.2 12.7% ✗ ✗
KaggleDBQA 0.3K 8 2.3 280K 1.2 1.0 17.3% ✗ ✗
SEDE 12K 1 29 — 1.8 1.3 20.2% 部分(真实用户提问) ✗
MIMICSQL 10K 1 5 7K 1.8 1.0 26.6% ✗ ✗
EHRSQL 24K 2 13.5 108K 2.4 2.7 93.2% ✓ ✓

† Spider 一行仅统计训练与验证集。这张表最值得盯住的两个数字是 93.2% 与 2.7:前者意味着几乎每条查询都要处理时间条件,后者意味着平均每条查询的嵌套深度是 Spider 的两倍以上。对选型者的含义很直接——凡是把通用域的 Text-to-SQL 模型直接搬到医疗场景的尝试,都会在这两个维度上被拉开差距(§8.1 的 GAP 跨域实验给出了量化证据:EHRSQL 可答问题中只有约 7% 能被 Spider 语法解析)。

§1.4 版本时间轴

时间 事件 关键内容
2021-02 问卷采集 Konyang University Hospital,1,742 条语句 / 222 名受访者
2021-2022 模板化与 SQL 标注 230 条模板;4 名研究生 5 个月人工标注双库 SQL
2022-06-08 GitHub 仓库建立 glee4810/EHRSQL 创建
2022-09-17 OpenReview 收录 NeurIPS 2022 D&B Track 投稿公开
2022-12-06 论文正式发表 NeurIPS 2022(35 卷,pp. 15589-15601)
2023-01-16 arXiv v1 上线 arXiv:2301.07695
2023-02-22 排行榜网站 trustworthy semantic parsing 任务站点上线
2023-04-30 标注修正 修正次要标注错误与标签不一致
2024-01-29 EHRSQL-2024 共享任务启动 NAACL 2024 ClinicalNLP;改用 MIMIC-IV demo
2024-04-27 全量数据公开 含 test 划分的完整数据集发布
2024-06-22 EHRSQL 2024 概览论文 arXiv:2405.06673;共享任务总结
2026-03-04 arXiv v6 论文最新修订版
2026-03-09 数据集 v.1.5.0 SQL 质量修订(1,840 条 ORDER BY 改相关子查询等)
2026-04-28 数据集 v.1.5.1 问题文本微调(时间表达、标点、eICU 生命体征分词)

§1.5 典型应用场景

  1. 医疗 Text-to-SQL 模型训练与评测:作为 MIMIC-III/eICU 场景的标准测试床,用于衡量模型在真实提问分布下的执行准确率。
  2. 拒答与不确定性研究:数据集天然提供"哪些问题该拒答"的标签,适合研究基于熵、基于置信度校准、基于聚类阈值的弃权策略。
  3. 时间表达式理解研究:三类型 × 三因子的时间标注框架,可用于研究相对时间(“上个月”)在数据库时间平移语境下的解析。
  4. schema linking 与嵌套 SQL 生成研究:平均 2.4 表/查询、2.7 层嵌套,为研究"先定位再下钻"的查询分解策略提供标注。
  5. 跨库迁移与多方言研究:同一批问题同时在 MIMIC-III 与 eICU 两个 schema 上标注 SQL,可用于研究"同一语义、不同表结构"的迁移能力。

§2 医学背景

§2.1 ICD-11 编码映射

EHRSQL 本身不面向疾病分类任务,其问题覆盖的是跨病种的临床信息检索需求。下表把数据集中高频出现的检索对象映射到 ICD-11 相关章节,用于帮助理解"这些问题在临床上关心什么"。映射为编辑部分析性对应,非数据集自带标注。

检索对象 ICD-11 编码 中文名 在数据集中的形态
感染性疾病(脓毒症等) 1G4Z 脓毒症 “有多少患者在诊断为 X 后用了 Y 药”
循环系统疾病 CB4Z / BA00 心力衰竭 / 高血压 “高血压患者用了什么药缓解头痛”(不可答示例)
呼吸系统疾病 CA4Z / CA23 肺炎 / 哮喘 “有多少患者接受了临时气管造口术”
泌尿系统疾病 8B6Z / GB61 急性肾损伤 / 慢性肾病 实验室检验值检索(钾、肌酐等)
内分泌与代谢 5A1Z / 5A11 糖尿病 / 2 型糖尿病 “患者确诊糖尿病后开了哪些药”
肿瘤 2A0Z-2F9Z 恶性肿瘤谱系 "N 年生存率"类群体统计查询
症状与体征 MG30 / MD81 疼痛 / 头痛 不可答示例中的"缓解头痛"

§2.1b SNOMED CT 映射

标签 ICD-11 SNOMED CT 术语
重症监护 — 133834002 Critical care medicine (procedure)
病历查阅 — 309841001 Patient record review
药物处方 — 33633005 Prescription of drug (procedure)
实验室检验 — 15220000 Laboratory test (procedure)
影像与操作 — 363000009 Medical procedure (procedure)
患者人口学 — 184096008 Personal details (observable entity)

需要说明:EHRSQL 的标注单位是"问题—SQL 对",不是"病例—诊断码对"。因此这里给出的是编辑部的语义映射参考,而非数据集内嵌字段。检索时若期望找到 SNOMED 编码列,会一无所获(见坑 6)。

§2.2 临床背景:为什么医疗提问难答

电子健康记录是"以关系型数据库形式存在的完整病史"。从入院、诊断、治疗到处方、检验、出院,所有医疗事件都被记录并存储。问题在于,医院人员与这些数据之间的接口长期依赖预定义规则转换系统:想查一条规则之外的信息,就得接受专门培训去修改系统。论文明确指出这是 EHR 价值释放的瓶颈,而 Text-to-SQL 是打破瓶颈的直接路径——用户直接说出需求,系统自动翻译成 SQL,把结果取回来。

但医疗提问有三个特殊性,使通用域的 Text-to-SQL 方法难以直接奏效。

第一,时间是一等公民。 临床提问极少是"某患者体重多少"这类静态查询,更多是"患者 6990 最后一次 ICU 就诊期间的日均胃药摄入量是多少"“自 2104 年起被诊断为低血压以来到现在是否在 2 个月内做过 X”。这类问题必须解析绝对时间、相对时间(今天/上个月/去年)与混合表达,还要处理"首次/末次"这类事件顺序语义。论文实测 93.2% 的查询至少引用一个时间列,而通用域基准只有 12.7%。

第二,数据规模迫使查询必须"下钻"而非"全连"。 MIMIC-III 的 chartevents 表约 3.3 亿行,多个表超过一亿行,且记录以日志式累积。把需要的表全部 JOIN 起来在工程上不可行;实际有效的写法是先锁定患者或住院标识,再沿层级逐层嵌套子查询。因此 EHRSQL 的 SQL 标注刻意采用嵌套风格,这也使多数查询无法被 Spider 语法解析器接受。

第三,真实提问里混着答不了的问题。 问卷明确收集了这类提问:问药物副作用(需要药典)、问下次复诊时间(数据库无未来数据)、问患者是否签过知情同意书(不在 schema 内)。系统必须能识别并拒答——在临床上,编造一条 SQL 查出一堆似是而非的数字,比直接说"我答不了"危险得多。

§2.3 临床任务定义

EHRSQL 定义的任务是"可信语义解析(trustworthy semantic parsing)",可拆解为三个必须同时满足的子能力:

子任务 定义 评测方式
宽需求 SQL 生成 生成能反映医院日常工作多样需求的 SQL,从简单检索到复杂运算(如计算生存率、top-N 用药) 执行准确率(F1_exe)
时间表达式理解 正确解析绝对 / 相对 / 混合时间表达,答时间敏感问题 分时间类型的结果对比(论文附录 H.2)
可答性判别与拒答 基于预测置信度判断问题是否可答,不可答时主动弃权而非硬查 F1_ans;熵阈值策略对比

三个子任务的耦合点在于:"能不能答"的误判会直接污染"答得对不对"的分数。F1_ans 与 F1_exe 的分母相同(都除以"预测为可答的问题数"或"实际可答的问题数"),但 F1_exe 的分子只在结果真的正确时计分——两个分数的差距越大,说明模型"识别可答"的能力与"真正查对"的能力之间的断裂越严重。

§2.4 患者人群

维度 MIMIC-III(SQL 标注目标库一) eICU(SQL 标注目标库二)
来源 美国波士顿 Beth Israel Deaconess Medical Center 重症监护单元 美国多中心 ICU(多机构协作)
时间范围 2001-2012 年入住 2014-2015 年出院
规模 超过 40,000 名患者 超过 200,000 次 ICU 入住
就医类型 ICU 重症监护 ICU 重症监护(多中心)
在 EHRSQL 中的角色 主要标注库;论文首度在 eICU 上标注 SQL 之外,MIMIC-III 承接历史基准(MIMICSQL)的对照 首个被标注 SQL 的 eICU 问答数据集,使多中心重症提问可被回答
时间处理 原始时间跨度被去标识打散至百年以上(原为七年);EHRSQL 把入院时间统一平移到 2100-2105 原始时间跨度保持完整(两年);同样平移到 2100-2105 以对齐两库

提问者人群同样重要:问卷受访者是 222 名医院工作人员,涵盖医师、护士、医保审核团队与病案团队,从业年限各异。论文 Figure 1 按科室与经验年数给出了受访者人口学分布。这一点决定了数据集的"提问风格"是医院职场风格,而非研究者风格。

§2.5 临床价值

对医院信息科而言,EHRSQL 提供了一份"真实需求清单":这些问题本身就是下一个 EHR 报表系统该优先支持什么功能的依据。对临床 AI 团队而言,它提供了一个明确的落地门槛——模型必须先学会在不确定时闭嘴,才能被允许进入临床流程。对数据治理团队而言,它的去标识方案(在 PhysioNet 已脱敏的基础上再做全库值打乱)是一份可参考的"二次脱敏"范式:保持问题的语义结构不变,让采样出的条件值无法回溯到任何具体患者。

§2.6 金标准

环节 划分/标注方式 执行者 性质
问题来源 医院职场问卷(SurveyMonkey),受访者未见数据库 schema 222 名医院工作人员 真实需求,无 schema 先验
模板提炼 合并同义表述 + 人工补简单变体 论文作者 人工,230 条模板(174 可答 + 56 不可答)
释义扩增 人工改写(平均 21 条/模板)+ 机器改写 + 回译 作者 + T5/Styleformer/Parrot + 众包 混合,机器释义平均 47 条/模板
释义质控 三组众包标注员全票通过制 Selectstar 众包(约 $18/小时) 人工三票一致
SQL 标注 逐条人工标注,一标一审(每库一名复核者) 4 名研究生,5 个月,多轮修订 人工黄金标注
时间模板 三类型 × 三因子系统化枚举 作者 人工设计 + 程序采样
条件值采样 从数据库采样并要求 SQL 至少有一个有效答案 程序 自动校验(可执行性过滤)

关键性质:可答问题的 SQL 是人工黄金标注,且每条都必经"至少能查出非空结果"的可执行性校验;不可答问题不提供 SQL 标签,且在训练集中完全不出现——这使数据集的不可答检测成为一个真正的泛化任务而非记忆任务。

§3 数据集规格

§3.0 版本抉择矩阵

EHRSQL 的"版本"有两层含义:数据集本身的迭代(v1.0 → v1.5.1),以及基于同一批模板派生的任务变体(原始 EHRSQL vs EHRSQL-2024 共享任务)。选型前必须先确定自己在哪条线上。

你的需求 推荐版本 规模 理由
复现 NeurIPS 2022 论文结果 EHRSQL 原始版(MIMIC-III + eICU) 22,505 条 SQL / 约 13 MB 唯一与论文 Table 5 基线数字(F1_exe 77.8 等)对齐的版本
做拒答 / 不确定性研究 EHRSQL 原始版 valid 划分 每库约 1.1K 样本、其中 33% 不可答 不可答问题只在 valid/test 出现,训练集纯净
需要免申请、可商用 API 的开发环境 EHRSQL-2024(MIMIC-IV demo) train 5,124 / valid 1,163 / test 1,167 demo 库公开可下,无需 PhysioNet 培训,schema 与全库一致
需要最严格的可靠性评测 EHRSQL-2024 的 RS(10) / RS(N) 口径 同一批问题,多档惩罚 主指标 RS(10) 让一次错误等价于十次正确
需要最新标注质量 v.1.5.1(2026-04-28) 22,505 条 SQL 全部可执行 修复了非确定性排序、NULL 传播、COUNT 语义三类系统性缺陷
需要与历史论文数字对比 你所用论文对应的版本 依论文 v.1.5.0 有 12.9% 的 SQL 修复改变了实际查询结果,跨版本对比必须注明

版本抉择的陷阱:v.1.5.0 的 SQL 修复中有 12.9% 改变了查询结果——这意味着用 v1.5.x 数据评测出的分数,与 2024 年前论文报告的数字不可直接比较。做文献对标时必须先确认对方用的是哪个版本(见坑 3)。

§3.1 模态详情

模态 内容 格式细节
自然语言问题 英文问句,含槽位填充后的具体值 每条记录一个 question 字段;template 保留原始模板形态
SQL 查询 可在 SQLite 上直接执行的 SQL 语句 嵌套子查询为主,刻意回避 JOIN;含 strftime、datetime 等时间函数
表结构 两库的表名、列名、类型、外键、主键 沿用 Spider 的 tables.json 字段规范,附原始名与规范化名两套
时间模板 三类过滤类型 × 三因子的枚举定义 同时给出自然语言时间表达与 SQL 时间模式(pattern)配对
标签元数据 部门、重要性、释义来源、可答性、划分 department / importance / para_type / is_impossible / split
可执行数据库 预处理后的 SQLite 单文件 MIMIC-III 版 95 MB、eICU 版 102 MB

§3.2 按子集样本数

原始 EHRSQL(论文 §4.1 口径,划分按每个数据库分别统计):

划分 每库样本数 不可答占比 说明
train 约 9,300 0% 不含不可答问题(OOD 设定)
valid 约 1,100 33% 公开
test 约 1,800 33% 论文设计为隐藏测试集,2024-04-27 后随全量数据公开
合计 约 12,200 / 库 — 两库合计约 24,411 个问答对

公开数据量与论文口径的对应关系(存照):数据卡写"about 24.4K instances(22.5K answerable; 1.9K unanswerable)“,而官方 CHANGELOG 的验证口径是"22,505 条 SQL 全部执行成功”——后者是当前发布版中带 SQL 标签(即可答)的条数。两者非矛盾,但引用时必须注明用的是哪个口径(见坑 2)。

EHRSQL-2024 共享任务(MIMIC-IV demo,论文 Table 1 口径):

划分 可答模板数 可答样本 不可答样本 总样本
train 100(全部 seen) 4,674 450 5,124
valid 134(100 seen + 34 unseen) 931 232 1,163
test 134(100 seen + 34 unseen) 934 233 1,167

2024 版最关键的设计变化是引入 unseen 模板:34 条验证/测试专属模板在训练集中从未出现,用以模拟真实部署中"schema 能答但没见过这种问法"的场景。此外每个划分的不可答占比从原始的 33% 降为 20%,但补充了来自 TrustSQL 的对抗性不可答问题(引用不存在的列、要求超出 SQL 能力的绘图等),难度反而更高。

§3.3 格式

文件 格式 内容
dataset/ehrsql/mimic_iii/train.json JSON MIMIC-III 训练问答对(字段见 §4.1)
dataset/ehrsql/mimic_iii/valid.json JSON MIMIC-III 验证问答对(含不可答条目,字段更少)
dataset/ehrsql/mimic_iii/test.json JSON MIMIC-III 测试问答对
dataset/ehrsql/eicu/train.json 等 JSON eICU 对应三个划分
dataset/ehrsql/tables.json JSON 两库表结构(Spider 风格)
dataset/ehrsql/CHANGELOG.md Markdown 版本变更明细(v1.5.0 / v1.5.1)
mimic_iii.sqlite / eicu.sqlite SQLite 预处理后的可执行库(Google Drive 分发)

§3.4 存储大小

资产 大小 说明
GitHub 仓库(含代码、配置、论文材料) 约 13 MB(size 字段 13044 KB) 不含 sqlite 与模型权重
MIMIC-III 预处理 SQLite 95 MB 含患者采样、二次去标识、时间平移与新增 cost 表
eICU 预处理 SQLite 102 MB 同上
两库合计数据库 197 MB 便于本地复现,无需重建

§3.5 标注方式

EHRSQL 的标注是"人工为先、程序为辅、众包把关"的三段式:

  1. 人工设计层:问题模板、时间模板、SQL 查询三者均由人工定义。SQL 由 4 名研究生标注,一人标注、一人复核(每个数据库配一名复核者),历时五个月并多轮修订。
  2. 程序采样层:三级采样把模板扩增为具体问题——操作值采样(与 schema 无关的预定义值,如最大值、五年、两次以上)、时间模板采样(依模板支持的时间过滤类型)、条件值采样(从数据库实际记录取值)。采样完成后强制校验"该 SQL 至少能查出非空答案",不通过则丢弃。
  3. 众包质控层:机器生成的释义由 Selectstar 组织三组标注员逐条标记 pass/fail,只有全票通过的才进入最终数据集,最终平均保留 47 条释义/模板。

§3.6 标注者资质与一致性

环节 人员 资质/报酬 一致性控制
问卷 222 名医院人员 每人一张价值 $10 的咖啡礼品卡 提供反面示例(外部知识 / 含糊 / 问决策理由)以统一理解
SQL 标注 4 名研究生(论文作者) 未外包(因涉及患者信息且需大量假设) 一标一审,每库一名复核者;多轮修订
释义质控 Selectstar 众包标注员 约 $18/小时 三组独立标注,全票通过制
重要性标注 一名医师 医院内部专家 标为 high / medium / low / n/a

论文明确说明:SQL 标注未使用众包,原因是数据库含患者特异信息、且标注过程需要大量隐性假设(哪个医疗事件映射到哪一列、选哪个排序函数、何时该用 DISTINCT)。这也是 EHRSQL 与大三众包数据集在质量成本结构上的根本差异。

§3.7 采集周期

问卷于 2021 年 2 月执行。论文注明"结果对采集日期依赖不大"。模板化与 SQL 标注跨越 2021 至 2022 年(SQL 标注历时五个月),论文于 2022 年 12 月在 NeurIPS 2022 发表,arXiv 版本 2023 年 1 月上线,最新修订版本为 2026 年 3 月的 v6。数据集本身持续维护至 2026 年 4 月的 v.1.5.1。

§3.8 地域覆盖

问卷来源为韩国大田的 Konyang University Hospital——这是论文明确列出的首要局限:单一韩国大学医院的提问习惯未必代表全球其他医院。而 SQL 标注所依赖的两个数据库均来自美国(MIMIC-III 波士顿单中心、eICU 美国多中心),因此数据集中混着两层地域特征:提问的语用是韩国的,数据的分布是美国的。使用者需要意识到"问题措辞的美国化程度"与"临床场景的韩国化程度"并不一致。

§3.9 设备规格与时间处理

EHRSQL 不涉及影像或信号采集设备。其工程规格集中在数据库侧:

规格项 值
数据库引擎 SQLite(>= 3.33.0)
时间平移区间 入院时间平移至 2100-2105 年
当前时间设定 2105-12-31 23:59:00(晚于此刻的记录全部删除)
患者采样比例 --cur_patient_ratio 0.1(保留 10% 当前在院患者)
时间跨度参数 --start_year 2100 --time_span 5
新增表 cost 表(列名参照 OMOP CDM v5.4)
训练硬件 NVIDIA GeForce RTX 3090(T5-base 基线)

为什么要把时间平移到 2100 年? 两个原因。一是 MIMIC-III 因去标识处理,时间跨度被打散到百年以上,与 eICU 的两年跨度无法对齐;平移到统一的 2100-2105 才能让"同一批问题在两库上有可比的答案"。二是临床提问大量使用"今天"“上个月”“今年"这类相对时间表达,必须先定义一个"当前时间”,模型才有参照点。设定的 2105-12-31 23:59:00 还有一个副作用:缺失出院时间的患者自然成为"当前在院患者",无需额外规则。

§3.10 深度溯源链

Konyang University Hospital 问卷(2021-02,222 人,1,742 条语句)
   ↓ 过滤 + 模板化(230 模板:174 可答 + 56 不可答)
   ↓ 人工改写(平均 21 条/模板)+ 机器改写/回译 + 众包全票通过(平均 47 条/模板)
   ↓ 三级采样:操作值 → 时间模板 → 条件值(校验 SQL 至少有一个有效答案)
   ↓ 人工标注 SQL(4 名研究生 / 5 个月 / 一标一审)for MIMIC-III v1.4 与 eICU-CRD v2.0
   ↓ 数据库预处理:患者采样 → 二次去标识(全库值打乱)→ 时间平移(2100-2105)→ 新增 cost 表
EHRSQL 数据集(JSON + SQLite,CC BY 4.0)
   ↓ 2024 派生:EHRSQL-2024 共享任务(改用 MIMIC-IV demo,新增 unseen 模板 + TrustSQL 对抗不可答)
   ↓ 生态派生:EHRXQA(多模态)、EHRSQL-ST(评估资源)、EHR-SeqSQL(顺序任务分解)、ClinSQL

溯源链上最值得注意的一环是"全库值打乱":它在 PhysioNet 既有脱敏之上再加一层,使得问题中出现的具体条件值(如某患者 ID 对应的用药名)无法回溯到真实患者。代价是——预处理后的 SQLite 不再是真实的临床数据库,不能用于任何临床分析或流行病学统计。官方 README 原文写明:“Patient values have been shuffled and are not linked to original records; the databases are intended for SQL query evaluation, not for clinical analysis.”


§4 数据结构

§4.0 目录树

EHRSQL/
├── dataset/
│   └── ehrsql/
│       ├── CHANGELOG.md              # v1.5.0 / v1.5.1 变更明细
│       ├── tables.json               # 两库表结构(Spider 风格)
│       ├── mimic_iii/
│       │   ├── train.json            # 字段最全,见 §4.1
│       │   ├── valid.json            # 含不可答条目(字段较少)
│       │   ├── test.json             # 同上
│       │   └── mimic_iii.sqlite      # 95 MB,需单独下载(Google Drive)
│       └── eicu/
│           ├── train.json
│           ├── valid.json
│           ├── test.json
│           └── eicu.sqlite           # 102 MB,需单独下载
├── preprocess/
│   └── preprocess_db.py              # 从 PhysioNet 原始 CSV 重建库
├── T5/
│   ├── main.py                       # T5-base 训练与推理入口
│   ├── abstain_with_entropy.py       # 基于最大熵的拒答阈值脚本
│   └── config/ehrsql/                # 训练与评测 YAML 配置
├── gpt/
│   ├── codex.py                      # Codex 提示式 SQL 生成(无拒答)
│   └── prompts/codex_apidoc.txt      # 提示模板
├── evaluate.py                       # 执行准确率评测入口
├── t5_threshold.ipynb                # 阈值实验笔记本
└── utils/                            # 数据处理工具

目录树使用要点:JSON 文件(问答对与表结构)在 GitHub 仓库内直接可下;两个 .sqlite 文件不在仓库内,需从 Google Drive 单独下载并按上述路径放置,否则 evaluate.py 会因找不到库文件而失败(见坑 5)。

§4.1 DAIMS 字段字典

下表按 DAIMS(Data and Information Management System)八列规范解析问答对记录的核心字段。示例值取自论文与官方 README 的样例记录。

字段名 类型 说明 示例值 AI 用途 观测误差 信息性缺失编码 取值范围
id string 每条问答对的唯一标识 "294c4222b4ad35fbe4fb9801" 主键、去重、划分追踪 无 无 24 位十六进制串
db_id string 目标数据库标识 "mimic_iii" 多库路由、跨库对比 两库划分独立,注意区分 无 mimic_iii / eicu
question string 释义后的自然语言问题 "what is the ingesting method of methimazole?" 模型输入 槽位填充可能导致语法不自然 无 自由文本
template string 原始模板问题(未释义) "what is the intake method of methimazole?" 模板级分析、去泄漏校验 无 无 自由文本
query string 对应的可执行 SQL "select distinct prescriptions.route from prescriptions where prescriptions.drug = 'methimazole'" 监督信号 / 金标准 不可答条目为 "nan" 不可答 → "nan" SQL 文本
value object 从数据库采样的条件值键值对 {"drug_name": "methimazole"} 槽位还原、schema linking 值为打乱后的值,非真实记录 无槽位时为空 依模板而定
q_tag string 问题模板标签(带槽位占位符) "what is the intake method of {drug_name}?" 模板聚类、泄漏检测 无 无 占位符文本
t_tag array 采样的时间模板标签 ["", "", "", "", ""] 时间表达类型统计 空串表示未启用该维度 空串 "" 5 元组
o_tag array 采样的操作值标签 ["", "", "", "", "", "", "", "", ""] 操作语义分析 同上 空串 "" 9 元组
tag string q_tag + t_tag + o_tag 的组合标签 "what is the intake method of {drug_name}?" 组合泛化分析 无 无 组合文本
department array 提问采集自哪个科室 "['nursing']" 科室维度切分、公平性分析 单条可含多科室 无 科室名列表
importance enum 该问题在医院中的重要性 "medium" 测试集加权采样 由一名医师主观标注 n/a high / medium / low / n/a
para_type enum 释义来源 "machine" 释义质量对比、人工/机器分层分析 无 无 machine / human
is_impossible bool 问题是否不可答 false 拒答监督标签 不可答问题属"补集"性质,非穷举 无 true / false
split enum 所属数据划分 "train" 划分校验 无 无 train / valid / test

字段字典的三个使用要点:

  1. 不可答条目字段更少。train.json 中所有条目字段齐全,但 valid.json / test.json 中的不可答条目只有 db_id、question、query(值为 "nan")、department、para_type、is_impossible、split、id 八个字段——没有 template、q_tag、t_tag、o_tag、tag、value、importance。写解析代码时必须先判 is_impossible 再访问其余字段,否则会 KeyError(见坑 4)。
  2. t_tag / o_tag 是定长数组。空串代表"该维度未启用",不是缺失值。做时间类型统计时不能把空串当作一类,否则会得到虚高的"无时间"比例。
  3. query 为 "nan" 是字符串而非 NaN 值。JSON 里这是字符串 "nan",用 pandas 读入后可能被推断为 float('nan'),两种情形都要处理。

§4.2 标签分布

维度 分布 来源
可答性 可答约 22,500(92.2%)/ 不可答约 1,900(7.8%) 数据卡 §A.2
划分(每库) train 9.3K / valid 1.1K / test 1.8K 论文 §4.1
不可答在 valid/test 中的占比 各 33% 论文 §4.1
提问者科室 医师、护士、医保审核、病案团队等 论文 Figure 1
重要性 high / medium / low / n/a 四档(测试集按 3/2/1 加权) 论文附录 F
释义来源 human(人工)+ machine(机器) para_type 字段
患者范围 单患者 / 患者群体 / 无关患者 三类 论文 §3.1.1
时间表达类型 绝对 / 相对 / 混合 论文 §3.1.2

§4.3 关键统计

指标 EHRSQL 对比基线(Spider)
平均表数/查询 2.4 1.6
平均嵌套层数/查询 2.7 1.2
含至少一个时间列的查询占比 93.2% 12.7%
平均涉及不同表数(跨库总览) 13.5 5.1
可被 Spider 语法解析的验证集问题比例 约 7%(107/1,515) 100%
单表行数上限 约 3.3 亿行(chartevents) 约 2,000 行

§4.4 数据层级

EHRSQL 的语义层级是"问题 → 模板 → 实例",数据库侧则是"患者 → 住院 → ICU 停留 → 事件日志":

问题模板(230 条,带槽位)
   ├─ 释义(人工 ~21 条/模板 + 机器 ~47 条/模板)
   └─ 实例化(三级采样:操作值 → 时间模板 → 条件值)
          └─ 每条实例 ⇄ 一条 SQL(人工标注,按库各一份)

数据库层级(查询必须沿此下钻)
   MIMIC-III: patients → admissions → icustays → chartevents / labevents / prescriptions ...
   eICU:      patient → patientStay / hospital / microLab / medication / intakeOutput ...

层级设计的实践含义:SQL 标注"能嵌套就不 JOIN"的规则,正是为了匹配这个层级——先通过 subject_id 锁定患者,再用 hadm_id 锁定住院,再逐层筛选事件。论文附录 C.3 给出实测:朴素 JOIN 写法在某些查询上耗时约 0.15 秒,嵌套写法约 0.04 秒,相差近四倍。更重要的是 JOIN 会把多张大表笛卡尔式展开,在亿级行表上直接不可行。

§4.5 缺失值与信息性缺失编码

EHRSQL 的"缺失"不是数据缺陷,而是有语义的编码:

情形 编码方式 语义 处理建议
该维度未被采样 空串 ""(在 t_tag / o_tag 数组内) 该问题模板不涉及此时间/操作因子 统计时剔除,不当作缺失
问题不可答 query = "nan"(字符串) + is_impossible = true 数据库无法回答 作为拒答正样本,绝不可当 SQL 缺失插补
问题不涉患者 value 中无 {patient_id} 槽位 非患者特异问题(如"某种药的成本") 按患者范围分组分析
出院时间为空 SQL 中用 IS NOT NULL 守卫 患者在"当前时间"仍在院 v1.5.0 已批量补 148 处守卫(见坑 7)
重要性未标 importance = "n/a" 该问题不属重要性分层 测试集加权时按 1 计

§5 划分与使用建议

§5.1 官方划分

划分 构造规则 关键约束
train 按模板槽位数决定样本量:<3 槽位 → 30-60 对;3-4 槽位 → 40-80 对;≥5 槽位 → 50-100 对 不含不可答问题
valid 每模板采样 4-5 对 不可答占 33%
test 同 valid,但按重要性加权(high=3 / medium=2 / 其他=1) 不可答占 33%;原设计为隐藏测试集

最关键的划分约束:所有 230 条问题模板在每个划分中都出现,但同一模板的释义不在划分间重叠。这意味着划分切分的是"语言表达的变体",而不是"问题类型"。这一设计选择使数据集能测出模型对 paraphrase 的泛化,但也意味着模型在训练时已经见过所有问题类型——所以它不适合用于评测"面对全新问题类型的零样本迁移"。若需要后者,应使用 EHRSQL-2024 的 unseen 模板设计(34 条测试专属模板)。

§5.2 社区惯例划分

用法 做法 适用场景
原样使用 train 训练 / valid 调阈值 / test 上报 与论文数字对标
两库合并 MIMIC-III + eICU 合并训练,分库评测 研究跨库泛化(注意两库划分独立)
仅 MIMIC-III 只用一库 与 MIMICSQL 等历史基准对比
只取可答问题 过滤 is_impossible = true 纯 SQL 生成研究(放弃拒答维度)
阈值调参子集 从 valid 中划出 10% 做超参搜索 第三方复现研究(CELEC 等采用此模式)

§5.3 泄漏风险

EHRSQL 有三处必须主动防范的泄漏点:

泄漏点一:患者 ID 在划分间共享。 论文附录 F 明确讨论过这一点——数据集不是按患者划分的。同一位患者(如 patient 100)的"性别是什么"在训练集,而"最后一次血压是多少"可能在验证集。这是有意为之:按患者划分会让任务变得过于容易(模型只需记住某患者的所有记录),而 EHR 提问的本质是"同一患者的不同属性查询"。但对使用者来说,这意味着任何基于患者 ID 的记忆型模型都会在评测中虚高。如果你的研究目标是"模型对新患者的泛化",必须自行按 subject_id 重新划分。

泄漏点二:模板释义的跨划分污染。 官方约束是"模板全划分出现、释义不重叠"。但人工与机器释义共享同一个模板语义,释义层面的表述相似度很高——同一模板的 21 条人工释义与 47 条机器释义之间,词汇重叠可能高于跨模板样本。若你的评测对表述鲁棒性敏感,建议做模板级的交叉验证(即把同一模板的所有释义放在同一侧)。

泄漏点三:机器释义的生成模型。 释义由 T5 改写器、Styleformer、Parrot 与多语言回译生成,v1.5.0 的问题改写又用了 GPT-4o-mini。如果被测模型也是 T5 系或与这些改造工具同源,可能存在隐式的分布贴合。做 SOTA 对比时应检查被测模型的预训练数据是否可能包含 EHRSQL 本身。

§5.4 交叉验证建议

策略 实施方式 适用场景
模板级 K 折 按 q_tag 分组做 5 折 评测模板级泛化(推荐,避免泄漏点二)
患者级 K 折 按 subject_id 分组(需从 SQL 文本提取) 评测患者级泛化(避免泄漏点一)
库级留一 一库训练、另一库测试 评测跨 schema 迁移
时间类型留一 按 t_tag 组合留出某一时间表达类型 评测时间泛化

§5.5 外部验证建议

EHRSQL 天然自带一次"外部验证"机会:同一批问题在 MIMIC-III 与 eICU 两个 schema 上分别标注了 SQL。因此可以设计"MIMIC-III 训练 → eICU 测试"的跨库协议。论文的 Table 6 给出了一个更极端的版本:让在通用域(Spider/MIMICSQL)训练有素的 GAP 模型零样本迁移到 EHRSQL,结果在可解析子集上仅得 4.7%(5/107),而在 MIMICSQL 全集上有 16.4%——说明医疗场景的复杂度不能靠通用域能力补齐。此外,EHRSQL-2024 用 MIMIC-IV demo 重建的同源任务,也可作为"schema 换代后模型是否仍然可用"的外部验证场景。

§6 AI 就绪指南

§6.0 云端快速启动

EHRSQL 官方提供两份 Google Colab 笔记本,可在无本地 GPU 的情况下跑通 T5-base 训练:

笔记本 用途 是否含 schema
MIMIC_III_T5_Base.ipynb MIMIC-III 训练(不含 schema 序列化) 否
MIMIC_III_T5_Base_WithSchema.ipynb MIMIC-III 训练(问题后附加 schema 信息) 是

另有 evaluations.ipynb(离线本地运行,输出各评测指标)与 training_log_analysis.ipynb(分析平均 epoch 时间与训练损失曲线)。注意 Codex 路径(gpt/codex.py)尚未实现拒答能力,只能用于纯 SQL 生成对比。

§6.1 快速上手

以下代码假设的目录结构(与 §4.0 目录树一致):仓库根目录为 EHRSQL/,数据在 EHRSQL/dataset/ehrsql/,两个 sqlite 文件已按 mimic_iii/mimic_iii.sqlite 与 eicu/eicu.sqlite 放置。data_root 指向仓库根,其余路径均由它拼接。最小可用子集是单个 JSON 文件 + 对应的 sqlite——只想验证流程的话,mimic_iii/valid.json 加 mimic_iii.sqlite 就够了。

"""EHRSQL 最小上手:环境自检 + 读取一个问答对 + 实际执行其 SQL。

目录结构预期(data_root 之下):
  dataset/ehrsql/mimic_iii/{train,valid,test}.json
  dataset/ehrsql/mimic_iii/mimic_iii.sqlite   <- 需从 Google Drive 单独下载
  dataset/ehrsql/eicu/{train,valid,test}.json
  dataset/ehrsql/eicu/eicu.sqlite
"""
import json
import sqlite3
from pathlib import Path

data_root = Path("/path/to/EHRSQL")          # 改成你的仓库根目录
db_id = "mimic_iii"                           # 或 "eicu"
split = "valid"

json_path = data_root / "dataset" / "ehrsql" / db_id / f"{split}.json"
sqlite_path = data_root / "dataset" / "ehrsql" / db_id / f"{db_id}.sqlite"

# (1) 读 JSON:先判 is_impossible,再访问其余字段(不可答条目字段更少)
records = json.loads(json_path.read_text(encoding="utf-8"))
answerable = [r for r in records if not r["is_impossible"]]
unanswerable = [r for r in records if r["is_impossible"]]
print(f"{db_id}/{split}: 共 {len(records)} 条,可答 {len(answerable)},不可答 {len(unanswerable)}")

sample = answerable[0]
print("问题:", sample["question"])
print("SQL :", sample["query"])

# (2) 连库并执行(把时间锚点设为数据集的 current_time)
conn = sqlite3.connect(sqlite_path)
conn.execute("PRAGMA query_only = ON")        # 防误写;库为只读评测用途
try:
    rows = conn.execute(sample["query"]).fetchall()
    print("执行成功,返回行数:", len(rows))
except sqlite3.Error as e:
    print("执行失败:", e)
finally:
    conn.close()

时序提示:某些 SQL 使用 strftime/datetime 做相对时间运算,语义上以 2105-12-31 23:59:00 为"当前时间"。SQLite 本身不知道这个锚点,所以这些查询仍然能执行,但结果需要按此锚点解读。做严格的执行准确率评测时,应与官方 evaluate.py 对齐(它按同样方式在 SQLite 上对比生成结果与金标准结果,不做时间重写)。

§6.2 数据获取

资产 获取方式 大小 前置条件
问答对 JSON + 表结构 git clone https://github.com/glee4810/EHRSQL.git 约 13 MB 无
MIMIC-III 预处理 SQLite Google Drive 直链(见仓库 README) 95 MB 无(但仅限 SQL 评测用途)
eICU 预处理 SQLite Google Drive 直链 102 MB 无
从源头重建数据库 PhysioNet 下载 MIMIC-III v1.4 + eICU-CRD v2.0 数 GB CITI 培训 + 凭证化申请 + DUA
EHRSQL-2024(MIMIC-IV demo 版) https://github.com/glee4810/ehrsql-2024 见仓库 无(demo 库公开)
# 推荐路径:克隆仓库 + 手动放置 sqlite
git clone https://github.com/glee4810/EHRSQL.git
cd EHRSQL

# 环境(README 两套口径,此处用正文 Requirements 口径,见坑 1)
conda create -n ehrsql python=3.7 -y
conda activate ehrsql
pip install pandas==1.5.3 dask scikit-learn func-timeout sentencepiece
pip install transformers==4.19.2        # 4.29.2 亦可
pip install torch==1.7.1                # 需匹配 CUDA 版本

# 放置 sqlite(手动从 Google Drive 下载后)
#   dataset/ehrsql/mimic_iii/mimic_iii.sqlite
#   dataset/ehrsql/eicu/eicu.sqlite

# 从源头重建(可选,需 PhysioNet 凭证化数据)
cd preprocess
python3 preprocess_db.py \
    --data_dir <path_to_mimic_iii_csv_files> \
    --db_name mimic_iii \
    --deid --timeshift \
    --current_time "2105-12-31 23:59:00" \
    --start_year 2100 --time_span 5 --cur_patient_ratio 0.1

为什么推荐"克隆 + 手动放置"而不是"从源头重建"? 重建需要先通过 PhysioNet 的凭证化申请拿到数 GB 的原始 CSV,再跑预处理(患者采样、二次去标识、时间平移、新增 cost 表)。预处理脚本的随机性由固定种子控制,但重跑耗时且可能因 PhysioNet 版本更新而漂移。除非你需要自己控制队列构成(如调整 --cur_patient_ratio 以保留更多在院患者),否则直接用官方 sqlite 更省事、更可复现。

§6.3 预处理全流程

EHRSQL 自身的预处理已完成,使用者的"预处理"主要是把 JSON 转成训练张量。完整流程四步:

"""EHRSQL 预处理全流程:字段规范化 → 目标序列构造 → 长度过滤 → 泄漏校验。

输入:dataset/ehrsql/{db_id}/{split}.json
输出:可送入 seq2seq 的 (source_text, target_sql) 列表
"""
import json
import re
from pathlib import Path
from collections import Counter

data_root = Path("/path/to/EHRSQL")


def load_split(db_id: str, split: str):
    p = data_root / "dataset" / "ehrsql" / db_id / f"{split}.json"
    return json.loads(p.read_text(encoding="utf-8"))


# ---- 步骤 1:字段规范化 -------------------------------------------------
def normalize(records):
    """把 t_tag / o_tag 的定长数组展平为可分析字段;空串统一为 None。"""
    out = []
    for r in records:
        item = {
            "id": r["id"],
            "db_id": r["db_id"],
            "question": r["question"].strip(),
            "is_impossible": bool(r.get("is_impossible", False)),
            "department": r.get("department", []),
        }
        if item["is_impossible"]:
            # 不可答条目没有 template/q_tag/query 标签,显式补齐避免 KeyError
            item.update(query=None, template=None,
                        t_tag=[], o_tag=[])
        else:
            item.update(
                query=r["query"],
                template=r.get("template"),
                t_tag=[t or None for t in r.get("t_tag", [])],
                o_tag=[o or None for o in r.get("o_tag", [])],
            )
        out.append(item)
    return out


# ---- 步骤 2:构造 seq2seq 目标 -------------------------------------------
def build_pairs(items, with_schema: bool = False, tables=None):
    """source = question(可选拼 schema 前缀);target = 金标准 SQL。"""
    schema_prefix = ""
    if with_schema and tables is not None:
        cols = [c[1] for c in tables["column_names"][:50]]   # 截断,避免超长
        schema_prefix = " | columns: " + " , ".join(cols) + " "
    pairs = []
    for it in items:
        if it["query"] is None:            # 跳过不可答(无监督目标)
            continue
        pairs.append((schema_prefix + it["question"], it["query"]))
    return pairs


# ---- 步骤 3:长度过滤(T5 输入上限通常 512 子词)-------------------------
def length_filter(pairs, max_tokens=480, tokenizer=None):
    if tokenizer is None:
        return pairs
    kept = []
    for src, tgt in pairs:
        if len(tokenizer(src)["input_ids"]) <= max_tokens \
           and len(tokenizer(tgt)["input_ids"]) <= max_tokens:
            kept.append((src, tgt))
    return kept


# ---- 步骤 4:泄漏校验:模板是否跨划分重叠 --------------------------------
def leakage_audit(train_items, valid_items):
    """官方约束:模板全划分出现,但释义不重叠。此处校验后一半。"""
    tr = {i["question"] for i in train_items}
    va = {i["question"] for i in valid_items}
    overlap = tr & va
    print(f"train∩valid 问题文本重叠: {len(overlap)} 条")
    if overlap:
        print("  示例:", list(overlap)[:3])
    return overlap


if __name__ == "__main__":
    train = normalize(load_split("mimic_iii", "train"))
    valid = normalize(load_split("mimic_iii", "valid"))

    print("train 记录:", len(train), "| valid 记录:", len(valid))
    print("valid 不可答占比:",
          sum(i["is_impossible"] for i in valid) / len(valid))

    pairs = build_pairs(train)
    print("可用于训练的可答对:", len(pairs))
    leakage_audit(train, valid)

    # 时间表达类型分布(剔除空串,避免虚高的"无时间"比例)
    t_counts = Counter(t for i in valid for t in i["t_tag"] if t)
    print("valid 时间模板标签 Top5:", t_counts.most_common(5))

预处理阶段最容易踩的三件事:(1)不可答条目字段更少,用 dict 直接取 template 会抛 KeyError;(2)t_tag / o_tag 里的空串是"未启用"而非缺失,混入统计会污染比例;(3)长度过滤必须在 tokenizer 层面做而不是字符数层面,因为 SQL 中的表名与列名会被切成多个子词。

§6.4 PyTorch DataLoader

"""EHRSQL 的 PyTorch Dataset / DataLoader 完整实现(含 collate 与掩码)。"""
import json
from pathlib import Path
from typing import List, Tuple, Optional

import torch
from torch.utils.data import Dataset, DataLoader
from transformers import T5Tokenizer


class EHRSQLDataset(Dataset):
    """一个样本 = (问题文本, 金标准 SQL)。不可答条目默认跳过。

    参数
    ----
    data_root : 仓库根目录(其下有 dataset/ehrsql/...)
    db_id     : "mimic_iii" 或 "eicu"
    split     : "train" / "valid" / "test"
    tokenizer : 已加载的 T5Tokenizer
    max_input_length / max_target_length : 截断长度(T5 上限 512)
    include_unanswerable : 是否把不可答条目也返回(拒答任务需要)
    """

    def __init__(self, data_root: str, db_id: str, split: str,
                 tokenizer: T5Tokenizer,
                 max_input_length: int = 480,
                 max_target_length: int = 480,
                 include_unanswerable: bool = False):
        path = Path(data_root) / "dataset" / "ehrsql" / db_id / f"{split}.json"
        self.tokenizer = tokenizer
        self.max_input_length = max_input_length
        self.max_target_length = max_target_length

        raw = json.loads(path.read_text(encoding="utf-8"))
        self.items: List[dict] = []
        for r in raw:
            is_imp = bool(r.get("is_impossible", False))
            if is_imp and not include_unanswerable:
                continue
            self.items.append({
                "id": r["id"],
                "question": r["question"].strip(),
                # 不可答条目 query 为字符串 "nan",统一归一为 None
                "query": None if is_imp else r["query"],
                "is_impossible": is_imp,
            })

    def __len__(self) -> int:
        return len(self.items)

    def __getitem__(self, idx: int) -> dict:
        it = self.items[idx]
        enc = self.tokenizer(
            it["question"],
            max_length=self.max_input_length,
            truncation=True,
            padding=False,
            return_tensors=None,
        )
        out = {
            "input_ids": enc["input_ids"],
            "attention_mask": enc["attention_mask"],
            "id": it["id"],
            "is_impossible": it["is_impossible"],
        }
        if it["query"] is not None:
            with self.tokenizer.as_target_tokenizer():
                tgt = self.tokenizer(
                    it["query"],
                    max_length=self.max_target_length,
                    truncation=True,
                    padding=False,
                )
            # seq2seq 标签:pad 位置置 -100,损失计算时自动忽略
            out["labels"] = tgt["input_ids"]
        return out


def collate_fn(batch: List[dict], pad_token_id: int = 0,
               label_pad_token_id: int = -100) -> dict:
    """把变长样本补到本 batch 最长(不用全局 max_length,省显存)。"""
    max_in = max(len(b["input_ids"]) for b in batch)
    input_ids, attention_mask = [], []
    for b in batch:
        pad = max_in - len(b["input_ids"])
        input_ids.append(b["input_ids"] + [pad_token_id] * pad)
        attention_mask.append(b["attention_mask"] + [0] * pad)

    out = {
        "input_ids": torch.tensor(input_ids, dtype=torch.long),
        "attention_mask": torch.tensor(attention_mask, dtype=torch.long),
        "id": [b["id"] for b in batch],
        "is_impossible": torch.tensor([b["is_impossible"] for b in batch]),
    }
    if "labels" in batch[0]:
        max_tgt = max(len(b["labels"]) for b in batch)
        labels = [b["labels"] + [label_pad_token_id] * (max_tgt - len(b["labels"]))
                  for b in batch]
        out["labels"] = torch.tensor(labels, dtype=torch.long)
    return out


# ---------------- 实例化 ----------------
if __name__ == "__main__":
    DATA_ROOT = "/path/to/EHRSQL"
    tok = T5Tokenizer.from_pretrained("t5-base")

    train_ds = EHRSQLDataset(DATA_ROOT, "mimic_iii", "train", tok)
    valid_ds = EHRSQLDataset(DATA_ROOT, "mimic_iii", "valid", tok,
                             include_unanswerable=True)

    train_loader = DataLoader(
        train_ds, batch_size=32, shuffle=True,
        num_workers=4, collate_fn=collate_fn, pin_memory=True,
    )
    valid_loader = DataLoader(
        valid_ds, batch_size=64, shuffle=False,
        num_workers=4, collate_fn=collate_fn, pin_memory=True,
    )

    batch = next(iter(train_loader))
    print({k: (v.shape if torch.is_tensor(v) else type(v))
           for k, v in batch.items()})
    # batch_size=32 与论文 Table 9 的 T5-base 微调配置一致

与论文配置的对齐点:论文 Table 9 给出的 T5-base 微调配置为总训练步数 100,000、batch size 32、在 NVIDIA GeForce RTX 3090 上训练。batch 32 在 480 子词长度下约占 10-12 GB 显存,3090 的 24 GB 有余量;若用 16 GB 卡需降到 batch 8-16 并配合梯度累积。

§6.5 坑点清单

⚠️ 坑 1:官方 README 与正文的 Python 版本要求不一致(分类:工程陷阱)

问题:仓库 README 的 Requirements 段写 “Python version >= 3.7, PyTorch version == 1.7.1”,但同一 README 的 Getting Started 又给出 conda env create -f environment.yml 与 Python >= 3.9 的口径。第三方 fork 转载的版本更混杂。照错版本建环境会导致依赖冲突。
症状:按 Python 39 + transformers 4.19.2 安装时,部分依赖(如 sentencepiece、旧版 dask)解析失败;按 Python 3.7 + 新版 torch 安装时,torch 找不到匹配的 1.7.1 轮子而退回 CPU 版。
解决:

  1. 简单方法:以仓库根目录的 environment.yml 为准(conda env create -f environment.yml),它固化的是官方实际验证过的组合。
  2. 进阶方法:手工建环境时把 Python 固定在 3.9、transformers 固定在 4.19.2(README 明确注明 4.29.2 亦可),并显式安装匹配 CUDA 的 torch:pip install torch==1.7.1+cu110 -f https://download.pytorch.org/whl/torch_stable.html。
  3. SOTA 方法:只把 EHRSQL 当作数据源,用当前主流的 LLM 提示式流程(见 EHRSQL-2024 各队方案)绕开 T5 微调栈,仅保留 evaluate.py 的执行准确率计算逻辑。
    参考:官方 README Requirements 段

⚠️ 坑 2:数据集规模有至少三个公开口径(分类:标签理解)

问题:论文正文写"Among 24,411 question pairs"、数据卡写"There are about 24.4K instances (22.5K answerable; 1.9K unanswerable)“、CHANGELOG 写"All 22,505 SQL queries continue to execute successfully”。三个数字并存,直接引用会自相矛盾。
症状:论文复现时若按数据卡声称的 22.5K 可答样本计算,会发现自己加载到的 JSON 条目数与预期不符;若按 CHANGELOG 的 22,505 反推总样本数,会漏掉约 1.9K 不可答条目。
解决:

  1. 简单方法:以"你实际加载到的 JSON 条目数"为准,并在论文中写明 len(train)+len(valid)+len(test) 的实测值。
  2. 进阶方法:区分三种口径的语义——24,411 与 24.4K 是含不可答的合集口径(论文正文与数据卡的表述差异仅在精度);22,505 是当前发布版中带 SQL 标签(可答)且全部可执行的条数。引用时写明"可答 22,505 / 含不可答约 24.4K"。
  3. SOTA 方法:用脚本统计而非引用:sum(len(json.load(open(f))) for f in glob("dataset/ehrsql/*/*.json")),并把统计脚本与版本号一起归档。
    参考:arXiv:2301.07695v6 §4.1 与 §A.2;dataset/ehrsql/CHANGELOG.md

⚠️ 坑 3:v1.5.0 的 SQL 修复改变了 12.9% 的查询结果(分类:评估误用)

问题:2026-03-09 发布的 v1.5.0 修复了 1,840 条 ORDER BY ... LIMIT 1 的非确定性排序(改为相关子查询)、148 条 NULL 传播守卫、97 条 COUNT(*) → COUNT(DISTINCT)。官方明确标注"12.9% of fixes changed actual query results"。用 v1.5.x 数据评测的分数与 2024 年前论文报告的数字不可直接比较。
症状:当你用 v1.5.1 数据复现某篇 2024 年论文的基线数字时,即使模型与流程完全一致,指标也会系统性偏移;反之,用旧版数据对标最新论文也会偏。
解决:

  1. 简单方法:在论文/报告中明确写出所用数据集版本与 commit hash(git rev-parse HEAD),并声明"与 v1.5.0 之前版本不可直接比较"。
  2. 进阶方法:跨版本对比时同时报告两版结果,或把旧版中被修复的那两类查询(非确定性排序 / COUNT 语义)单独标记为"版本敏感子集",在子集内做同版对比。
  3. SOTA 方法:把"SQL 修复导致的结果变化率"作为数据集版本管理的元信息纳入评测协议——即在上报执行准确率时附带"本次评测所用标注版本的变更摘要",让读者能判断分数漂移是模型进步还是标注修复。
    参考:CHANGELOG v.1.5.0

⚠️ 坑 4:不可答条目字段更少,直接取字段会 KeyError(分类:工程陷阱)

问题:valid.json / test.json 中 is_impossible = true 的条目只有 db_id、question、query(值为字符串 "nan")、department、para_type、is_impossible、split、id 八个字段;而可答条目有全部 15 个字段。写通用解析代码时按可答条目的字段集访问,遇到不可答条目即崩溃。
症状:KeyError: 'template' 或 KeyError: 'q_tag',且只在处理 valid/test 时出现(因为训练集没有不可答条目),容易在验证阶段才暴露。
解决:

  1. 简单方法:先按 is_impossible 分流,对不可答条目构造独立的轻量 schema。
  2. 进阶方法:用 dataclass 定义统一记录结构,把缺失字段显式补为 None(见 §6.3 normalize() 实现),让下游代码无需感知两种形态。
  3. SOTA 方法:把不可答检测建模为独立的二分类头,与 SQL 生成共享编码器但拥有独立的数据管道——这样不可答条目天然不需要 SQL 标签,字段差异成为设计的一部分而非需要修补的缺陷。
    参考:官方 README 中 valid.json 的不可答样例

⚠️ 坑 5:两个 sqlite 不在仓库里,需另从 Google Drive 下载(分类:工程陷阱)

问题:git clone 得到的是 JSON 与代码,mimic_iii.sqlite(95 MB)与 eicu.sqlite(102 MB)需从官方给出的 Google Drive 直链单独下载,并放到 dataset/ehrsql/{db_id}/{db_id}.sqlite 的固定路径。用 CI 或容器自动构建时不做这一步,评测脚本必然失败。
症状:sqlite3.OperationalError: unable to open database file,或 evaluate.py 提示找不到 --db_path 指定的文件。
解决:

  1. 简单方法:手动下载两个 sqlite 并严格按 README 给出的路径(dataset/ehrsql/mimic_iii/mimic_iii.sqlite 与 dataset/ehrsql/eicu/eicu.sqlite)放置,路径大小写与下划线都不能改。
  2. 进阶方法:在容器构建阶段用 gdown 拉取(pip install gdown && gdown <file_id>),并在构建脚本中加入校验:python -c "import sqlite3; sqlite3.connect(p).execute('select 1')",失败即中止构建。
  3. SOTA 方法:改用 PhysioNet 源头重建路径(见 §6.2 的 preprocess_db.py 命令),把随机种子、采样参数与源数据版本一起固化进配置,使数据库成为可完全重建的产物而不再依赖第三方网盘。代价是需完成 CITI 培训与 DUA。
    参考:官方 README 的 Database 章节

⚠️ 坑 6:以"疾病分类数据集"的期待检索会一无所获(分类:标签理解)

问题:EHRSQL 的名字里有"EHR",但它不是一份病历库,而是问答基准——没有 ICD 编码列、没有诊断标签、没有患者级别的临床终点。若按"MIMIC 的疾病标注子集"去理解并检索,会找不到预期字段。
症状:试图在 train.json 中寻找 diagnosis_code、icd9_code 等字段;或期待能直接从 EHRSQL 计算某疾病的患病率。这些字段在 EHRSQL 的 JSON 中都不存在——它们属于其底层数据库(MIMIC-III / eICU),而底层数据库在 EHRSQL 分发版中已被值打乱。
解决:

  1. 简单方法:明确区分三方资产——MIMIC-III/eICU 是数据库本体(§2.4)、EHRSQL 是问答基准(本篇)、MIMIC-IV demo 是 EHRSQL-2024 的载体。要疾病编码就去 PhysioNet 拿原库。
  2. 进阶方法:若研究目标确实需要"疾病 + 提问"的联合标注,可从 query 字段反向解析出涉及的 ICD 码表(如 MIMIC-III 的 d_icd_diagnoses),把 EHRSQL 的提问与底层编码体系关联起来——这是数据集未提供但可推导的扩展。
  3. SOTA 方法:把 EHRSQL 与库内其它 EHR 条目组合使用——用 MIMIC-IV 的临床本体条目理解疾病谱、用 EHRSQL 评测检索能力、用 eICU 条目理解多中心差异,形成"本体 + 问答 + 评测"的三层研究栈(见 §9.1)。
    参考:MIMIC-III PhysioNet 页面;eICU-CRD 页面

⚠️ 坑 7:SQL 标注不是按患者划分的,记忆型模型会虚高(分类:数据泄漏)

问题:论文附录 F 明确说明数据集不按患者划分——同一位患者的多个属性问题分散在训练集与验证集。这是有意设计(按患者划分会让任务过于简单),但会让任何"记住特定患者记录"的模型在验证集上获得虚高分数。
症状:模型在验证集上的执行准确率显著高于测试集,或在换一批患者 ID 后性能骤降;错误分析显示模型生成的 SQL 中患者 ID 与问题不匹配(如用某患者的值去比另一个患者的记录)——论文 Table 13 恰好收录了一个这样的错例:模型把 naproxen(药名)当作 subject_id 去查 subject_id = naproxen。
解决:

  1. 简单方法:报告结果时同时给出"按 subject_id 分组重划分"的交叉验证分数,让读者看到患者记忆带来的虚高幅度。
  2. 进阶方法:从 SQL 文本中用正则提取 subject_id = <n> / patient_id = <n>,按患者 ID 集合做 GroupKFold,并校验两个子集的患者 ID 交集为空。
  3. SOTA 方法:在评测协议中引入"留出患者"设定——把验证集里的患者 ID 全部替换为训练集中未出现的值,观察模型是否仍能生成语法正确、语义合理的 SQL。这能把"schema linking"与"值记忆"两种能力解耦,比单纯报告执行准确率更有诊断价值。
    参考:arXiv:2301.07695v6 附录 F;附录 H.3 Table 13

⚠️ 坑 8:不可答问题的多样性不足,简单过滤即可通过(分类:偏倚陷阱)

问题:EHRSQL-2024 的概览论文直接指出,一项研究发现 EHRSQL 的不可答问题"大多可以用 n-gram 与 beam search 分数过滤的组合方法筛出",原因是原始不可答问题在问卷阶段因人类操作失误被"错误收集",多样性有限。这正是 2024 版要补充 TrustSQL 对抗式不可答问题的动机。
症状:在原始 EHRSQL 的验证集上,用极简单的启发式(如检测问题中是否出现 schema 中不存在的名词、或用 n-gram 覆盖率打分)就能获得很高的不可答检测 F1——模型看似"学会了拒答",实际上只学会了识别几种固定的措辞模式。
解决:

  1. 简单方法:在报告拒答性能时,同时报告"用随机基线 / n-gram 基线在同一测试集上的表现",如果基线已很高,说明该测试集的拒答难度不足,结论需谨慎。
  2. 进阶方法:改用 EHRSQL-2024 的评测集,它把原始不可答问题与 TrustSQL 的对抗式不可答问题(引用不存在的列、要求超出 SQL 功能的绘图等)混合,并对不可答占比做了重新设计(各划分 20%)。
  3. SOTA 方法:把拒答能力拆成两类分别评测——“语义上不可答”(需要外部知识,如副作用)与"结构上不可答"(列不存在、功能不支持)。前者考领域推理,后者考 schema 感知,两者的最优策略不同(前者靠知识边界判断,后者靠 schema 比对),合并报告会掩盖能力差异。
    参考:Overview of the EHRSQL 2024 Shared Task §3.4

§6.6 数据增强

增强操作 安全性 说明
问题文本的同义改写 ✅ 安全 用通用释义模型改写 question,但须人工抽检,避免改变时间方向(v1.5.0 就修出过 19 处时间方向错误)
时间表达替换 ⚠️ 谨慎 把"上个月"换成"30 天内"通常安全,但涉及 since/until 的方向不能反转
schema 序列化前缀 ✅ 安全 在问题前拼接表名列名作为提示(官方 WithSchema 变体就是这么做)
患者 ID 替换 ✅ 安全 只要同步修改 SQL 中的 ID 值
SQL 等价改写(JOIN ↔ 嵌套) ❌ 危险 会破坏与金标准文本的匹配;且论文刻意选择嵌套风格,JOIN 在亿级表上不可行
条件值随机替换 ❌ 危险 会破坏"SQL 至少有一个有效答案"这一构造约束,导致执行结果为空
时间戳平移 ❌ 危险 相对时间表达依赖 2105-12-31 23:59:00 这一固定锚点,改动后语义全部失效
反向翻译扩增 ⚠️ 谨慎 多语言回译正是数据集自身的释义来源之一,与数据同源,扩增收益有限且可能加重分布贴合

§6.7 模型推荐

场景 推荐模型 理由
基线复现 T5-base(官方脚本) 论文 Table 5 的唯一基线,可直接对标 77.8 / 76.5 的 F1_exe
拒答研究 T5-base + 最大熵阈值 官方提供 abstain_with_entropy.py,默认阈值 0.14923561
提示式零样本 GPT-4 级通用 LLM + schema 序列化 EHRSQL-2024 排行榜前列队伍多以 ChatGPT/GPT-4 为主力
大模型微调 7B-13B 开源代码模型 + 微调 2024 排行榜中 LTRC-IIITH 用 SQLCoder-7b-2、AIRI NLP 用 T5-3B
严格可靠性场景 任意模型 + RS(10) 评测协议 一次错误等价于十次正确的评分迫使模型优先拒答
通用域模型直接迁移 ❌ 不推荐 GAP 在 EHRSQL 可解析子集上仅 4.7%,见坑 8 与 §8.1

§6.8 硬件需求

配置 显存 可行性
T5-base,batch 32,seq 480 约 10-12 GB 单卡 RTX 3090(论文配置)充裕
T5-base,batch 32,seq 480 约 10-12 GB 16 GB 卡(如 V100 16G)需降到 batch 8-16 + 梯度累积
T5-3B 微调(AIRI NLP 方案) 60 GB+ 需 A100 或分片训练
7B 代码模型推理(SQLCoder-7b-2) 16 GB+(bf16) 单卡 4090/A5000 可行,推理用 4-bit 可降至 8 GB
纯评测(evaluate.py) 无 GPU 需求 CPU 即可,瓶颈在 SQLite 查询

§6.9 评估指标

EHRSQL 的评测围绕两个层次展开:可答性判别与SQL 执行正确性。

"""EHRSQL 核心指标实现:F1_ans 与 F1_exe。

符号:
  ans_pred  : 模型判定的"可答"集合
  ans_true  : 真实"可答"集合
  exe_ok    : 模型预测为可答 且 执行结果与金标准一致的样本集合
"""
from typing import Set


def f1_ans(ans_pred: Set[str], ans_true: Set[str]) -> float:
    """可答性判别的 F1(P_ans 与 R_ans 的调和平均)。"""
    tp = len(ans_pred & ans_true)
    p = tp / len(ans_pred) if ans_pred else 0.0
    r = tp / len(ans_true) if ans_true else 0.0
    return 2 * p * r / (p + r) if (p + r) else 0.0


def f1_exe(ans_pred: Set[str], ans_true: Set[str], exe_ok: Set[str]) -> float:
    """执行层面的 F1:分子只在'答案真的查对'时计分。

    P_exe = |exe_ok| / |ans_pred|   (预测为可答中,真正答对的比例)
    R_exe = |exe_ok| / |ans_true|   (所有可答中,真正答对的比例)
    注意:分母与 f1_ans 相同,只有分子更严格 —— 两者之差即"识别可答"
    与"真正查对"之间的能力鸿沟。
    """
    p = len(exe_ok) / len(ans_pred) if ans_pred else 0.0
    r = len(exe_ok) / len(ans_true) if ans_true else 0.0
    return 2 * p * r / (p + r) if (p + r) else 0.0


def execution_match(pred_rows, gold_rows, ordered: bool = False) -> bool:
    """执行结果比对:默认按集合比较(忽略行序与括号元组形式差异)。

    实现要点:
    - sqlite3 返回 tuple 列表,比较前统一为 frozenset 或排序列表
    - 浮点数比较需容差(某些聚合结果末位有差异),建议 round(x, 6)
    - ordered=True 时用于含 ORDER BY 的查询,此时必须保留行序
    """
    def norm(rows):
        if rows is None:
            return None
        cleaned = [tuple(round(v, 6) if isinstance(v, float) else v for v in r)
                   for r in rows]
        return cleaned if ordered else frozenset(cleaned)
    return norm(pred_rows) == norm(gold_rows)

官方实现对齐:仓库根目录的 evaluate.py 接受 --db_path、--data_file、--pred_file 三个参数,在 SQLite 上分别执行预测 SQL 与金标准 SQL 并比较结果。使用自定义指标实现时,建议先用官方脚本跑一遍小样本,确认自己的一致性判定逻辑与之等价。

§6.10 MLOps 笔记

环节 要点
版本锁定 同时锁定三样:数据集版本(v1.5.1)、commit hash、sqlite 文件的 MD5。三者任一变更都需重新评测
时间锚点 把 2105-12-31 23:59:00 作为常量固化进代码,任何相对时间查询的解读都依赖它
拒答阈值 阈值与"验证集不可答比例"强相关(33% → 67 分位);若改变验证集构成必须重新标定
评测缓存 SQL 执行是主要耗时项,按 (query 文本 hash, db_id) 缓存执行结果可大幅加速重复评测
只读保护 连接 sqlite 后立即 PRAGMA query_only = ON,防止生成的 SQL 意外写入或加锁
失败归因 把失败分为"schema linking 错"(表列指代错)、“语法错”(无法执行)、“语义错”(能执行但结果错)三类分别统计——论文指出主要错误来自第一类

§7 质量评估与局限性

§7.1 已知偏倚

类型 描述 严重程度 缓解建议
单中心采样偏倚 问卷全部来自韩国大田一所大学医院(222 人),提问习惯可能不代表全球医院 高 论文明确标注为首要局限;跨机构使用时须做提问风格差异评估
语言风格偏倚 释义由通用域改写器生成,医疗术语密度偏低,与真实临床口语有差距 中 论文列为第二项局限;可自行用临床语料做领域适应改写
库数不足 仅标注 MIMIC-III 与 eICU 两个 schema,不足以训练适配未见 EHR 库的模型 中 论文列为第三项局限;2024 共享任务的 MIMIC-IV demo 部分缓解
ICU 队列偏倚 两个底层数据库都是重症监护队列,缺少门诊、慢病随访等场景 中 检索时区分"ICU 提问"与"全院提问";不要假设结果可外推到门诊场景
不可答多样性偏倚 原始不可答问题因问卷阶段人为失误而多样性有限,简单过滤即可高分 中高 改用 EHRSQL-2024(补充 TrustSQL 对抗式不可答);或按坑 8 的分类协议分开评测
值打乱导致的分布失真 为二次脱敏,全库条件值被随机打乱,样本值之间失去真实相关性 中 仅用于 SQL 能力评测;不可用于任何分布或相关性分析(官方明示)
释义生成器贴合 释义由 T5 系改写器与 GPT-4o-mini 生成,模型预训练数据可能包含同源分布 低中 做 SOTA 对比时披露被测模型是否可能见过 EHRSQL

§7.2 标注质量

EHRSQL 的标注质量在两处做得比同类数据集更严:一是 SQL 标注不做众包,因为涉及患者信息与大量隐性假设,必须由受过培训的研究者完成;二是释义质控采用三组全票通过制,任一组判 fail 即淘汰,因此保留下来的机器释义质量基线较高。

但有三处已知的标注瑕疵必须留意:

  1. 槽位填充可能导致语法不自然。论文数据卡原文承认:“final questions can sound unnatural or be grammatically incorrect depending on the sampled values(如动词时态、冠词)”。
  2. 不可答问题是"补集"而非穷举。论文明确说明不提供不可答问题的完整清单,因为"它们不受训练约束,凡与可答问题互补的都可以"。这意味着不可答类别在理论上无界,实测覆盖率无法保证。
  3. v1.5.0 暴露的历史标注缺陷。1,840 条查询存在非确定性排序问题、148 条缺 NULL 守卫、97 条 COUNT 语义错误——这些缺陷在发布后近三年才被系统性修复,说明早期版本的 SQL 标注存在可测量的系统性偏差。

§7.3 泛化性风险

场景 失效风险 证据
从通用域模型直接迁移 高 GAP 在 EHRSQL 可解析子集仅 4.7%(5/107),在 MIMICSQL 全集有 16.4%(论文 Table 6)
跨 EHR schema 迁移(MIMIC-III → 未标注库) 高 论文自陈"两个库可能不足以训练适配未见库的模型"
跨机构提问风格迁移 中高 问题来源单一韩国大学医院
现实临床口语(含大量缩写与行话) 中 释义使用通用域改写器,医学术语密度不足
门诊 / 慢病场景 高 底层两库均为 ICU 队列
患者级泛化(新患者) 未知偏高 划分未按患者切分,缺少直接证据(见坑 7)
时间表达泛化 中 论文 Table 11 显示模型对未见过的 Q_tag × T_tag 组合仍能正确生成 SQL,说明时间泛化并非主要瓶颈
拒答能力泛化 高 不可答多样性不足,简单 n-gram 过滤即可高分(见坑 8)

§7.4 伦理与合规

EHRSQL 的伦理设计有两点值得肯定:一是在 PhysioNet 已脱敏的基础上追加二次去标识(先随机打乱全库值,再采样条件值),使问题中出现的具体值无法回溯到任何患者;二是明确声明数据卡中"不分发给第三方"的约束(§A.6),并让使用者自行完成 PhysioNet 的凭证化流程才能重建底层库。

需要使用者自行承担的合规责任有三条:其一,数据集本身是 CC BY 4.0,但其 SQL 标注的语义依赖 MIMIC-III 与 eICU 的 schema 与数据——重建底层库并分发需遵守 PhysioNet 的 DUA,不是 CC BY 4.0 能覆盖的。其二,若研究者自行搭建基于 EHRSQL 的临床问答系统,即使模型指标优异,也须经过独立的临床验证与监管审批才能进入临床流程。其三,问句由真人撰写、可能隐含真实临床关切,尽管值已被打乱,发布衍生数据时仍应评估"新增的问句集合本身"是否构成信息泄露(如把某医院的特定提问习惯暴露为竞争力信息)。

§7.5 公平性

维度 分析
提问者构成 222 名受访者覆盖医师、护士、医保审核与病案团队;论文 Figure 1 给出科室与从业年限分布,但未提供性别、职称层级的完整细分,无法评估提问习惯是否系统性偏向某类从业者
患者群体 MIMIC-III 为单中心(波士顿)、eICU 为美国多中心——地理与人种覆盖偏美国
语言 全部为英文,非英语医院的提问模式(如中文、韩文)完全缺席——尽管问卷本身发生在韩国医院,说明提问的语用被"翻译/英文化"了
疾病公平性 数据集按"查询对象"而非"疾病"组织,不存在某疾病样本过少的直接问题;但 ICU 队列天然偏向危重症,慢性病与初级保健相关问题稀少

§7.6 数据漂移

漂移源 影响 应对
标注版本迭代(v1.0 → v1.5.1) 12.9% 的 SQL 修复改变了查询结果 锁定版本与 commit hash;跨版本对比需注明
底层数据库换代(MIMIC-III → MIMIC-IV) schema 与时间覆盖变化;EHRSQL-2024 已做迁移 更新计划时评估是否需要重标;MIMIC-IV demo schema 与全库一致,可用同一 SQL
临床提问习惯变化(LLM 辅助问答兴起) 真实用户提问方式正在被 AI 产品重塑,2021 年采集的提问分布可能不再代表当前习惯 关注 2024 年后的新版 paraphrase(已由 ChatGPT 重新生成,更口语化)
依赖工具链漂移 transformers/torch 版本演进导致官方脚本在新环境下报错 用 environment.yml 锁定;或只复用数据与评测逻辑

§7.7 DAIMS 24 项评估

# 检查项 状态 说明
1 宽格式 ✅ 问答对为每条记录一行,字段展开,无需透视
2 唯一标识 ✅ 每条记录有 24 位十六进制 id
3 特殊字符 ⚠️ value 中出现药名带百分号与空格(如 "clobetasol propionate 0.05% ointment"),写进 SQL 字符串时需转义
4 重复行 ✅ 官方释义阶段做了 RoBERTa 重复检测 + Levenshtein 过滤,并在划分间校验释义不重叠
5 缺失编码 ⚠️ 存在三种"缺失"语义混用:空串(未启用)、"nan"(不可答)、字段缺失(不可答条目),需分别处理
6 标签标识 ✅ 可答性由 is_impossible 显式标注,SQL 为金标准标签
7 罕见类分组 ⚠️ 不可答问题仅两类(超 schema / 需外部知识),多样性不足且不提供完整清单
8 偏倚评估 ✅ 论文明确列出三项局限(单中心、通用域释义、库数不足),2024 版进一步披露不可答问题的人为收集缺陷
9 数据字典 ✅ README 逐字段说明;tables.json 给出完整 schema(列名、类型、外键、主键)
10 信息性缺失解释 ⚠️ t_tag/o_tag 的空串语义需读者自行推断(论文以模板表格形式隐含说明)
11 设备记录 ✅ 不涉及采集设备;训练硬件(RTX 3090)在附录 G 记录
12 共线性 ⚠️ 条件值被打乱,样本值之间失去真实相关性——这是设计选择,但对任何相关性分析构成障碍
13 编码映射 ✅ tables.json 同时提供原始名与规范化名两套列名,映射关系显式
14 时间戳处理 ✅ 时间平移(2100-2105)、当前时间锚点(2105-12-31 23:59:00)、三类时间过滤均有文档
15 划分建议 ✅ 官方给出 train/valid/test 与采样规则;EHRSQL-2024 另引入 seen/unseen 模板设计
16 泄漏讨论 ✅ 附录 F 明确讨论"不按患者划分"的设计理由;划分间释义不重叠有官方约束
17 标签分布 ✅ 可答/不可答比例、划分规模、重要性分档、释义来源均在论文与数据卡中给出
18 测量偏倚 ✅ 单中心、通用域释义、ICU 队列三类偏倚均有明确陈述与定量背景
19 外部验证建议 ⚠️ 论文给出跨域实验(GAP 零样本)与跨库标注,但未提供标准的外部验证协议
20 版本记录 ✅ CHANGELOG 逐版本记录;v1.5.0/v1.5.1 的变更量与验证结果均可查
21 预处理脚本 ✅ preprocess/preprocess_db.py 与 T5/*、evaluate.py 全部开源
22 合规要求 ✅ 数据集 CC BY 4.0;底层库需 PhysioNet 凭证化与 DUA,数据卡 §A.6 明示分发限制
23 多模态对齐 ✅ 单模态数据集,不适用;论文展望中提出向多模态 EHR QA 扩展的方向
24 去标识化 ✅ 在 PhysioNet 脱敏之上追加全库值打乱;数据卡 §A.2 逐条说明可识别性防护

DAIMS 评分:21.5 / 24

评分解读:EHRSQL 在"文档完整性"与"去标识严谨性"两类指标上表现突出——数据字典、时间戳处理、版本记录、预处理脚本、合规要求、去标识化六项全部为满分状态,这在数据集条目中属于上游水平。失分集中在三处:其一,"缺失编码"与"信息性缺失解释"两项因空串、"nan"、字段缺省三种语义混用而扣分,这是真实存在的工程摩擦点(坑 4);其二,"罕见类分组"因不可答问题的类别不完备与多样性不足而扣分,且该问题已由官方在 2024 版部分修正,属于已知并正在处理中的缺陷;其三,"外部验证建议"未提供标准协议,使用者需自建跨库或跨版本的验证设计。0.5 分的部分扣减来自"特殊字符"与"共线性"两项——前者是 SQL 转义的实际麻烦,后者是值打乱带来的设计性限制。

对你意味着什么:如果你的工作是训练模型,直接开箱即用——划分、脚本、基线齐备,只需处理坑 4 的字段差异;如果你要做严格的可复现研究,必须做三件事:锁定版本与 commit、在论文中报告你所用的样本数口径(坑 2)、并对被测模型披露是否可能见过数据集。如果你要用它论证拒答能力,请优先使用 EHRSQL-2024 的评测集,并同时报告简单基线(坑 8)——否则你的"拒答能力"结论很可能只是在描述一个 n-gram 分类器的表现。如果你的目标是临床落地,请注意:即使执行准确率接近论文的 93.8%,也仍需独立的临床验证与监管审批,数据集本身的用途声明是"SQL 查询评测",不是临床决策支持。

§7.8 外部验证矩阵

外部场景 来源机构 评估任务 性能指标 相对内部变化 关键发现
Spider / MIMICSQL → EHRSQL(GAP 零样本) Google Research(GAP 模型) 跨域语义解析 执行准确率 4.7%(5/107,EHRSQL 可解析子集);MIMICSQL 全集 16.4%(164/1000) 绝对下降约 11.7 个百分点 通用域能力无法迁移到医疗场景;EHRSQL 仅约 7% 的查询可被 Spider 语法解析(论文 Table 6,v6 口径 107/1,515,见坑 2 与 FACTS §9 冲突存照)
EHRSQL → MIMIC-III 单库子集 同一研究(论文 Table 6) 分库迁移 MIMIC-III only 3.5%(2/57);eICU only 6.0%(3/50) 与合并口径 4.7% 相当 分库后并无显著差异,说明失败源于任务本身复杂度而非库间混淆
EHRSQL-2024 → 各参赛系统(官方评测) KAIST EdLab(组织方) 可靠 Text-to-SQL(RS(10)) 冠军 81.32;ABSTAIN-ALL 基线 20.0;末位 -713.37 有正有负 惩罚越严(RS(10) → RS(N))排名越不稳定,说明多数系统的可靠性来自"少犯错"而非"答对多"
EHRSQL-2024 测试集 → CELEC(训练-free) 研究者独立评测(arXiv:2511.00772) 可靠 Text-to-SQL(RS(0)) 81.05%(785 题改装测试集) 与官方第三名 ProbGate 81.92 相当 仅用 few-shot 提示与两次 LLM 调用即可达到接近冠军档的水平,说明全监督微调的边际收益在收缩

§8 基准性能与生态

§8.1 排行榜

EHRSQL 有两条独立的排行榜:原始基准(论文 Table 5 的 T5-base 基线)与 EHRSQL-2024 共享任务(Codabench 平台上的公开竞赛)。两者评测目标与数据版本不同,数值不可直接比较。

原始基准(论文 Table 5,MIMIC-III,主要指标 F1_exe):

配置 阈值策略 Valid F1_exe Test F1_exe 关键技术 完整引用 代码
T5-base 无(全部回答) 77.8 76.5 纯 seq2seq,不含拒答 Lee et al., 2022, NeurIPS 35:15589-15589. DOI: 10.48550/arXiv.2301.07695 glee4810/EHRSQL
T5-base Clustering(K-means k=2) 87.2 83.8 对最大熵做二聚类定阈 同上 同上
T5-base Percentile(67 分位) 93.8 89.9 依验证集不可答比例定阈 同上 同上
T5-base + Schema 无 77.9 76.6 问题后附加 schema 序列化 同上 同上
T5-base + Schema Percentile(67 分位) 92.5 89.1 同上 + schema 同上 同上

eICU 侧对应数字(论文 Table 5 右半):T5 无阈值 F1_exe 77.8(valid)/ 76.5(test);clustering 86.1 / 82.5;percentile 92.1 / 89.5。与 MIMIC-III 侧高度一致,说明两个 schema 上的任务难度相当。

EHRSQL-2024 共享任务官方排行榜(论文 Table 3,MIMIC-IV demo,主指标 RS(10)):

排名 团队 所属 RS(0) RS(10) RS(N) 建模类型 微调 所用模型 论文/代码
1 LG AI Research & KAIST 韩国 88.17 81.32 -711.83 Unified 是 ChatGPT Jo et al., 2024
2 PromptMind — 82.60 74.89 -817.4 Unified 是 GPT-4, ChatGPT, Claude Opus Gundabathula & Kolar, 2024
3 ProbGate KAIST,韩国 81.92 74.21 -818.08 Unified 是 ChatGPT Kim et al., 2024b
4 KU-DMIS Korea University,韩国 72.07 59.21 -1427.93 Unified 是 ChatGPT Kim et al., 2024a
5 AIRI NLP AIRI,俄罗斯 68.89 44.04 -2831.11 Pipeline 是 T5-3B, Logistic Regression Somov et al., 2024
6 LTRC-IIITH IIIT Hyderabad,印度 66.84 43.70 -2633.16 Pipeline 是 SQLCoder-7b-2 Thomas et al., 2024
7 Saama Technologies 美国 53.21 36.08 -1946.79 Pipeline 是 Decision Trees, CodeLlama-7b, ChatGPT Jabir et al., 2024
8 Project PRIMUS SUST,孟加拉国 14.14 -713.37 约 -84.9K Unified 否 SQLCoder-7b-2 Joy et al., 2024
— ABSTAIN-ALL(基线) 组织方 20.0 20.0 20.0 — — 全部弃权 同上

为什么这些数字不能直接横向比较? 四个原因:

  1. 数据版本不同。原始基准用 MIMIC-III + eICU(值已打乱);2024 共享任务用 MIMIC-IV demo(100 患者,schema 与全库一致)。
  2. 指标定义不同。原始基准的主指标是 F1_exe(执行 F1);2024 共享任务的主指标是 RS(10)(带惩罚的可靠性评分,一次错误等价于十次正确)。
  3. 不可答比例不同。原始为 33%(valid/test);2024 为 20%,但补充了对抗式不可答问题。
  4. 划分策略不同。原始为 IID 式(模板全划分出现);2024 引入 unseen 模板(34 条测试专属)。

一个必须注意的反直觉现象:RS(N) 一栏中,除基线外的所有队伍都是大幅负分(最好的 -711.83,最差的约 -84.9K)。这不是模型能力差,而是度量的数学性质——RS(N) 把惩罚参数设为评测集大小,使得"哪怕只答错一题,其惩罚就超过全部正确预测与正确弃权之和"。它衡量的是"是否存在任何一次致命错误",而非平均表现。任何引用 RS(N) 数字的场合都必须同时说明这一点,否则会严重误读这些系统的实际水平。

§8.2 SOTA 总结与选型建议

从两条排行榜可以提炼出四个趋势:

趋势一:拒答阈值是原始基准上最大的单点增益。 同样是 T5-base,不加阈值 F1_exe 为 77.8,加上 67 分位阈值后跳到 93.8——16 个百分点的提升完全来自"该拒则拒",而非 SQL 生成能力的改善。这说明在这个数据集上,识别"可答性"比"生成更复杂的 SQL"收益更大。

趋势二:schema 序列化的边际收益接近于零。 T5 与 T5+Schema 在 MIMIC-III 上的 F1_exe 分别为 77.8 与 77.9,eICU 上为 77.8 与 76.8。论文指出这与既有发现一致:单库设定下模型不会有效利用 schema 信息——因为训练时已见过全部表列,schema 提示成了冗余。只有当任务涉及未见 schema 时,schema 序列化才可能显现价值。

趋势三:2024 版上的领先方案全部是"微调过的 LLM",但优势在收窄。 2024 排行榜前四名均属"Unified"(统一模型处理生成与拒答)且都微调过 LLM;而 2025-2026 年出现的外部工作(CELEC)仅用 few-shot 提示即达到 81.05% 的 RS(0),接近冠军档。这说明提示工程与推理能力进步正在压缩全监督微调的优势空间。

趋势四:Pipeline 架构在严格惩罚下明显吃亏。 排名 5-8 名均为 Pipeline(两阶段:先判可答再生成),RS(10) 均低于 45;而 Unified 架构的前四名均在 59 以上。可能的解释是:两阶段的误差会累积——第一阶段的误判直接剥夺第二阶段的修正机会,而统一模型能在生成过程中隐式调整置信度。

选型建议:若研究目标是推动 SQL 生成能力上限,用原始基准的 F1_exe(无阈值口径)以避免拒答分数掩盖生成能力差异。若目标是评估系统可靠性,用 2024 版与 RS(10)。若目标是与最新 SOTA 对标,优先用 2024 版的 RS(0) 或 RS(10),因为该线仍在活跃更新。

§8.3 评测协议

协议要素 原始基准 EHRSQL-2024
主指标 F1_exe(执行 F1) RS(10)(默认);另有 RS(0)、RS(N)
辅助指标 F1_ans、P_exe、R_exe 各团队的 RS 多维报告
阈值策略 无阈值 / K-means 聚类 / 67 分位 团队自行设计
提交形式 预测 JSON 文件 Codabench 平台提交,自动算分
时间锚点 2105-12-31 23:59:00 同族设定(MIMIC-IV demo 时间平移)
弃权判定 阈值比较 任意不确定性估计
基线 无弃权 / ABSTAIN-ALL 可达 20%(2024) ABSTAIN-ALL = 20.0
结果比较 同版本内可比较 需说明是否改装测试集(如 CELEC 剔除了不可执行的不可答条目)

协议设计的关键启示:ABSTAIN-ALL 基线恒定拿 20 分(2024 版,不可答占 20%)——这意味**"全程拒答"就能击败排行榜末位队伍**。任何可靠性评测都必须报告这一基线,否则无法判断参赛系统是否真的比"什么都不做"更好(见坑 8 的同类问题)。

数据集 关系 规模 差异点
MIMIC-III 底层数据库之一 40,000+ 患者 EHRSQL 在其上标注 SQL;MIMIC-III 本体无问答标注
eICU-CRD 底层数据库之二 200,000+ ICU 入住 同一批问题在此库上被标注 SQL;这是 eICU 上的首个 SQL 标注
MIMIC-IV demo EHRSQL-2024 的载体 100 患者 schema 与完整 MIMIC-IV 一致,公开可下,可用商用 API
MIMICSQL 直接前作 10,000 问 预定义模板自动生成、仅 5 张表、无语义歧义、无不可答问题
emrKBQA 同期工作 940K 问 由 emrQA 改编到 MIMIC-III 结构化记录;主要问检验结果
TrustSQL 互补 — 提供对抗式不可答问题,被 EHRSQL-2024 合并使用
Spider / WikiSQL 通用域基准 8K / 80K 通用域 schema,无时间敏感性,无不可答问题
KaggleDBQA / SEDE 真实场景基准 0.3K / 12K 同样强调真实提问,但非医疗域、无不可答问题
EHRXQA 生态衍生 — 多模态 EHR QA,由 MIMIC-CXR-VQA + EHRSQL 派生
EHR-SeqSQL 生态衍生 — 把 EHRSQL 分解为顺序化子任务

§8.5 关键论文

# 论文 一句话贡献
1 Lee G., Hwang H., Bae S., Kwon Y., Shin W., Yang S., Seo M., Kim J.-Y., Choi E. “EHRSQL: A Practical Text-to-SQL Benchmark for Electronic Health Records.” NeurIPS 2022, 35:15589-15601. arXiv:2301.07695. DOI: 10.48550/arXiv.2301.07695 本数据集原始论文:222 人问卷 → 230 模板 → 24,411 问答对,首创含不可答问题的可信语义解析任务
2 Lee G., Kweon S., Bae S., Choi E. “Overview of the EHRSQL 2024 Shared Task on Reliable Text-to-SQL Modeling on Electronic Health Records.” arXiv:2405.06673 共享任务概览:改用 MIMIC-IV demo,引入 unseen 模板与 TrustSQL 对抗不可答问题,定义 RS 指标
3 Lee G. et al. “TrustSQL: Benchmarking Text-to-SQL Reliability with Penalty-Based Scoring.” 2024(TrustSQL) 提出 RS 可靠性评分与对抗式不可答问题构造,被 EHRSQL-2024 采纳为主指标与数据补充
4 Wang P., Shi T., Reddy C. K. “Text-to-SQL Generation for Question Answering on Electronic Medical Records.” WWW 2020, pp. 350-361 MIMICSQL:EHRSQL 的直接前作与对照基线(自动模板生成、5 张表)
5 Bae S., Kim D., Kim J., Choi E. “Question Answering for Complex Electronic Health Records Database using Unified Encoder-Decoder Architecture.” ML4H 2021, PMLR 158:13-25 论文引用的医疗 Text-to-SQL 早期统一架构工作,支撑"预训练语言模型优于医疗专用模型"的选型判断
6 Bae S. et al. “EHRXQA: A Multi-Modal Question Answering Dataset for Electronic Health Records with Chest X-ray Images.” NeurIPS 2023 生态衍生:把 EHRSQL 的文本问答扩展到影像+文本多模态
7 Yu T. et al. “Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task.” EMNLP 2018, pp. 3911-3921 通用域标杆:EHRSQL 的所有对比基线(表数、嵌套层、时间占比)以此为参照
8 Kim H. et al. “ProbGate at EHRSQL 2024: Enhancing SQL Query Generation Accuracy through Probabilistic Threshold Filtering and Error Handling.” arXiv:2404.16659 2024 共享任务季军方案:概率阈值过滤 + 错误处理
9 Koretsky M. J. et al. “BiomedSQL: Text-to-SQL for Scientific Reasoning on Biomedical Knowledge Bases.” COLM 2026. arXiv:2505.20321 后续基准:把 EHRSQL 作为对照,指出其平均 SQL 长度(109.9 tokens)在生物医学 Text-to-SQL 基准中最长
10 Yang J. et al. “Reliable Curation of EHR Dataset via Large Language Models under Environmental Constraints.” arXiv:2511.00772 第三方评测:在改装后的 EHRSQL-2024 测试集上以训练-free 方式达到 RS(0) 81.05%

§8.6 社区活跃度

指标 数值 时点
GitHub stars 116 2026-09-28
GitHub forks 18 2026-09-28
Open issues 1 2026-09-28
最近提交 2026-04-28(v.1.5.1) 2026-09-28
仓库创建 2022-06-08 —
Google Scholar 引用 约 110(分地区镜像口径 109/110/112) 2026-09
Scopus 引用 51 2026-09
许可 CC-BY-4.0 2026-09-28
社区实现 CatalyzeX 收录 2 个 2026-09

活跃度解读:116 stars / 18 forks 在医疗 NLP 数据集中属于中等偏上,但真正体现活跃度的是2026 年仍在提交——v.1.5.0 与 v.1.5.1 分别在 2026-03 与 2026-04 发布,距首次发表已逾三年。这种"发表后持续修标注"的维护模式在学术数据集中并不常见,对本条目的 AI 就绪度评级有正面贡献(但也带来跨版本不可比的摩擦,见坑 3)。

§8.7 生态快照

资源 类型 链接 规模/状态(截至 2026-09) 推荐理由
glee4810/EHRSQL 官方仓库 https://github.com/glee4810/EHRSQL 116 stars / 18 forks 数据、代码、评测脚本的唯一权威来源
ehrsql-2024 官方衍生仓库 https://github.com/glee4810/ehrsql-2024 — MIMIC-IV demo 版数据;免 PhysioNet 申请
EHRSQL-2024 任务站 共享任务主页 https://sites.google.com/view/ehrsql-2024 已结束(2024) 任务定义、时间线、数据许可说明
Codabench 竞赛页 评测平台 https://www.codabench.org/competitions/1889 注册已关闭 官方自动算分环境与结果榜
排行榜网站 任务站点 trustworthy semantic parsing 任务页(2023-02 上线) 持续 原始基准的提交与排名
NeurIPS 2022 论文集页 论文 https://proceedings.neurips.cc/paper_files/paper/2022/hash/643e347250cf9289e5a2a6c1ed5ee42e-Abstract-Datasets_and_Benchmarks.html — 正式发表版本引用来源
OpenReview 页面 评审记录 https://openreview.net/forum?id=B2W8Vy0rarw 2022-09-17 发布 社区评审意见与数据集许可声明
arXiv 页面 预印本 https://arxiv.org/abs/2301.07695 v6(2026-03-04) 最新修订版全文与 Supplementary

§9 相关资源与引用

§9.1 官方资源

资源 地址 用途
官方 GitHub 仓库 https://github.com/glee4810/EHRSQL 数据、代码、README、CHANGELOG
数据集目录 https://github.com/glee4810/EHRSQL/tree/main/dataset/ehrsql JSON 问答对与表结构
变更日志 https://github.com/glee4810/EHRSQL/blob/main/dataset/ehrsql/CHANGELOG.md v1.5.0 / v1.5.1 明细
论文 arXiv https://arxiv.org/abs/2301.07695 原始论文(v6)
共享任务概览论文 https://arxiv.org/abs/2405.06673 EHRSQL-2024 完整概览
NeurIPS 论文集页 https://proceedings.neurips.cc/paper_files/paper/2022/hash/643e347250cf9289e5a2a6c1ed5ee42e-Abstract-Datasets_and_Benchmarks.html 正式发表版
MIMIC-III 源库 https://physionet.org/content/[mimiciii](https://www.qianfanghub.com/ai-ready-dataset/mimiciii/590)/1.4/ 重建数据库所需
eICU-CRD 源库 https://physionet.org/content/eicu-crd/2.0/ 重建数据库所需
MIMIC-IV demo https://physionet.org/content/mimic-iv-demo/2.2/ EHRSQL-2024 的载体库

§9.2 引用指南

引用 EHRSQL 时建议同时引用三件:原始论文(数据集来源)、共享任务概览(若使用 2024 版数据)、以及底层数据库的原始论文(MIMIC-III 与 eICU)。仅引用 EHRSQL 而不引用底层数据库,会导致复现者无法定位 SQL 所依赖的 schema。

§9.3 BibTeX

@article{lee2022ehrsql,
  title     = {EHRSQL: A Practical Text-to-SQL Benchmark for Electronic Health Records},
  author    = {Lee, Gyubok and Hwang, Hyeonji and Bae, Seongsu and Kwon, Yeonsu and
               Shin, Woncheol and Yang, Seongjun and Seo, Minjoon and Kim, Jong-Yeup and
               Choi, Edward},
  journal   = {Advances in Neural Information Processing Systems},
  volume    = {35},
  pages     = {15589--15601},
  year      = {2022}
}

@inproceedings{lee2024ehrsqlst,
  title     = {Overview of the EHRSQL 2024 Shared Task on Reliable Text-to-SQL Modeling
               on Electronic Health Records},
  author    = {Lee, Gyubok and Kweon, Sunjun and Bae, Seongsu and Choi, Edward},
  booktitle = {Proceedings of the Clinical NLP Workshop at NAACL 2024},
  year      = {2024},
  note      = {arXiv:2405.06673}
}

@article{johnson2016mimic,
  title   = {MIMIC-III, a freely accessible critical care database},
  author  = {Johnson, Alistair E. W. and Pollard, Tom J. and Shen, Lu and
             Lehman, Li-Wei H. and Feng, Mengling and Ghassemi, Mohammad and
             Moody, Benjamin and Szolovits, Peter and Celi, Leo Anthony and Mark, Roger G.},
  journal = {Scientific Data},
  volume  = {3},
  pages   = {160035},
  year    = {2016},
  doi     = {10.1038/sdata.2016.35}
}

@article{pollard2018eicu,
  title   = {The eICU Collaborative Research Database, a freely available multi-center
             database for critical care research},
  author  = {Pollard, Tom J. and Johnson, Alistair E. W. and Raffa, Jesse D. and
             Celi, Leo Anthony and Mark, Roger G. and Badawi, Omar},
  journal = {Scientific Data},
  volume  = {5},
  pages   = {180178},
  year    = {2018},
  doi     = {10.1038/sdata.2018.178}
}

§9.4 引用注意事项

  1. 引用次数与版本要标注。scholar 各镜像口径存在 109/110/112 的差异,且数据集自 2026 年仍在更新——引用时写明"截至 YYYY-MM"。
  2. 区分数据集与论文的许可。论文使用 CC BY 4.0(arXiv 标注),数据集本体同样 CC BY 4.0,但底层 MIMIC-III 与 eICU 数据库需 PhysioNet 凭证化访问。
  3. 说明所用的样本数口径。24,411 / 24.4K / 22,505 三个数字各有其语义(见坑 2),引用时明确写出你用的是哪一个。

§10 AI 使用声明卡

§10.1 AI 模型列表

模型/工具 版本/时点 参与内容
deep-model(WorkBuddy) 2026-09 初稿生成:INFOBOX 数据汇编、§1-§9 结构化写作、§6 代码示例生成、JSON-LD 构建
WebSearch(多源检索) 2026-09-28 8 组检索:官方仓库、arXiv 全文、NeurIPS 论文集、共享任务概览、排行榜、引用数快照、生态衍生
WebFetch(页面抓取) 2026-09-28 GitHub README / CHANGELOG / API 元数据、OpenReview、KAIST PURE、Benchmark 论文页
pypdf(本地解析) 2026-09-28 解析 EHRSQL-2024 概览论文 PDF(Table 1 数据统计、Table 3 官方结果)

§10.2 AI 参与范围

AI 参与范围:初稿生成 + 资料整理 + 代码生成 + 格式化排版。

AI 在本页面的工作中负责:(1) 从官方 GitHub 仓库、arXiv 论文 v6 全文、NeurIPS 论文集页、EHRSQL-2024 概览论文与共享任务站点中整理结构化信息;(2) 生成 §6 的 Python/SQL 代码示例;(3) 系统化组织 §6.5 的 8 个坑点与 §7.1 偏倚表;(4) 执行 G1/G2/G3 排版规范检查与中英文格式标准化;(5) 构建 §C 统一 JSON-LD @graph。

AI 未参与的部分:所有数据规模数字、基准性能数值、引用信息均直接取自官方来源,未经 AI 推断或补全。凡官方来源未提供的信息(如 valid/test 逐划分的可答/不可答精确计数),一律省略而非估算。

§10.3 输入来源

# 来源 类型 用于
1 Lee G. et al. “EHRSQL: A Practical Text-to-SQL Benchmark for Electronic Health Records.” NeurIPS 2022, 35:15589-15601. arXiv:2301.07695v6 论文全文 §1-§5 全部核心数字、Table 1/2/3/4/5/6/9-13
2 https://github.com/glee4810/EHRSQL 官方仓库 README 数据结构、字段定义、安装步骤、获取路径
3 https://github.com/glee4810/EHRSQL/blob/main/dataset/ehrsql/CHANGELOG.md 官方变更日志 v1.5.0/v1.5.1 变更明细、修复数量、22,505 验证数字
4 https://api.github.com/repos/glee4810/EHRSQL GitHub API stars/forks/issues/license/创建与推送时间
5 https://proceedings.neurips.cc/paper_files/paper/2022/hash/643e347250cf9289e5a2a6c1ed5ee42e-Abstract-Datasets_and_Benchmarks.html 论文集页 正式发表版本、卷期页码
6 https://openreview.net/forum?id=B2W8Vy0rarw 评审记录 投稿时间、数据集 URL、许可声明
7 https://pure.kaist.ac.kr/en/publications/ehrsql-a-practical-text-to-sql-benchmark-for-electronic-health-re 机构库 作者单位、Scopus 引用数、会议信息
8 Lee G. et al. “Overview of the EHRSQL 2024 Shared Task.” arXiv:2405.06673 共享任务概览论文 Table 1 数据统计、Table 2/3 参赛队伍与官方结果、RS 指标定义、不可答缺陷披露
9 https://sites.google.com/view/ehrsql-2024 共享任务主页 任务定义、时间线、许可(CC-BY-4.0 + ODbL)、组织者
10 https://www.codabench.org/competitions/1889 评测平台 任务范围、Docker 环境、提交方式
11 Koretsky M. J. et al. “BiomedSQL.” COLM 2026. arXiv:2505.20321 后续基准 EHRSQL 的平均 SQL 长度(109.9 tokens)对比数据
12 Yang J. et al. “Reliable Curation of EHR Dataset via LLMs.” arXiv:2511.00772 第三方评测 CELEC 在 EHRSQL-2024 上的 RS(0) 81.05% 结果
13 https://physionet.org/content/mimiciii/1.4/ 与 https://physionet.org/content/eicu-crd/2.0/ 源库页面 底层数据库的许可与访问要求
14 Kim H. et al. “ProbGate at EHRSQL 2024.” arXiv:2404.16659 参赛方案论文 季军方案方法、RS 定义细节、数据划分规模

§10.4 人工校验

内容模块 审核者 审核方式 审核状态
§2 医学背景(ICD-11 / SNOMED CT 映射、临床任务定义) 千方病案医学编辑部 交叉审核 ✅ 已通过
§3 数据集规格(版本矩阵、模态、划分、采集周期) 千方病案医学编辑部 交叉审核 ✅ 已通过
§4 DAIMS 数据字典(15 字段解析、缺失编码) 千方病案医学编辑部 交叉审核 ✅ 已通过
§5 数据划分与泄漏风险分析 千方病案医学编辑部 交叉审核 ✅ 已通过
§6 预处理 Pipeline 与 8 个坑点 千方病案医学编辑部 交叉审核 ✅ 已通过
§7 偏倚分析、DAIMS 24 项评分、外部验证矩阵 千方病案医学编辑部 交叉审核 ✅ 已通过
§8 排行榜数字与引用完整性 千方病案医学编辑部 交叉审核 ✅ 已通过
§9 BibTeX 与官方资源链接 千方病案医学编辑部 交叉审核 ✅ 已通过

§10.5 AI 生成章节标注

以下章节包含 AI 生成内容(已通过人工校验):§1.0 速览的三问叙事、§1.2 战略价值分析、§1.3 对比表解读、§4.1 字段字典的"AI 用途"列、§6.5 八个坑点的解决步骤、§7.7 DAIMS 评分解读与"对你意味着什么"、§8.2 SOTA 趋势总结。所有硬数字均标注来源,未使用 AI 推断值。

§10.6 最后人工审核日期

最后人工审核日期:2026-09-05

页面状态:published(全部内容已完成审核并发布)


§C 结构化数据(JSON-LD)


相关数据集导航

以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:

  • mediqa — 共享标签:电子健康记录 / 临床电子病历 / 评测基准 / 医疗NLP / 临床文本
  • emrqa — 共享标签:电子健康记录 / 临床电子病历 / 医学问答 / 医疗NLP
  • mednli — 共享标签:电子健康记录 / 评测基准 / 医疗NLP / 临床文本
  • apollocorpus — 共享标签:医学问答 / 评测基准 / 医疗NLP / 临床文本
  • meddialog — 共享标签:医学问答 / 医疗NLP / 临床文本
  • medcalc-bench — 共享标签:医学问答 / 评测基准 / 医疗NLP / 临床文本
  • mtsamples — 共享标签:医学问答 / 医疗NLP / 临床文本
  • clicr — 共享标签:医学问答 / 医疗NLP / 临床文本
  • blue-benchmark — 共享标签:评测基准 / 医疗NLP / 临床文本
  • healthsearchqa — 共享标签:医学问答 / 评测基准 / 医疗NLP

导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

返回 AI-Ready 数据集