信息速览
INFOBOX
| 数据集名称 | MIT-BIH Arrhythmia Database |
| 英文全称 | MIT-BIH Arrhythmia Database |
| 别名 / 简称 | MIT-BIH、MITDB、mitdb、BIH Arrhythmia Database |
| 疾病分类 | BC70–BC8Z 心律失常(ICD-11);核心映射:BC75 过早搏动 / BC71 室上性心动过速 / BC72 室性心动过速 / BC73 心房颤动 / BC80 房室传导阻滞 |
| SNOMED CT | 61086009 Premature ventricular contraction / 2598007 Atrial premature beat / 233917008 Bundle branch block / 427197007 Cardiac arrhythmia / 426996002 Cardiac rhythm normal |
| 数据模态 | 时序(双导联动态心电图 ECG) |
| AI 任务类型 | 心拍分类、心律失常检测、信号去噪、异常检测 |
| 样本总数 | 48 条 30 分钟双导联 ECG 记录(47 名受试者),约 110,000 次心拍标注 |
| 数据大小 | ~104.3 MB(解压后) |
| 数据格式 | WFDB(.hea 头文件 + .dat 信号文件 + .atr 标注文件) |
| 许可证 | 开放(PhysioNet 免费下载,无需凭证认证) |
| 访问级别 | 开放 |
| DUO 标签 | NRES |
| 语言 | 不适用(信号数据 + 符号标注) |
| 首发日期 | 1980(磁带分发)/ 1999-09(PhysioNet 在线发布)/ 2005-02-24(完整版上线) |
| 最后更新 | 2018-07-06(记录 102 标注修正) |
| 发布机构 | MIT Laboratory for Computer Science & Beth Israel Hospital (现 BIDMC) Arrhythmia Laboratory |
| 官方主页 | https://physionet.org/content/mitdb/ |
| 下载地址 | https://physionet.org/content/mitdb/1.0.0/ |
| DOI | 10.13026/C2F305 |
| 引用次数 | 4,100+(IEEE EMB 2001 论文,截至 2026-08);PhysioNet 项目浏览 3,284 次(唯一注册用户) |
| AI 就绪度评分 | ⭐⭐⭐⭐(4/5)— 金标准逐拍标注 + AAMI 标准分类 + DS1/DS2 标准划分 + WFDB 工具链完善;扣分项:仅 47 名受试者、1970 年代单中心采集、类别极不平衡 |
| 页面状态 | published |
§0 E-E-A-T 信任声明与免责声明
医学审核者:[千方病案医学编辑部]交叉审核:§2 医学背景(ICD-11 映射、心律失常临床定义、AAMI 标准分类)、§7 偏倚分析。
数据工程审核者:[千方病案医学编辑部]交叉审核,审核范围:§4 DAIMS 数据字典、§5 数据划分策略(DS1/DS2 inter-patient 范式)、§6 预处理 Pipeline 和坑点。
审核日期:2026-08-04
医疗免责声明:本页面提供的医学信息仅供研究和教育目的,不构成医疗建议、诊断或治疗方案。数据集的医学描述基于公开发表的文献,未经逐一临床验证。任何基于该数据集训练的 AI 模型在应用于临床决策前,必须经过独立的临床验证和监管审批。
技术免责声明:本页面的代码示例、预处理建议和基准性能数据基于公开资料整理,不保证在特定环境下的准确性和适用性。使用者应自行验证代码安全性和数据预处理流程的正确性。千方病案医数集不对因使用本页面信息而导致的任何直接或间接损失承担责任。
数据使用合规:使用本页面描述的数据集前,请务必阅读并遵守数据集原始许可协议。MIT-BIH Arrhythmia Database 为完全开放数据集,可直接从 PhysioNet 下载,无需额外认证。
§1 数据集概览(Overview)
§1.0 📌 30 秒速览
MIT-BIH Arrhythmia Database 是 MIT 与 Beth Israel Hospital 于 1980 年创建的全球首个公开心律失常标准心电数据库,包含 47 名受试者的 48 条 30 分钟双导联动态心电图记录,附带约 110,000 次由心脏病专家逐拍标注的参考标注。
它的独特价值在于定义了心律失常检测算法的评估范式——AAMI 标准(ANSI/AAMI EC57)将 15 种心拍类型归为 5 类(N/S/V/F/Q),de Chazal 等人提出的 DS1/DS2 患者独立划分成为事实标准。自 1980 年以来已被全球 500+ 研究机构使用,原始论文被引用 4,100 余次,是心律失常 AI 研究领域引用最多的数据集。
你可以用它来:训练和评估心拍分类模型(5 类 AAMI 标准)、开发 ECG 信号去噪和 QRS 检测算法、或作为新模型必须超越的基准数据集来证明方法的有效性。
§1.1 摘要
MIT-BIH Arrhythmia Database(MITDB)由 George B. Moody 和 Roger G. Mark 在 MIT 与 Beth Israel Hospital 的合作研究中创建,于 1980 年首次以磁带形式分发,1999 年通过 PhysioNet 在线发布,2005 年完整版上线。数据库包含 48 条 30 分钟双导联动态 ECG 记录,来自 47 名受试者(25 名男性,32-89 岁;22 名女性,23-89 岁),于 1975-1979 年间在 Beth Israel Hospital 心律失常实验室采集。信号以 360 Hz 采样率、11-bit 分辨率数字化,10 mV 量程。其中 23 条记录从约 4000 条 24 小时 Holter 记录中随机抽取(约 60% 住院、40% 门诊),另外 25 条记录专门选取以包含少见但具有临床意义的心律失常。两名以上心脏病专家独立标注每条记录的所有心拍,分歧通过协商解决,最终产生约 110,000 次逐拍参考标注。
§1.2 战略价值分析
技术创新维度:MIT-BIH Arrhythmia Database 是全球第一个公开可用的心律失常检测器标准测试材料集。在它之前,心律失常检测算法的评估缺乏统一基准——不同研究组使用各自的数据,结果无法横向比较。MIT-BIH 的出现催生了 AAMI EC57 标准(将 15 种心拍类型归为 5 大类),并推动了从基于规则的传统算法到深度学习方法的演进。WFDB 格式(.hea + .dat + .atr)由此成为 PhysioNet 的基础数据格式,影响了后续所有 PhysioNet 数据集的设计。
生态推动维度:该数据库催生了完整的 ECG 研究生态系统——WFDB 软件包(C/Python/MATLAB/Java 接口)、WAVE 交互式波形浏览器、MIT-BIH Database Directory 标注规范,以及 INCART、NSTDB、PTB-XL 等一系列衍生和互补数据集。de Chazal 等人提出的 DS1/DS2 患者独立划分方案成为 inter-patient 评估的事实标准,几乎所有严肃的心律失常分类论文都采用此划分。原始论文被引用 4,100 余次,是全球引用最多的 ECG 数据集论文。
历史地位维度:数据库创建者 Moody 和 Mark 在 2001 年的回顾文章中写道:“它的寿命远超其创建者的预期”。从 1980 年磁带分发到 2026 年的深度学习时代,该数据库已持续使用 46 年,跨越了从模板匹配到 Transformer 的多代技术演进,是医疗 AI 领域寿命最长的基准数据集。
§1.3 同类数据集对比
| 数据集 | 样本量 | 模态 | 标注方式 | 采样率 | 核心差异化 |
|---|---|---|---|---|---|
| MIT-BIH Arrhythmia | 48 条×30 min | 2 导联 ECG | 心脏病专家逐拍标注 | 360 Hz | 历史最悠久、引用最多、AAMI 标准基准 |
| INCART 12-lead | 75 条×30 min | 12 导联 ECG | 自动算法+人工修正 | 257 Hz | 12 导联覆盖,常作为 MIT-BIH 外部验证集 |
| PTB-XL | 21,837 条×10 s | 12 导联 ECG | 心脏病专家标注 | 500 Hz | 大规模、多标签、现代临床 ECG |
| MIT-BIH NSTDB | 15 条×30 min | 2 导联 ECG + 噪声 | — | 360 Hz | 专为噪声鲁棒性评估设计 |
| Chapman-Shaoxing | 10,646 条×10 s | 12 导联 ECG | 心脏病专家标注 | 500 Hz | 多心律类型、多人群 |
§1.4 版本演进时间轴
| 时间 | 事件 |
|---|---|
| 1975-1979 | Beth Israel Hospital 心律失常实验室采集原始 Holter 记录 |
| 1980 | MIT-BIH Arrhythmia Database 完成并开始以 9-track 磁带分发 |
| 1989-08 | CD-ROM 版本发布(完整 48 条记录) |
| 1999-09 | PhysioNet 上线,25 条记录信号文件 + 全部 48 条标注文件免费在线发布 |
| 2001-05 | Moody & Mark 发表里程碑回顾论文(IEEE EMB, PMID: 11446209) |
| 2005-02-24 | 完整 48 条记录信号文件在 PhysioNet 上线(v1.0.0) |
| 2018-07-06 | 记录 102 的标注 #1991 从样本 590296 修正至 590262 |
§1.5 典型 AI 应用场景
- 心拍分类:按 AAMI 标准将每个心拍分为 N/S/V/F/Q 五类,是心律失常检测的基础任务
- 心律失常检测:检测特定心律失常类型(PVC、房颤、束支传导阻滞等),用于临床预警系统
- ECG 信号去噪:开发去基线漂移、工频干扰、肌电噪声的预处理算法
- QRS 复合波检测:定位 R 峰,是所有 ECG 分析的基础步骤
- 模型基准验证:作为新模型必须超越的标准基准,证明方法有效性
§2 医学背景(Medical Context)
§2.1 ICD-11 编码
| 数据集覆盖 | ICD-11 编码 | 中文名 |
|---|---|---|
| 过早搏动 | BC75 | 过早搏动 |
| 室上性心动过速 | BC71 | 室上性心动过速 |
| 室性心动过速 | BC72 | 室性心动过速 |
| 心房颤动 | BC73 | 心房颤动 |
| 房室传导阻滞 | BC80 | 房室传导阻滞 |
| 束支传导阻滞 | BC81 | 束支传导阻滞 |
§2.1b SNOMED CT 映射
| 数据集标签 | AAMI 类 | SNOMED CT | SNOMED CT 术语 |
|---|---|---|---|
| Normal (N) | N | 426996002 | Cardiac rhythm normal (finding) |
| Left bundle branch block (L) | N | 233917008 | Left bundle branch block (finding) |
| Right bundle branch block ® | N | 233918003 | Right bundle branch block (finding) |
| Atrial premature beat (A) | S | 2598007 | Atrial premature beat (finding) |
| Premature ventricular contraction (V) | V | 61086009 | Premature ventricular contraction (finding) |
| Ventricular escape beat (E) | V | 75560003 | Ventricular escape beat (finding) |
| Fusion beat (F) | F | 7383002 | Fusion of ventricular and normal beat (finding) |
| Paced beat (/) | Q | 251199005 | Paced beat (finding) |
§2.2 疾病简介
心律失常(Cardiac Arrhythmia)是指心脏电传导系统异常导致的心跳节律、频率或传导顺序紊乱。全球约 2-3% 的人口受心律失常影响,其中心房颤动是最常见的持续性心律失常。室性心律失常(如室性早搏、室性心动过速)与心源性猝死风险密切相关。动态心电图(Holter 监测)是诊断心律失常的金标准,通过 24-48 小时连续记录捕捉间歇性发作。
§2.3 临床任务
临床任务定义:心律失常筛查与分类——从连续 ECG 信号中自动识别和分类不同类型的心律失常心拍,用于 Holter 监测报告的自动生成和实时心律监护预警。AAMI EC57 标准将此任务定义为:将每个心拍分为 5 类(N=正常/束支传导阻滞,S=室上性异位,V=室性异位,F=融合波,Q=未知),并重点评估 S 类(SVEB)和 V 类(VEB)的检测性能。
§2.4 患者人群特征
| 维度 | 特征 |
|---|---|
| 数据来源 | Beth Israel Hospital (现 BIDMC) 心律失常实验室,波士顿 |
| 采集时间 | 1975-1979 年 |
| 年龄分布 | 男性 32-89 岁,女性 23-89 岁 |
| 性别比例 | 25 男 / 22 女(53% / 47%) |
| 种族分布 | 未释放种族数据 |
| 就医类型 | 混合:约 60% 住院 + 40% 门诊 |
| 记录数 | 48 条 30 分钟摘录(从约 4000 条 24 小时 Holter 记录中选取) |
§2.5 临床意义
心律失常的自动检测具有重要的临床和社会价值。在 Holter 监测中,24 小时记录可包含超过 10 万次心拍,人工逐拍分析耗时且易疲劳出错。自动心律失常检测算法可大幅提高分析效率,使大规模心律筛查成为可能。MIT-BIH Arrhythmia Database 作为标准测试集,直接推动了商业心律失常分析仪器的性能竞争和改进——Moody 和 Mark 在 2001 年指出,该数据库与 AHA Database 一起"在刺激心律失常分析器制造商在客观可测量的性能基础上竞争方面发挥了有趣的作用"。
§2.6 金标准
| 数据划分 | 标注方式 | 标注者 | 金标准性质 |
|---|---|---|---|
| 全部 48 条记录 | 逐拍标注(15 种心拍类型 + 节律标注 + 非心拍标注) | 两名以上委员会认证的心脏病专家 | 参考标准(Reference Standard)——独立标注后协商解决分歧 |
§3 数据集规格(Specifications)
§3.0 版本抉择矩阵
| 你的需求 | 推荐版本 | 大小 | 理由 |
|---|---|---|---|
| 心律失常分类基准实验 | v1.0.0(完整版) | ~104 MB | 唯一版本,含全部 48 条记录信号+标注,PhysioNet 直接下载 |
| 历史复现(1999-2005 期间论文) | 25 条子集 | ~55 MB | 早期 PhysioNet 仅含 25 条信号文件,部分旧论文仅用此子集;现已不推荐 |
§3.1 模态详细说明
双导联动态心电图(Ambulatory ECG / Holter)。两条通道为:
- 通道 0(上信号):Modified Limb Lead II (MLII)——电极置于胸部,模拟标准肢体导联 II。除记录 114 外,所有记录的通道 0 均为 MLII。
- 通道 1(下信号):Modified V1(大多数记录),偶尔为 V2、V5,记录 124 为 V4。
§3.2 样本统计
| 统计项 | 数值 |
|---|---|
| 总记录数 | 48 条 |
| 总受试者数 | 47 名(记录 201 和 202 来自同一男性受试者) |
| 记录时长 | 每条 30 分钟(1,800 秒) |
| 采样率 | 360 samples/second/channel |
| 分辨率 | 11-bit(10 mV 量程) |
| 总心拍标注数 | ~110,000 次 |
| 心拍类型数 | 15 种 |
| 导联数 | 2 通道/记录 |
| 随机抽取记录 | 23 条(编号 100-124) |
| 选择性抽取记录 | 25 条(编号 200-234) |
§3.3 数据格式
| 文件类型 | 扩展名 | 说明 |
|---|---|---|
| WFDB 头文件 | .hea |
记录元信息:采样率、导联名、增益、基线、信号文件名 |
| WFDB 信号文件 | .dat |
二进制信号数据,每样本 11-bit(存储为 12-bit 字) |
| WFDB 标注文件 | .atr |
逐拍标注:时间戳 + 标注符号(N/L/R/V/A 等) |
§3.4 存储大小
| 版本 | 压缩后 | 解压后 |
|---|---|---|
| v1.0.0 完整版 | ~52 MB (zip) | ~104.3 MB |
§3.5 标注方式
两名以上委员会认证的心脏病专家独立标注每条记录的全部心拍。标注包括:
- 逐拍标注:15 种心拍类型符号(见 §4.2 标签分布表)
- 节律标注:如窦性心律 (NSR)、房颤 (AFIB)、室性二联律 (B) 等
- 非心拍标注:如伪影 (~)、起搏脉冲 (‘’‘’‘’‘’)、QRS 标注 (‘’‘’‘’‘’|‘’‘’‘’‘’) 等
分歧通过协商讨论解决,最终产生计算机可读的参考标注文件。
§3.6 标注者信息
| 属性 | 说明 |
|---|---|
| 标注者人数 | 每条记录 ≥2 名 |
| 资质 | 委员会认证的心脏病专家 |
| 标注方式 | 独立标注后协商解决分歧 |
| 一致性 | 未报告 Cohen’‘’‘’‘’'s Kappa 等量化一致性指标(1980 年代标准做法) |
§3.7 采集时间
1975-1979 年,在 Beth Israel Hospital 心律失常实验室采集。
§3.8 地理覆盖
单一中心:美国马萨诸塞州波士顿 Beth Israel Hospital(现为 Beth Israel Deaconess Medical Center, BIDMC)。
§3.9 采集设备
- 记录设备:1960-1970 年代便携式 Holter 监测仪(磁带记录)
- 数字化方式: playback 单元重放磁带信号,经 A/D 转换器以 360 Hz 采样率数字化
- 分辨率:11-bit,10 mV 量程(约 4.88 μV/LSB)
§3.10 深度溯源链
原始数据源
├── 4000+ 条 24 小时 Holter 磁带记录(Beth Israel Hospital, 1975-1979)
│ ├── 混合人群:~60% 住院 + ~40% 门诊
│ └── 电极配置:MLII + V1(标准胸部放置)
│
├── 记录选取
│ ├── 23 条随机抽取(编号 100-124)→ 代表日常心律失常分布
│ └── 25 条选择性抽取(编号 200-234)→ 覆盖少见但重要的心律失常
│
├── 信号处理
│ ├── 磁带 playback → A/D 转换 → 360 Hz, 11-bit 数字化
│ └── 30 分钟摘录截取
│
├── 人工标注
│ ├── ≥2 名心脏病专家独立逐拍标注
│ ├── 分歧协商解决
│ └── 生成 .atr 参考标注文件
│
└── 分发历程
├── 1980: 9-track 磁带 (800/1600 bpi) + IRIG FM 模拟磁带
├── 1989: CD-ROM 版本
├── 1999: PhysioNet 在线发布(25 条信号 + 48 条标注)
└── 2005: 完整 48 条信号在线发布 (v1.0.0)
§4 数据结构详解(Data Schema)
§4.0 目录树预览
mit-bih-arrhythmia-database-1.0.0/
├── 100.hea # 记录 100 头文件
├── 100.dat # 记录 100 信号文件
├── 100.atr # 记录 100 标注文件
├── 101.hea
├── 101.dat
├── 101.atr
├── ...
├── 234.hea
├── 234.dat
├── 234.atr
├── RECORDS # 记录列表(48 行,每行一个记录编号)
├── ANNOTATORS # 标注者列表
└── LICENSE.txt # 许可证
§4.1 DAIMS 标准化字段描述表
| 字段名 | 数据类型 | 说明 | 示例值 | AI 用途 | 观测误差 | 信息性缺失编码 | 取值范围 |
|---|---|---|---|---|---|---|---|
| record_id | string | 3 位数字记录编号 | “100” | 记录标识 | — | — | 100-124, 200-234 |
| signal_ch0 | float[] | 通道 0 信号(MLII) | [0.0, 0.1, …] | 输入特征 | ±4.88 μV/LSB | — | [-5, +5] mV |
| signal_ch1 | float[] | 通道 1 信号(V1/V2/V4/V5) | [0.0, 0.05, …] | 输入特征 | ±4.88 μV/LSB | — | [-5, +5] mV |
| annotation_time | int | 标注时间戳(样本索引) | 18 | R 峰定位 | ±1 sample (2.78 ms) | — | 0 - 648,000 |
| annotation_symbol | string | 心拍类型符号 | “N” | 分类标签 | — | “~”(伪影) | 15 种符号 |
| rhythm_label | string | 节律标注 | “(N” | 上下文信息 | — | — | NSR/AFIB/B 等 |
| sampling_rate | int | 采样率 (Hz) | 360 | 重采样参考 | — | — | 固定 360 |
| gain | int | 信号增益 (adu/mV) | 200 | 物理量转换 | — | — | 记录特定 |
| adc_zero | int | ADC 零点 | 1024 | 基线校准 | — | — | 记录特定 |
§4.2 标签分布
AAMI 五类分类标准(ANSI/AAMI EC57)
| AAMI 类 | 含义 | 包含的心拍类型 | MIT-BIH 符号 |
|---|---|---|---|
| N | 正常或束支传导阻滞 | 正常搏动、左/右束支传导阻滞、房性逸搏、交界性逸搏 | N, L, R, e, j |
| S | 室上性异位搏动 | 房性早搏、变异房性早搏、交界性早搏、室上性早搏 | A, a, J, S |
| V | 室性异位搏动 | 室性早搏、室性逸搏 | V, E |
| F | 融合波 | 室性融合波 | F |
| Q | 未知 | 起搏搏动、起搏融合波、不可分类 | /, f, Q |
DS1/DS2 标准划分(de Chazal et al.)
移除 4 条含起搏搏动的记录(102, 104, 107, 217)后,剩余 44 条记录分为:
| 数据集 | 用途 | 包含的记录编号 | N | S | V | F | Q | 总计 |
|---|---|---|---|---|---|---|---|---|
| DS1 | 训练集 | 101, 106, 108, 109, 112, 114, 115, 116, 118, 119, 122, 124, 201, 203, 205, 207, 208, 209, 215, 220, 223, 230 | 45,868 | 942 | 3,787 | 415 | 8 | 51,020 |
| DS2 | 测试集 | 100, 103, 105, 111, 113, 117, 121, 123, 200, 202, 210, 212, 213, 214, 219, 221, 222, 228, 231, 232, 233, 234 | 44,258 | 1,837 | 3,221 | 388 | 7 | 49,711 |
类别不平衡严重程度:N 类占 ~90%,S 类占 ~2-3%,V 类占 ~6-7%,F 类占 ~0.8%,Q 类占 ~0.01%。
§4.3 关键统计数据
- 总心拍数:~110,000(全部 48 条记录,含起搏记录)
- 总时长:24 小时(48 × 30 分钟)
- 总数据点:2 × 360 × 1800 × 48 = 62,208,000 个样本
- N 类占比(DS1+DS2):~90.1%
- 最少类别 Q:仅 15 个样本(DS1+DS2),几乎所有论文忽略此类
§4.4 数据层级关系
受试者 (Subject) → 记录 (Record) → 心拍 (Beat)
47 名 48 条 ~110,000 次
注意:记录 201 和 202 来自同一受试者。在 inter-patient 评估范式中,同一受试者的记录必须全部在 DS1 或全部在 DS2 中,防止数据泄漏。
§4.5 缺失值情况
| 数据项 | 缺失情况 | 说明 |
|---|---|---|
| ECG 信号 | 无缺失 | 连续信号,无间断 |
| 心拍标注 | 无缺失 | 每个心拍均有标注 |
| 患者元数据 | 大量缺失 | 仅有性别和年龄范围,无具体诊断、用药、结局信息 |
| 种族信息 | 完全缺失 | 未释放种族数据 |
§5 数据划分与使用建议(Splits & Usage)
§5.1 标准评估范式
MIT-BIH Arrhythmia Database 有两种主流评估范式,选择哪种直接影响论文的可信度:
| 范式 | 描述 | 优点 | 缺点 | 推荐度 |
|---|---|---|---|---|
| Inter-patient(患者独立) | DS1 训练,DS2 测试,不同患者完全分离 | 评估对新患者的泛化能力,临床现实 | 性能数值通常低于 intra-patient | ⭐⭐⭐⭐⭐ 强烈推荐 |
| Intra-patient(患者内) | 所有心拍混合后随机划分 train/test | 性能数值高(99%+) | 同一患者心拍同时出现在 train 和 test 中,存在数据泄漏 | ⭐⭐ 不推荐用于严肃研究 |
§5.2 Inter-patient 标准划分(de Chazal et al., 2004)
- 移除记录:102, 104, 107, 217(含起搏搏动,AAMI 建议排除)
- 训练集 DS1(22 条):101, 106, 108, 109, 112, 114, 115, 116, 118, 119, 122, 124, 201, 203, 205, 207, 208, 209, 215, 220, 223, 230
- 测试集 DS2(22 条):100, 103, 105, 111, 113, 117, 121, 123, 200, 202, 210, 212, 213, 214, 219, 221, 222, 228, 231, 232, 233, 234
§5.3 AAMI 评估指标
AAMI EC57 标准建议重点评估 S 类(SVEB)和 V 类(VEB)的性能,F 类和 Q 类误分类不施加惩罚:
- Accuracy (Acc) = (TP + TN) / 总数
- Sensitivity (Se) = TP / (TP + FN)
- Positive Predictivity (+P) = TP / (TP + FP)
- F1-Score = 2 × (Se × +P) / (Se + +P)
§5.4 心拍分割方法
标准心拍分割以 R 峰为中心,取固定窗口:
- 窗口大小:通常 280-300 samples(~0.78-0.83 秒,覆盖一个完整心搏周期)
- R 峰定位:使用标注文件中的 R 峰时间戳(.atr 文件中的标注位置)
- 对齐方式:R 峰居中或 R 峰偏左
§5.5 交叉验证注意事项
不推荐使用 k-fold 交叉验证——同一患者的心拍会泄漏到训练集和测试集中。如需多次评估,建议使用 DS1/DS2 互换法(先 DS1 训练 DS2 测试,再 DS2 训练 DS1 测试),取平均值。
§5.6 外部验证集推荐
INCART 12-lead Arrhythmia Database 是最常用的外部验证集——75 条 30 分钟记录,32 名受试者,采样率 257 Hz,心拍类型与 MIT-BIH 基本一致。跨数据集验证时需重采样到统一频率。
§6 AI 就绪指南(AI-Ready Guide)
§6.1 快速上手
# ========================================
# MIT-BIH Arrhythmia Database 快速上手 — wfdb-python
# 环境要求: pip install wfdb numpy matplotlib
#
# ⚠️ 目录结构预期:
# 请将下载的数据解压至 ./data/mitdb/ 目录,确保以下结构:
# ./data/mitdb/
# ├── 100.hea
# ├── 100.dat
# ├── 100.atr
# └── ...
#
# 或直接使用 wfdb 内置的 PhysioNet 下载功能(无需手动下载)
# ========================================
import wfdb
import numpy as np
import matplotlib.pyplot as plt
# ── 方式一:直接从 PhysioNet 在线读取(推荐入门)──
record = wfdb.rdrecord(''''''''100'''''''', pn_dir=''''''''mitdb'''''''')
annotation = wfdb.rdann(''''''''100'''''''', ''''''''atr'''''''', pn_dir=''''''''mitdb'''''''')
print(f"采样率: {record.fs} Hz")
print(f"导联: {record.sig_name}") # [''''''''MLII'''''''', ''''''''V1'''''''']
print(f"信号长度: {record.p_signal.shape}") # (648000, 2)
print(f"标注数: {len(annotation.symbol)}") # ~2273
print(f"标注类型: {set(annotation.symbol)}")
# ── 提取单个心拍(以 R 峰为中心,280 samples 窗口)──
window = 140 # 前后各 140 samples (总计 280 ≈ 0.78s)
beats = []
labels = []
for i, peak in enumerate(annotation.sample):
if peak - window < 0 or peak + window > len(record.p_signal):
continue
beat = record.p_signal[peak - window : peak + window, 0] # MLII 通道
beats.append(beat)
labels.append(annotation.symbol[i])
beats = np.array(beats)
labels = np.array(labels)
print(f"提取心拍数: {len(beats)}")
print(f"心拍形状: {beats[0].shape}")
# ── AAMI 五类映射 ──
aami_map = {
''''''''N'''''''': ''''''''N'''''''', ''''''''L'''''''': ''''''''N'''''''', ''''''''R'''''''': ''''''''N'''''''', ''''''''e'''''''': ''''''''N'''''''', ''''''''j'''''''': ''''''''N'''''''',
''''''''A'''''''': ''''''''S'''''''', ''''''''a'''''''': ''''''''S'''''''', ''''''''J'''''''': ''''''''S'''''''', ''''''''S'''''''': ''''''''S'''''''',
''''''''V'''''''': ''''''''V'''''''', ''''''''E'''''''': ''''''''V'''''''',
''''''''F'''''''': ''''''''F'''''''',
''''''''/'''''''': ''''''''Q'''''''', ''''''''f'''''''': ''''''''Q'''''''', ''''''''Q'''''''': ''''''''Q''''''''
}
aami_labels = np.array([aami_map.get(s, ''''''''Q'''''''') for s in labels])
unique, counts = np.unique(aami_labels, return_counts=True)
print(f"AAMI 分布: {dict(zip(unique, counts))}")
§6.2 数据获取
| 方式 | 链接 | 大小 | 说明 |
|---|---|---|---|
| PhysioNet 直接下载 | https://physionet.org/content/mitdb/1.0.0/ | ~52 MB (zip) | 无需认证,直接下载 |
| wfdb-python 在线读取 | wfdb.rdrecord(''''''''100'''''''', pn_dir=''''''''mitdb'''''''') |
— | 逐条在线读取,无需下载 |
| WFDB 工具包 | pip install wfdb |
— | Python API |
§6.3 预处理 Pipeline
# ========================================
# MIT-BIH 预处理 Pipeline — 完整版
# 包含:带通滤波 → 基线漂移去除 → 归一化 → 心拍分割 → AAMI 映射 → DS1/DS2 划分
# ========================================
import wfdb
import numpy as np
from scipy.signal import butter, filtfilt
# ── DS1/DS2 标准划分 ──
DS1 = [101, 106, 108, 109, 112, 114, 115, 116, 118, 119,
122, 124, 201, 203, 205, 207, 208, 209, 215, 220, 223, 230]
DS2 = [100, 103, 105, 111, 113, 117, 121, 123,
200, 202, 210, 212, 213, 214, 219, 221, 222, 228, 231, 232, 233, 234]
# 移除 4 条起搏记录:102, 104, 107, 217
# ── AAMI 映射 ──
AAMI_MAP = {
''''''''N'''''''': ''''''''N'''''''', ''''''''L'''''''': ''''''''N'''''''', ''''''''R'''''''': ''''''''N'''''''', ''''''''e'''''''': ''''''''N'''''''', ''''''''j'''''''': ''''''''N'''''''',
''''''''A'''''''': ''''''''S'''''''', ''''''''a'''''''': ''''''''S'''''''', ''''''''J'''''''': ''''''''S'''''''', ''''''''S'''''''': ''''''''S'''''''',
''''''''V'''''''': ''''''''V'''''''', ''''''''E'''''''': ''''''''V'''''''',
''''''''F'''''''': ''''''''F'''''''',
''''''''/'''''''': ''''''''Q'''''''', ''''''''f'''''''': ''''''''Q'''''''', ''''''''Q'''''''': ''''''''Q''''''''
}
# ── 带通滤波(0.5-40 Hz,去除基线漂移和高频噪声)──
def bandpass_filter(signal, fs=360, lowcut=0.5, highcut=40.0, order=4):
nyq = 0.5 * fs
b, a = butter(order, [lowcut/nyq, highcut/nyq], btype=''''''''band'''''''')
return filtfilt(b, a, signal)
# ── 归一化(Z-score,按记录独立归一化)──
def normalize(signal):
return (signal - np.mean(signal)) / (np.std(signal) + 1e-8)
# ── 心拍分割 ──
def extract_beats(signal, annotations, window=140):
"""以 R 峰为中心提取心拍"""
beats, labels = [], []
for peak, symbol in zip(annotations.sample, annotations.symbol):
if peak - window < 0 or peak + window > len(signal):
continue
beat = signal[peak - window : peak + window]
aami_label = AAMI_MAP.get(symbol, ''''''''Q'''''''')
beats.append(beat)
labels.append(aami_label)
return np.array(beats), np.array(labels)
# ── 完整 Pipeline ──
def load_dataset(record_ids, pn_dir=''''''''mitdb'''''''', fs=360):
all_beats, all_labels = [], []
for rid in record_ids:
record = wfdb.rdrecord(str(rid), pn_dir=pn_dir)
ann = wfdb.rdann(str(rid), ''''''''atr'''''''', pn_dir=pn_dir)
# 通道 0 (MLII)
raw = record.p_signal[:, 0]
filtered = bandpass_filter(raw, fs=fs)
normalized = normalize(filtered)
beats, labels = extract_beats(normalized, ann)
all_beats.append(beats)
all_labels.append(labels)
return np.vstack(all_beats), np.concatenate(all_labels)
# ── 加载训练集和测试集 ──
X_train, y_train = load_dataset(DS1)
X_test, y_test = load_dataset(DS2)
print(f"训练集: {X_train.shape}, 标签分布: {dict(zip(*np.unique(y_train, return_counts=True)))}")
print(f"测试集: {X_test.shape}, 标签分布: {dict(zip(*np.unique(y_test, return_counts=True)))}")
§6.4 框架 DataLoader
<details>
<summary>PyTorch DataLoader</summary>
import torch
from torch.utils.data import Dataset, DataLoader
import wfdb
import numpy as np
from scipy.signal import butter, filtfilt
class MITBIHDataset(Dataset):
"""MIT-BIH 心拍分类 Dataset(inter-patient 范式)"""
DS1 = [101, 106, 108, 109, 112, 114, 115, 116, 118, 119,
122, 124, 201, 203, 205, 207, 208, 209, 215, 220, 223, 230]
DS2 = [100, 103, 105, 111, 113, 117, 121, 123,
200, 202, 210, 212, 213, 214, 219, 221, 222, 228, 231, 232, 233, 234]
AAMI_MAP = {
''''''''N'''''''': 0, ''''''''L'''''''': 0, ''''''''R'''''''': 0, ''''''''e'''''''': 0, ''''''''j'''''''': 0,
''''''''A'''''''': 1, ''''''''a'''''''': 1, ''''''''J'''''''': 1, ''''''''S'''''''': 1,
''''''''V'''''''': 2, ''''''''E'''''''': 2,
''''''''F'''''''': 3,
''''''''/'''''''': 4, ''''''''f'''''''': 4, ''''''''Q'''''''': 4
}
def __init__(self, split=''''''''train'''''''', pn_dir=''''''''mitdb'''''''', window=140, fs=360):
record_ids = self.DS1 if split == ''''''''train'''''''' else self.DS2
self.beats = []
self.labels = []
for rid in record_ids:
record = wfdb.rdrecord(str(rid), pn_dir=pn_dir)
ann = wfdb.rdann(str(rid), ''''''''atr'''''''', pn_dir=pn_dir)
signal = record.p_signal[:, 0]
# 带通滤波
nyq = 0.5 * fs
b, a = butter(4, [0.5/nyq, 40.0/nyq], btype=''''''''band'''''''')
signal = filtfilt(b, a, signal)
# 归一化
signal = (signal - signal.mean()) / (signal.std() + 1e-8)
for peak, symbol in zip(ann.sample, ann.symbol):
if peak - window < 0 or peak + window > len(signal):
continue
beat = signal[peak - window : peak + window]
label = self.AAMI_MAP.get(symbol, 4)
self.beats.append(beat)
self.labels.append(label)
self.beats = np.array(self.beats, dtype=np.float32)
self.labels = np.array(self.labels)
def __len__(self):
return len(self.beats)
def __getitem__(self, idx):
beat = torch.from_numpy(self.beats[idx]).unsqueeze(0) # (1, 280)
label = torch.tensor(self.labels[idx], dtype=torch.long)
return beat, label
# ── 使用示例 ──
train_ds = MITBIHDataset(split=''''''''train'''''''')
test_ds = MITBIHDataset(split=''''''''test'''''''')
train_loader = DataLoader(train_ds, batch_size=128, shuffle=True, num_workers=4)
test_loader = DataLoader(test_ds, batch_size=256, shuffle=False, num_workers=4)
print(f"训练集: {len(train_ds)} 个心拍")
print(f"测试集: {len(test_ds)} 个心拍")
</details>
<details>
<summary>TensorFlow / Keras DataLoader</summary>
import tensorflow as tf
import numpy as np
import wfdb
from scipy.signal import butter, filtfilt
def load_mitbih_split(record_ids, pn_dir=''''''''mitdb'''''''', window=140, fs=360):
beats, labels = [], []
aami_map = {
''''''''N'''''''': 0, ''''''''L'''''''': 0, ''''''''R'''''''': 0, ''''''''e'''''''': 0, ''''''''j'''''''': 0,
''''''''A'''''''': 1, ''''''''a'''''''': 1, ''''''''J'''''''': 1, ''''''''S'''''''': 1,
''''''''V'''''''': 2, ''''''''E'''''''': 2, ''''''''F'''''''': 3, ''''''''/'''''''': 4, ''''''''f'''''''': 4, ''''''''Q'''''''': 4
}
for rid in record_ids:
record = wfdb.rdrecord(str(rid), pn_dir=pn_dir)
ann = wfdb.rdann(str(rid), ''''''''atr'''''''', pn_dir=pn_dir)
signal = record.p_signal[:, 0]
nyq = 0.5 * fs
b, a = butter(4, [0.5/nyq, 40.0/nyq], btype=''''''''band'''''''')
signal = filtfilt(b, a, signal)
signal = (signal - signal.mean()) / (signal.std() + 1e-8)
for peak, symbol in zip(ann.sample, ann.symbol):
if peak - window < 0 or peak + window > len(signal):
continue
beats.append(signal[peak - window : peak + window])
labels.append(aami_map.get(symbol, 4))
return np.array(beats, dtype=np.float32)[..., np.newaxis], np.array(labels)
DS1 = [101, 106, 108, 109, 112, 114, 115, 116, 118, 119,
122, 124, 201, 203, 205, 207, 208, 209, 215, 220, 223, 230]
DS2 = [100, 103, 105, 111, 113, 117, 121, 123,
200, 202, 210, 212, 213, 214, 219, 221, 222, 228, 231, 232, 233, 234]
X_train, y_train = load_mitbih_split(DS1)
X_test, y_test = load_mitbih_split(DS2)
train_ds = tf.data.Dataset.from_tensor_slices((X_train, y_train))
train_ds = train_ds.shuffle(10000).batch(128).prefetch(tf.data.AUTOTUNE)
test_ds = tf.data.Dataset.from_tensor_slices((X_test, y_test))
test_ds = test_ds.batch(256).prefetch(tf.data.AUTOTUNE)
# ── 简单 1D-CNN 模型 ──
model = tf.keras.Sequential([
tf.keras.layers.Conv1D(32, 5, activation=''''''''relu'''''''', input_shape=(280, 1)),
tf.keras.layers.MaxPooling1D(2),
tf.keras.layers.Conv1D(64, 5, activation=''''''''relu''''''''),
tf.keras.layers.MaxPooling1D(2),
tf.keras.layers.Conv1D(128, 3, activation=''''''''relu''''''''),
tf.keras.layers.GlobalAveragePooling1D(),
tf.keras.layers.Dense(64, activation=''''''''relu''''''''),
tf.keras.layers.Dropout(0.5),
tf.keras.layers.Dense(5, activation=''''''''softmax'''''''')
])
model.compile(optimizer=''''''''adam'''''''',
loss=''''''''sparse_categorical_crossentropy'''''''',
metrics=[''''''''accuracy''''''''])
model.fit(train_ds, epochs=30, validationevent-blocked=test_ds)
</details>
§6.5 常见坑点
⚠️ 坑点 1:Intra-patient 划分导致数据泄漏(分类:数据泄漏)
问题:将所有心拍混合后随机划分 train/test,同一患者的心拍同时出现在训练集和测试集中。由于同一患者的 ECG 形态高度个体化,模型实际上在"记忆"患者特征而非学习心律失常的通用特征。
症状:论文报告 99.9%+ 准确率,但模型在新患者数据上性能骤降(下降 10-30%)。这是 MIT-BIH 文献中最常见的错误。
解决:严格使用 DS1/DS2 inter-patient 划分(de Chazal et al., 2004),确保训练集和测试集的患者完全独立。引用 de Chazal, P. et al. (2004). “Automatic classification of heartbeats using ECG morphology and heartbeat interval features.” IEEE TBE, 51(7), 1196-1206.
⚠️ 坑点 2:类别极端不平衡(分类:偏倚陷阱)
问题:N 类占 ~90%,Q 类仅 15 个样本。直接训练会导致模型倾向于将所有心拍分类为 N 类,S 和 Q 类的召回率极低。
症状:总体准确率 95%+ 看起来很好,但 S 类 Sensitivity < 50%,Q 类完全无法检测。Macro F1 远低于 Accuracy。
解决:
- 类别加权:
class_weight = {0: 1, 1: 50, 2: 15, 3: 100, 4: 3000}(按反频率加权)- 过采样:SMOTE-Tomek 对少数类过采样(CAT-Net, 2024 验证有效)
- Focal Loss:
FL(p_t) = -α_t (1-p_t)^γ log(p_t),γ=2, α 按类别反比- 评估指标:必须报告 macro-F1 和各类独立 Sensitivity/+P,不可只看 Accuracy
⚠️ 坑点 3:Q 类(起搏/不可分类)处理不当(分类:标签理解)
问题:Q 类包含起搏搏动(/)、起搏融合波(f)和不可分类搏动(Q),总共仅 15 个样本(DS1+DS2)。AAMI 建议移除含起搏搏动的 4 条记录(102, 104, 107, 217),但剩余 Q 类样本仍极少。
症状:模型对 Q 类的预测完全随机,F 类误分为 Q 类或反之。
解决:(1) 移除 4 条起搏记录后,多数论文直接丢弃 Q 类做 4 分类(N/S/V/F),或进一步合并为 3 分类(N/S/V,将 F 并入 V);(2) AAMI EC57 标准允许 F 类和 Q 类的误分类不施加惩罚。
⚠️ 坑点 4:WFDB 信号增益和基线校准(分类:预处理陷阱)
问题:.hea 文件中的
gain和adc_zero参数控制数字值到物理量(mV)的转换。不同记录的增益可能不同,直接使用原始数字值会导致振幅不一致。症状:同一类型心拍在不同记录中振幅差异巨大,模型学习到记录特异性而非心拍形态。
解决:使用
wfdb.rdrecord()返回的p_signal(已转换为物理单位 mV),或手动转换:physical = (digital - adc_zero) / gain。然后按记录独立 Z-score 归一化。
⚠️ 坑点 5:R 峰标注偏移(分类:标签理解)
问题:.atr 标注文件中的标注位置是心脏病专家标注的 R 峰位置,但与实际信号 R 峰可能存在 ±1 sample(2.78 ms)的偏差。2018 年还修正了记录 102 的一个标注偏移(从样本 590296 修正至 590262)。
症状:心拍分割时 R 峰未居中,导致形态特征提取不一致。
解决:(1) 在标注位置 ±5 samples 范围内搜索信号最大值作为精确 R 峰;(2) 使用
wfdb.processing.gqrs_detect()或 Pan-Tompkins 算法重新检测 R 峰进行对比验证。
⚠️ 坑点 6:1970 年代信号质量差异(分类:偏倚陷阱)
问题:数据使用 1970 年代模拟磁带 Holter 记录仪采集,与现代数字 Holter 监测仪在频率响应、噪声特性和基线稳定性方面存在显著差异。模型在 MIT-BIH 上训练后在现代数据上性能下降。
症状:在 MIT-BIH 上 >99% 准确率,但在 PTB-XL 或自有现代数据集上降至 85-90%。
解决:(1) 不要仅依赖 MIT-BIH 训练——使用 PTB-XL(500 Hz, 12 导联, 现代)作为预训练或联合训练数据;(2) 在 MIT-BIH 上训练后必须在 INCART 或 PTB-XL 上做外部验证;(3) 添加与 1970 年代信号特征匹配的数据增强(带通噪声、基线漂移模拟)。
§6.6 数据增强策略
| 方法 | 安全性 | 说明 |
|---|---|---|
| 加性高斯噪声 | ✅ | 模拟传感器噪声,σ=0.005-0.02 mV |
| 基线漂移注入 | ✅ | 添加 0.1-0.5 Hz 正弦波模拟呼吸基线漂移 |
| 时间拉伸/压缩 | ✅ | ±5% 速率变化模拟心率变异 |
| 振幅缩放 | ✅ | ±10% 振幅随机缩放 |
| 随机相移 | ✅ | 在分割窗口内 ±5 samples 随机偏移 R 峰对齐 |
| 频率掩码 | ✅ | 在频域随机遮蔽 2-5 Hz 宽度的频段 |
| Mixup | ✅ | 同类心拍间 Mixup,α=0.2 |
| SMOTE-Tomek | ✅ | 少数类过采样+清洗(CAT-Net 2024 验证有效) |
| 导联翻转 | ❌ | MIT-BIH 仅 2 导联,翻转可能改变临床含义 |
| 随机导联替换 | ❌ | 不同记录的通道 1 导联不同(V1/V2/V4/V5),不可混用 |
§6.7 模型推荐配置
| 模型 | 参数量 | 预期性能(inter-patient) | 推荐场景 |
|---|---|---|---|
| 1D-CNN (3 层) | ~100K | Acc ~94-96%, Macro-F1 ~75-82% | 基线快速验证 |
| ResNet-1D (18 层) | ~1M | Acc ~96-98%, Macro-F1 ~82-88% | 主力模型 |
| BiLSTM | ~500K | Acc ~95-97%, Macro-F1 ~80-85% | 时序上下文建模 |
| Transformer | ~3M | Acc ~94-96%, Macro-F1 ~85-88% | 注意力机制研究 |
| CAT-Net (CNN+Attention+Transformer) | ~2M | Acc ~99% (intra), Macro-F1 ~88-94% | SOTA 追求 |
§6.8 硬件配置
| 配置级别 | GPU | 显存 | 训练时间(30 epoch) | 说明 |
|---|---|---|---|---|
| 最低 | 无(CPU) | — | <5 分钟 | 数据量极小(~100K 心拍),CPU 即可完成 |
| 推荐 | 任意 GPU | 4 GB+ | <1 分钟 | 1D-CNN/ResNet 单 GPU 足够 |
| 实验性 | 多 GPU | 8 GB+ | <30 秒 | 大规模超参搜索 |
注:MIT-BIH 数据集极小(~100K 心拍, 104 MB),对计算资源要求极低。瓶颈不在算力,而在方法论(划分范式、类别平衡、外部验证)。
§6.9 评估指标代码
# ========================================
# MIT-BIH AAMI 标准评估指标
# 重点评估 S 类 (SVEB) 和 V 类 (VEB)
# F 类和 Q 类误分类不施加惩罚(AAMI EC57)
# ========================================
import numpy as np
from sklearn.metrics import confusion_matrix, classification_report
def evaluate_mitbih(y_true, y_pred, class_names=[''''''''N'''''''', ''''''''S'''''''', ''''''''V'''''''', ''''''''F'''''''', ''''''''Q'''''''']):
"""
AAMI 标准评估:
- Overall Accuracy
- Per-class Sensitivity (Se) 和 Positive Predictivity (+P)
- Macro-F1 (5 类平均)
- 重点报告 S 类和 V 类
"""
cm = confusion_matrix(y_true, y_pred, labels=range(5))
print("=" * 60)
print("Confusion Matrix (Rows=True, Cols=Pred)")
print(f"{'''''''''''''''':>6} {''''''''N'''''''':>8} {''''''''S'''''''':>8} {''''''''V'''''''':>8} {''''''''F'''''''':>8} {''''''''Q'''''''':>8}")
for i, name in enumerate(class_names):
print(f"{name:>6} {cm[i,0]:>8} {cm[i,1]:>8} {cm[i,2]:>8} {cm[i,3]:>8} {cm[i,4]:>8}")
print("\n" + "=" * 60)
print("Per-class Metrics")
print(f"{''''''''Class'''''''':>6} {''''''''Se(%)'''''''':>8} {''''''''+P(%)'''''''':>8} {''''''''F1(%)'''''''':>8} {''''''''Count'''''''':>8}")
f1_scores = []
for i, name in enumerate(class_names):
tp = cm[i, i]
fn = cm[i, :].sum() - tp
fp = cm[:, i].sum() - tp
tn = cm.sum() - tp - fn - fp
se = tp / (tp + fn) * 100 if (tp + fn) > 0 else 0
pp = tp / (tp + fp) * 100 if (tp + fp) > 0 else 0
f1 = 2 * se * pp / (se + pp) if (se + pp) > 0 else 0
f1_scores.append(f1)
print(f"{name:>6} {se:>8.2f} {pp:>8.2f} {f1:>8.2f} {cm[i,:].sum():>8}")
acc = np.trace(cm) / cm.sum() * 100
macro_f1 = np.mean(f1_scores)
print(f"\n{''''''''Overall Accuracy'''''''':>20}: {acc:.2f}%")
print(f"{''''''''Macro-F1 (5-class)'''''''':>20}: {macro_f1:.2f}%")
print(f"{''''''''S-class (SVEB) Se'''''''':>20}: {cm[1,1]/cm[1,:].sum()*100:.2f}%")
print(f"{''''''''V-class (VEB) Se'''''''':>20}: {cm[2,2]/cm[2,:].sum()*100:.2f}%")
print("=" * 60)
# ── 使用示例 ──
# evaluate_mitbih(y_true, y_pred)
§6.10 MLOps 笔记
-
数据版本:v1.0.0 是唯一版本,2018 年仅有微小标注修正(记录 102),无需版本管理
-
可复现性:固定 random seed,报告 DS1/DS2 互换的均值±标准差
-
模型部署:MIT-BIH 上训练的模型不可直接部署——必须在外部数据集(INCART/PTB-XL)和真实临床数据上验证
-
报告标准:必须明确声明使用 inter-patient 还是 intra-patient 范式,否则结果不可比较
§7 质量评估与局限性(Quality & Limitations)
§7.1 已知偏倚
| 偏倚类型 | 描述 | 严重程度 | 缓解措施 |
|---|---|---|---|
| 选择偏倚 | 25/48 条记录专门选取少见心律失常,高估了罕见心律的频率 | 高 | 报告结果时注明数据集的过采样设计 |
| 单中心偏倚 | 所有数据来自波士顿一家医院 | 高 | 在 INCART/PTB-XL 等多中心数据集上外部验证 |
| 时代偏倚 | 1975-1979 年采集,模拟磁带技术 | 中 | 添加现代数据集联合训练/验证 |
| 人口偏倚 | 47 名受试者,无儿科数据,种族信息缺失 | 中 | 限制结论的泛化范围 |
| 类别不平衡 | N 类占 ~90%,Q 类仅 15 个样本 | 高 | 类别加权/SMOTE/Focal Loss,报告 macro-F1 |
§7.2 标注质量评估
| 标注方式 | 标注者 | 准确率 | 一致性 | 局限性 |
|---|---|---|---|---|
| 逐拍标注 | ≥2 名心脏病专家 | 金标准(参考标准) | 未报告量化一致性(1980 年代标准) | 未报告 Cohen’‘’‘’‘’'s Kappa;标注分歧协商过程未记录 |
§7.3 泛化性讨论
| 场景 | 失效风险 | 证据 |
|---|---|---|
| 现代数字 Holter 监测 | 高 | 1970 年代模拟磁带与现代数字设备频率响应不同 |
| 可穿戴 ECG 设备(Apple Watch 等) | 高 | 单导联/干电极 vs 双导联/湿电极,信号质量差异大 |
| 临床 12 导联 ECG | 中 | MIT-BIH 仅 2 导联,导联配置不同 |
| 儿科心律失常检测 | 高 | 无儿科数据,心率和波形形态差异大 |
| 不同种族/地区人群 | 中-高 | 单中心、人口多样性有限 |
§7.4 伦理考量
- 去标识化:数据已完全去标识化,无患者姓名、日期或直接标识符。记录编号为任意标识符。
- 知情同意:原始数据采集于 1975-1979 年,当时的伦理审查标准与现在不同。PhysioNet 在线发布时已确认符合当时的伦理规范。
- 数据再利用:数据创建于 AI 时代之前,原始受试者未预期数据将被用于 AI 训练。但数据已完全去标识化且为回顾性研究用途,符合现行伦理标准。
- 公平性:数据集人口多样性有限,可能不适用于所有人群。部署基于此数据集训练的模型时需进行公平性评估。
§7.5 公平性评估
由于数据集未释放种族信息且仅 47 名受试者,无法进行有意义的子群体公平性评估。性别分布较为均衡(53% 男 / 47% 女),但样本量不足以进行可靠的性别分层分析。
§7.6 数据漂移提示
1975-1979 年的 ECG 记录技术与 2026 年存在显著差异:
- 记录介质:模拟磁带 → 数字传感器
- 频率响应:1970 年代 Holter 的频率响应有限(约 0.05-100 Hz),现代设备可达 0.01-150 Hz
- 电极技术:湿电极 Ag/AgCl → 部分可穿戴设备使用干电极
- 临床实践:诊断标准和治疗手段已显著变化
§7.7 DAIMS 24 项数据就绪度评估表
| # | 评估项 | 状态 | 说明 |
|---|---|---|---|
| 1 | 数据字典/模式文档 | ✅ | WFDB 头文件 + MIT-BIH Database Directory 详细文档 |
| 2 | 字段级描述 | ✅ | .hea 文件格式、标注符号均有完整文档 |
| 3 | 数据类型标注 | ✅ | 信号 float, 标注 string, 时间戳 int |
| 4 | 缺失值标注 | ✅ | 无缺失值(连续信号 + 完整标注) |
| 5 | 信息性缺失编码 | ✅ | “~” 标注表示伪影区域 |
| 6 | 标准术语映射 | ✅ | AAMI EC57 标准 15→5 类映射 |
| 7 | ICD/SNOMED 映射 | ⚠️ | 未提供官方映射,本 Wiki 补充 |
| 8 | 标注者资质 | ✅ | 委员会认证心脏病专家 |
| 9 | 标注者人数 | ✅ | ≥2 名独立标注 |
| 10 | 标注一致性 | ⚠️ | 未报告 Cohen’‘’‘’‘’'s Kappa 等量化指标 |
| 11 | 标注协议文档 | ⚠️ | 标注流程描述简略,无详细协议 |
| 12 | 标注工具信息 | ❌ | 未报告使用的标注工具 |
| 13 | 数据采集协议 | ✅ | Holter 监测,30 分钟摘录,详细描述 |
| 14 | 设备规格 | ✅ | 采样率 360 Hz, 11-bit, 10 mV |
| 15 | 采集环境 | ✅ | Beth Israel Hospital, 住院+门诊混合 |
| 16 | 人口统计 | ⚠️ | 有性别和年龄范围,无种族/具体年龄 |
| 17 | 知情同意/伦理 | ⚠️ | 1970 年代标准,未报告 IRB 详情 |
| 18 | 去标识化 | ✅ | 完全去标识化 |
| 19 | 数据划分标准 | ✅ | de Chazal DS1/DS2 标准划分 |
| 20 | 评估协议 | ✅ | AAMI EC57 标准 |
| 21 | 已知偏倚文档 | ⚠️ | 选择偏倚已知但未正式文档化 |
| 22 | 数据版本控制 | ✅ | v1.0.0, 2018 年标注修正有记录 |
| 23 | 许可证 | ✅ | 完全开放,无使用限制 |
| 24 | 引用/来源 | ✅ | DOI + 期刊论文 + PhysioNet |
DAIMS 评分:17 / 24
评分解读:良好 — 接近优秀,但受限于时代。
对你意味着什么:该数据集是心律失常分类的事实标准基准,金标准标注质量极高。主要扣分项集中在:(1) 未报告标注一致性的量化指标(1980 年代标准做法,现代数据集应补充);(2) 人口统计信息有限(无种族、无具体年龄);(3) 伦理审查信息不完整(1970 年代数据)。建议在训练前执行以下操作:(1) 严格使用 DS1/DS2 inter-patient 划分;(2) 使用 SMOTE-Tomek 或 Focal Loss 处理类别不平衡;(3) 必须在 INCART 或 PTB-XL 上进行外部验证;(4) 报告 macro-F1 和各类独立指标,不可只看 Accuracy。
§7.8 外部验证矩阵
| 外部数据集/场景 | 来源机构 | 样本量 | 评估任务 | 性能指标 | 相对内部测试集变化 | 关键发现 |
|---|---|---|---|---|---|---|
| INCART 12-lead | St. Petersburg Institute of Cardiological Technics | 75 条×30 min | 5 类心拍分类 | Acc 85-93% (跨域) | -6% to -14% | 12 导联 vs 2 导联 + 不同采样率 (257 vs 360 Hz) 导致域差距 |
| PTB-XL | University Medical Center Hamburg-Eppendorf | 21,837 条×10 s | 5 类心拍分类 | Acc 80-90% (零样本迁移) | -10% to -20% | 现代 12 导联临床 ECG,1970 年代 vs 现代信号特征差异显著 |
| MIT-BIH NSTDB | MIT & BIDMC | 15 条×30 min | 噪声鲁棒性 | Se 下降 5-15% | -5% to -15% | 加入校准噪声后评估鲁棒性,原始模型在噪声条件下性能下降 |
| 可穿戴单导联 ECG | 各研究组 | 变化 | PVC 检测 | Se 70-85% | -15% to -30% | 单导联+干电极+运动伪影导致大幅性能下降 |
约束:本矩阵仅记录有同行评审论文支撑的外部评估结果。
§8 基准性能与生态(Benchmarks & Ecosystem)
§8.1 排行榜
重要注意:不同论文的绝对数值不可直接比较——取决于评估范式(inter-patient vs intra-patient)、类别数(5/4/3 类)、预处理方法和评估指标。下表按评估范式分组。
Inter-patient 范式(DS1 训练, DS2 测试,推荐)
| 排名 | 模型 | 性能指标 | 年份 | 关键技术 | 完整引用 | 代码 |
|---|---|---|---|---|---|---|
| 1 | MuRe-LAT | Acc 94.0%, Macro-F1 88.4, AUROC 96.2 | 2025 | 多分辨率 Lead-Aware Transformer + 域适应 | Masuduzzaman & Mridha, 2025, IEEE Access | — |
| 2 | CAT-Net | Acc 92-94% (inter, 估), Macro-F1 88-94 | 2024 | CNN+Attention+Transformer, SMOTE-Tomek | Islam, 2024, Biomedical Signal Processing and Control. DOI: 10.1016/j.bspc.2024.106211 | GitHub |
| 3 | Seq2Seq CNN+LSTM | Acc ~93-95% | 2020 | 序列到序列 CNN+LSTM, inter-patient | Mousavi & Afghah, 2020, IEEE Access | — |
| 4 | de Chazal et al. | Acc 86.4%, VEB Se 77.7% | 2004 | LDA + 形态+RR 间隔特征(非深度学习基线) | de Chazal et al., 2004, IEEE TBE 51(7) | — |
Intra-patient 范式(参考,数值偏高)
| 排名 | 模型 | 性能指标 | 年份 | 关键技术 | 完整引用 | 代码 |
|---|---|---|---|---|---|---|
| 1 | CAT-Net | Acc 99.14%, Macro-F1 94.69 | 2024 | CNN+Attention+Transformer, SMOTE-Tomek | Islam, 2024, BSPC | GitHub |
| 2 | CNN (3-layer) | Acc 99.0% | 2025 | 简单 1D-CNN | Apicella, 2025, CalPoly Thesis | — |
| 3 | ResNet-18 (1D) | Acc 98.5% | 2025 | 残差网络 | Apicella, 2025, CalPoly Thesis | — |
⚠️ 注意:Intra-patient 范式的 99%+ 准确率因数据泄漏而虚高,不可与 inter-patient 结果直接比较。严肃研究应采用 inter-patient 范式。
§8.2 SOTA 总结与选型建议
| 需求 | 推荐模型 | 理由 |
|---|---|---|
| 追求 SOTA 性能 | MuRe-LAT (2025) | 最新 inter-patient SOTA,含域适应和跨域泛化 |
| 平衡性能与效率 | CAT-Net (2024) | 99.14% intra, 含 SMOTE-Tomek 解决类别不平衡 |
| 快速基线验证 | 1D-CNN (3 层) | 数据集极小,简单模型即可达 94-96% inter-patient |
| 可解释性研究 | de Chazal et al. (2004) | 传统特征+LDA,非深度学习经典基线 |
| 跨域迁移研究 | MuRe-LAT | 零样本 PTB-XL→MIT-BIH 迁移达 91.7% |
§8.3 评估协议
推荐协议(inter-patient, AAMI EC57):
- 移除 4 条起搏记录(102, 104, 107, 217)
- DS1(22 条)训练,DS2(22 条)测试
- 按 AAMI 15→5 类映射标注
- 报告各类独立 Se 和 +P,重点报告 S 和 V 类
- 报告 macro-F1(5 类平均)
- F 和 Q 类误分类不施加惩罚
- 在 INCART 数据集上做外部验证
§8.4 相关数据集
| 数据集 | 关系 | 说明 |
|---|---|---|
| INCART 12-lead Arrhythmia | 互补 | 75 条×30 min, 12 导联, 257 Hz, 最常用的外部验证集 |
| MIT-BIH NSTDB | 扩展 | 噪声压力测试数据库,含从 MIT-BIH 衍生的噪声测试信号 |
| MIT-BIH P-wave Annotations | 衍生 | 12 条 MIT-BIH 记录的 P 波标注 |
| PTB-XL | 互补 | 21,837 条×10 s, 12 导联, 500 Hz, 现代大规模 ECG |
| AHA Database | 同类 | 美国心脏协会数据库,与 MIT-BIH 并列为早期标准 |
§8.5 关键论文
- Moody GB, Mark RG. “The impact of the MIT-BIH Arrhythmia Database.” IEEE Engineering in Medicine and Biology Magazine, 20(3):45-50, 2001. PMID: 11446209. — 里程碑回顾论文,4,100+ 引用,描述数据库历史、内容和影响。
- de Chazal P, O’‘’‘’‘’'Dwyer M, Reilly RB. “Automatic classification of heartbeats using ECG morphology and heartbeat interval features.” IEEE Transactions on Biomedical Engineering, 51(7):1196-1206, 2004. — 提出 DS1/DS2 inter-patient 标准划分和 LDA 基线。
- Goldberger AL et al. “PhysioBank, PhysioToolkit, and PhysioNet: Components of a new research resource for complex physiologic signals.” Circulation, 101(23):e215-e220, 2000. — PhysioNet 平台创立论文。
- Islam M. “CAT-Net: Convolution, attention, and transformer based network for single-lead ECG arrhythmia classification.” Biomedical Signal Processing and Control, 2024. DOI: 10.1016/j.bspc.2024.106211. — CAT-Net SOTA 模型,99.14% intra-patient, SMOTE-Tomek。
- Masuduzzaman & Mridha. “MuRe-LAT: Lead-Aware Multi-Resolution Transformer With Domain Adaptation for Beat-Level ECG Arrhythmia Classification.” 2025. — 最新 inter-patient SOTA,94.0% acc, 88.4 macro-F1。
- Mark RG, Schluter PS, Moody GB, et al. “An annotated ECG database for evaluating arrhythmia detectors.” IEEE Transactions on Biomedical Engineering, 29(8):600, 1982. — 数据库首次正式发表。
§8.6 社区活跃度
| 指标 | 数值 | 截至 |
|---|---|---|
| PhysioNet 项目浏览(唯一注册用户) | 3,284 | 2026-08 |
| 原始论文引用(IEEE EMB 2001) | 4,100+ | 2026-08 |
| PhysioNet 引用(Circulation 2000) | 20,000+ | 2026-08 |
| 使用该数据集的论文总数(估计) | 10,000+ | 2026-08 |
§8.7 生态快照
| 资源 | 类型 | 链接 | Star/Fork(截至 2026-08) | 为什么值得关注 |
|---|---|---|---|---|
| wfdb-python | 工具库 | GitHub | 500+/150+ | MIT-LCP 官方 Python WFDB 库,直接在线读取 MIT-BIH |
| NeuroKit2 | 工具库 | GitHub | 1.2K+/250+ | 含 ECG 处理全流程:R 峰检测→心拍分割→特征提取 |
| biosppy | 工具库 | GitHub | 700+/200+ | 生物信号处理库,含 ECG QRS 检测和心率变异性分析 |
| MIT-BIH Database Directory | 文档 | PhysioNet | — | 官方完整目录:48 条记录的导联配置、节律、心拍统计 |
| PhysioNet | 平台 | PhysioNet | — | 数据集官方托管,含下载、引用和文档 |
§9 相关资源与引用(Resources & Citation)
§9.1 引用格式
BibTeX:
@article{moody2001impact,
title={The impact of the {MIT-BIH} Arrhythmia Database},
author={Moody, George B. and Mark, Roger G.},
journal={IEEE Engineering in Medicine and Biology Magazine},
volume={20},
number={3},
pages={4550},
year={2001},
publisher={IEEE},
doi={10.1109/51.932724},
pmid={11446209}
}
@article{goldberger2000physiobank,
title={PhysioBank, PhysioToolkit, and PhysioNet: components of a new research resource for complex physiologic signals},
author={Goldberger, Ary L. and Amaral, Luis A. N. and Glass, L. and Hausdorff, Jeffrey M. and Ivanov, Plamen Ch. and Mark, Roger G. and Mietus, Joseph E. and Moody, George B. and Peng, Chung-Kang and Stanley, H. Eugene},
journal={Circulation},
volume={101},
number={23},
pages={e215e220},
year={2000}
}
§9.2 数据获取
- PhysioNet 主页:https://physionet.org/content/mitdb/1.0.0/
- DOI:https://doi.org/10.13026/C2F305
- 下载方式:直接下载 ZIP 或使用
wfdb-python在线读取 - 无需认证:完全开放,无需 CITI 培训或凭证申请
§9.3 许可证
完全开放,无使用限制。PhysioNet 数据使用政策允许任何研究目的使用,包括商业研究。
§9.4 相关链接
- MIT-BIH Database Directory — 官方完整目录
- WFDB Programmer’‘’‘’‘’'s Guide — WFDB 库编程指南
- WFDB Applications Guide — WFDB 工具集使用手册
- WAVE User’‘’‘’‘’'s Guide — 交互式波形浏览器
§9.5 常见问题
Q: 为什么只有 47 名受试者却有 48 条记录?
A: 记录 201 和 202 来自同一男性受试者,分别在两次不同时间采集。
Q: 采样率为什么是 360 Hz 而不是标准的 250/500 Hz?
A: 360 Hz 是 1980 年代 MIT-BIH 选择的采样率,可被 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 18, 20, 24, 30, 36, 40, 45, 60, 72, 90, 120, 180 整除,便于降采样。这一非标准采样率已成为心律失常文献中的事实标准。
Q: 为什么移除 4 条记录(102, 104, 107, 217)?
A: 这 4 条记录包含起搏搏动(paced beat),AAMI EC57 标准建议排除起搏记录,因为起搏器的脉冲信号会干扰心拍形态分析。
§9.6 术语表
| 术语 | 说明 |
|---|---|
| AAMI | Association for the Advancement of Medical Instrumentation,美国医疗仪器促进协会 |
| WFDB | WaveForm DataBase,PhysioNet 信号文件格式标准 |
| MLII | Modified Lead II,改良肢体导联 II |
| PVC | Premature Ventricular Contraction,室性早搏 |
| SVEB | Supraventricular Ectopic Beat,室上性异位搏动 |
| VEB | Ventricular Ectopic Beat,室性异位搏动 |
| LBBB | Left Bundle Branch Block,左束支传导阻滞 |
| RBBB | Right Bundle Branch Block,右束支传导阻滞 |
| TSST | Trier Social Stress Test(非本数据集术语,见 WESAD) |
| Holter | 24 小时动态心电图监测仪 |
§9.7 更新日志
| 日期 | 版本 | 变更 |
|---|---|---|
| 2005-02-24 | v1.0.0 | 完整 48 条记录信号文件在 PhysioNet 上线 |
| 2018-07-06 | v1.0.0 | 记录 102 标注 #1991 从样本 590296 修正至 590262 |
§10 AI 使用声明卡
§10.1 AI 模型使用
- Claude (Anthropic) — 用于撰写本 Wikipedia 条目的全部文本内容
- Web 搜索 — 用于获取最新 SOTA 模型性能数据和引用统计
§10.2 AI 参与范围
全文生成 + 研究资料整合 + 代码示例编写
§10.3 输入来源
- PhysioNet MIT-BIH Arrhythmia Database 官方页面 (https://physionet.org/content/mitdb/)
- MIT-BIH Database Directory (https://archive.physionet.org/physiobank/database/html/mitdbdir/mitdbdir.htm)
- Moody & Mark, 2001, IEEE EMB 20(3):45-50 (PMID: 11446209)
- de Chazal et al., 2004, IEEE TBE 51(7):1196-1206
- Islam, 2024, BSPC. DOI: 10.1016/j.bspc.2024.106211 (CAT-Net)
- Masuduzzaman & Mridha, 2025, MuRe-LAT
- 《Global Medical AI Datasets》PDF
§10.4 人工校验表
| 内容模块 | 审核者 | 审核方式 | 审核状态 |
|---|---|---|---|
| §2 医学背景 | 千方病案医学编辑部 | 交叉审核 | ✅ 已通过 |
| §6 代码示例 | 千方病案医学编辑部 | 逻辑审查 | ✅ 已通过 |
| §3 数据规格 | 千方病案医学编辑部 | 与 PhysioNet 官方文档交叉比对 | ✅ 已验证 |
| §8 排行榜 | 千方病案医学编辑部 | 与原始论文交叉比对 | ✅ 已验证 |
页面状态:published(全部内容已完成审核并发布)
