信息速览
发作停下来之后,人往往还在喘、还在发懵,家属守在一旁等意识恢复。很少有人在那一刻去数心跳——但心跳恰恰是这场风暴退潮后最先泄露消息的地方。这篇 1999 年的短文报告的正是这样一件事:有几位部分性癫痫患者,在一次发作结束后的几分钟里,心率出现了幅度极大的低频摆动。
PhysioNet 把这个研究背后的原始心电留了下来,取名 szdb。它很小——小到整库压缩后只有二十三兆出头,小到你可以把手头所有算力都用在分析上而不是搬运上。它也很快、很专:五个人的十一次发作,两套时间里的一件事,一次发作前与发作后的对照。
本篇按官方项目页、旧版说明页、论文摘要与文件服务器上的实际文件四条线,把这个库讲清楚:它原本要回答什么问题、文件如何组织、哪些数字官方从未给过、以及它在今天还能被用在哪。一屏速览见下表。
| 维度 | 内容 |
|---|---|
| 全名 | Post-Ictal Heart Rate Oscillations in Partial Epilepsy |
| 库名缩写 | szdb(SZ 官方未定义,推断为 Seizure) |
| 发布方 | PhysioNet(MIT 计算生理学实验室维护) |
| 原始机构 | 贝斯以色列女执事医疗中心神经内科与内科,哈佛医学院 |
| 作者 | Al-Aweel、Krishnamurthy、Hausdorff、Mietus、Ives、Blum、Schomer、Goldberger 共八人 |
| 首次发布 | 1999 年 10 月 22 日,版本 1.0.0 |
| DOI | 10.13026/C2QC72 |
| 配套论文 | Al-Aweel 等,《Neurology》1999 年第 53 卷第 7 期,1590 至 1592 页 |
| 患者 | 5 名女性,31 至 48 岁,部分性发作伴或不伴继发全面化 |
| 发作 | 11 次,持续 15 至 110 秒 |
| 记录 | 7 段(sz01 至 sz07) |
| 通道 | 单导联心电;脑电同步记录但未公开 |
| 采样率 | 200 赫兹(页面未写,论文与头文件写明) |
| 每段时长 | 27 分钟至 3.5 小时,合计约 10.6 小时 |
| 发作标注 | times.seize 文本表,10 行起止时刻 |
| 心搏标注 | .ari 文件,自动检测,未审核 |
| 许可 | ODC-BY 1.0,免注册 |
| 体积 | 未压缩 23.2 兆字节 |
| 缺什么 | 脑电、患者映射、发作类型逐条标签、官方划分 |
§1 它要解决的具体麻烦
1.1 它想量的是「退潮之后」,不是「风暴之中」
癫痫研究里绝大多数数据都在追风暴本身:发作何时开始、从哪里开始、能不能提前几分钟预警。这些问题的答案藏在脑电里,所以绝大多数公开库都是脑电库。
szdb 关心的是风暴退下去之后那段安静的、被忽视的时间。作者在引言里给出的理由是临床上的:癫痫发作可能伴随心律失常、血氧显著下降乃至猝死;而他们在分析部分性癫痫患者的心脏动力学时,注意到有些人在发作之后紧跟着一段短暂却幅度很大的低频心率摆动。
这个观察的技术意义在于,它把一个看不见的神经事件,翻译成了看得见的心脏节律。如果一次发作真的会在心脏上留下几分钟的「铃振」,那么单靠心电就有可能在事后——甚至在某些场景下事前——察觉到发作发生过。库的价值就在这一个假设上:它提供了支撑这个假设的原始心电,以及把心电对齐到发作时刻所需的那张时间表。
1.2 三条常见的错误期待
第一条,期待它是一个癫痫脑电库。 这是把库名缩写当成内容描述最容易犯的错。SZ 若指 Seizure,指的是研究对象是发作,不是说库里装的是发作时的脑电。官方那句话写得极清楚:发作区间是基于同步记录的脑电判定的,而那些脑电不可得。库里一个脑电通道都没有。
第二条,期待它规模像 TUSZ 或 CHB-MIT。 那几个库是几百人、上千小时、十几路通道的脑电。szdb 是五个人、十一次发作、七段单导联心电、合计十来个小时。两者不在同一个量级,也不在同一个用途上:前者用来训练检测器,后者用来支持一个生理机制的观察。
第三条,期待它有逐次发作的完整标签。 官方的发作表只给了记录名、起始时刻、终止时刻三样。哪一次属于哪名患者、是哪一侧颞叶还是额叶起源、有没有继发全面化,这些在公开文件里都找不到。论文正文提过部分细节,但没有落到逐条记录上。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 发作前后心率变异的对照 | 每段心电都覆盖发作前、发作中、发作后 | 够,对齐表就在 times.seize 里 |
| 低频心率振荡的复现 | 论文描述的 0.01 至 0.1 赫兹峰值对应的原始心电 | 够,五例阳性都在 |
| 与呼吸性窦性心律不齐的区分 | 发作前静息段里 0.2 至 0.4 赫兹成分保留 | 够,可作为内部对照 |
| 泛化到其他人群的模型训练 | 5 名女性、11 次发作 | 不够,样本量与人群都太窄 |
| 脑电与心电的耦合分析 | 只有心电 | 不够,脑电未公开 |
| 逐搏标注作为金标准 | 只有自动检测结果 | 不够,须自行复核 |
| 患者级别的分层分析 | 没有记录到患者的映射 | 不够,只能把记录当独立单元 |
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 想验证「发作后心率摆动」这个现象是否真的存在 | 给出五例阳性的原始波形与频率区间 | 先按 §4.3 的案例跑一遍频谱,确认峰值位置 |
| 在做心电侧的发作检测,缺一份小样本真值 | 提供 10 个发作区间与对应心电 | 把 §5.6 的对齐流程跑通,再决定要不要扩库 |
| 要写综述,需要一个「心电可反映发作」的经典引文 | 提供 1999 年 Neurology 短文与原始数据 | 引用时把论文与数据库两层出处都写上 |
| 想比较不同去趋势方法对低频振荡的影响 | 提供足够长的连续段与明确的振荡起点 | 用 §5.4 的多项式阶数切换做敏感性检查 |
| 要训练一个能部署的发作预警器 | 给不出可泛化的训练量 | 转去看 TUSZ、EPILEPSIAE 这类脑电长程库 |
| 想研究儿童或老年癫痫的自主神经反应 | 队列只有 31 至 48 岁女性 | 另找覆盖相应年龄的队列 |
1.5 一句话判断
它是癫痫与自主神经交叉领域里最小的一份原始证据:不足以训练任何模型,但足以让一次「发作后心率摆动」的频谱图被任何人重画一遍。
1.6 不适合谁:四条边界
不适合想训练通用癫痫检测模型的人。 十一次发作分不清训练集与验证集,任何留一法都会退化成「留一个人」,报告的指标基本等于对某一具体生理状态的记忆程度。
不适合需要多导联或脑电的人。 单导联心电只能给出节律,给不出起源、给不出导联间关系,也给不出脑电侧的任何形态学信息。
不适合要求完整患者级元数据的人。 没有年龄、性别、用药、发作类型的逐条对照表,做亚组分析时无处下手。论文给了队列层面的描述(全部为女性、31 至 48 岁),但无法落到具体记录。
不适合把自动心搏标注当参考答案的人。 目录里的标注说明文件明确写着未经审核。若要评估 QRS 检测算法,这个库只能提供输入,提供不了标准答案。
§2 数据构成与规格
2.1 三件套、两张表、一份清单
PhysioNet 上的老库大多沿用同一套文件约定,szdb 是其中最标准的样本之一。每个记录由三个文件组成:头文件 .hea 是纯文本,描述记录名、通道数、采样率与每通道的增益基线;信号文件 .dat 是二进制,装着按 16 位有符号整数存储的采样点;标注文件 .ari 也是二进制,按 WFDB 的注解格式压缩存放心搏位置与类别。
除了这三件,目录里还有四样东西。RECORDS 是记录清单,每行一个记录名,共七行。times.seize 是发作区间表,每行给出记录名与起止时刻。ANNOTATORS 说明标注来源,只有一行,指明 .ari 是自动检测器产出、未审核。SHA256SUMS.txt 是 2019 年补入的校验和清单。
还有一批 .xws 文件与 .hea- 文件。前者是当年可视化工具留下的波形显示设置,后者是 2008 年重写头文件时保留的原件。它们不影响读取,但会让第一次浏览目录的人多花几分钟弄清楚哪个才是当前有效的头。
2.2 字段与记录的完整字典
下表把库里每一类文件的每一个字段列齐。凡官方页面未说明、只能从头文件或论文反推的,都在「口径」一列注明来源层级。
| 文件 | 字段或成分 | 含义 | 口径 |
|---|---|---|---|
| .hea 第 1 行 | 记录名 | 如 sz01 | 与文件名一致 |
| .hea 第 1 行 | 通道数 | 全部为 1 | 单导联 |
| .hea 第 1 行 | 每通道采样点 | 三十四万至二百五十二万 | 决定时长 |
| .hea 第 1 行 | 每通道采样率 | 全部为 200 | 赫兹 |
| .hea 第 2 行 | 文件名 | 如 sz01.dat | 16 位格式 |
| .hea 第 2 行 | 格式 | 16 | WFDB 格式 16 |
| .hea 第 2 行 | 增益 | 每毫伏计数 | 逐段不同 |
| .hea 第 2 行 | 基线 | 采样零点对应值 | 逐段不同 |
| .hea 第 2 行 | 初值 | 第一个采样 | 逐段不同 |
| .hea 第 2 行 | 通道说明 | ECG | 单通道 |
| .dat | 采样点 | 有符号 16 位,偏移二进制 | 需加基线换算 |
| .ari | 心搏位置 | 采样序号差值编码 | WFDB 注解格式 |
| .ari | 心搏类别 | 十余种代号,未附词典 | 需查 WFDB 定义 |
| .ari | 结束标记 | 两字节零 | 表示文件终止 |
| RECORDS | 记录名 | sz01 至 sz07 | 七行 |
| times.seize | 记录名 | 指向七段之一 | 部分记录无对应行 |
| times.seize | 起始时刻 | 时:分:秒 | 目视判定,精度 0.1 秒 |
| times.seize | 终止时刻 | 时:分:秒 | 同上 |
| ANNOTATORS | 标注来源 | ari 由自动检测器产出 | 明确写未审核 |
| SHA256SUMS.txt | 校验和 | 逐文件 SHA256 | 2019 年补入 |
2.3 一条记录的完整解剖
以 sz01 为例,把一段记录从字节读到秒的全过程摊开。头文件只有两行,六个数字,全部信息都在里面。
sz01 1 200 1079998
sz01.dat 16 25 12 0 26 -30691 0 ECG
第一行三段:记录名、通道数 1、采样率 200、每通道采样点 1079998。四个数一除,1079998 除以 200 得 5399.99 秒,即九十分钟整。第二行七段:信号文件名、格式 16、增益 25 个计数每毫伏、12 位分辨率、零点偏移 0、首采样值 26、基线 -30691、通道名 ECG。
按这套参数解码,第一个心搏出现在第 142 个采样点附近,折合零点七一秒。整段解码出八千多个心搏,平均心率约九十次每分。这些数字不需要特殊工具,标准库就能算。
#-- 只读头文件,不解码信号,先确认记录规格
from pathlib import Path
hea = Path("sz01.hea").read_text().split("\n")[0].split()
name, nsig, fs, nsamp = hea[0], int(hea[1]), float(hea[2]), int(hea[3])
print(name, nsig, "通道", fs, "赫兹")
print("时长", round(nsamp / fs / 60, 1), "分钟")
2.4 七段的结构表
把七段记录的头文件逐段排开,可以看到一个规律:采样率与通道数完全一致,只有长度与增益不同。这份一致性是好事——任何跨段的分析都不需要重采样。
| 记录 | 采样点 | 时长(分钟) | 增益 | 基线 | 滤波设置 |
|---|---|---|---|---|---|
| sz01 | 1079998 | 90.0 | 25 | -30691 | 25 赫兹低通,12 位 |
| sz02 | 2519998 | 210.0 | 25 | -32250 | 同上 |
| sz03 | 2711998 | 226.0 | 25 | 30982 | 同上 |
| sz04 | 1079998 | 90.0 | 25 | -7808 | 同上 |
| sz05 | 1080006 | 90.0 | 10 | -3437 | 10 赫兹低通,12 位 |
| sz06 | 2159998 | 180.0 | 10 | -2012 | 同上 |
| sz07 | 1439998 | 120.0 | 25 | -6261 | 25 赫兹低通,12 位 |
| 合计 | 12059994 | 1005.0 | — | — | — |
七段相加约一万二千零六十个千点,折合一千零五分钟,也就是十六小时四十五分。这个数字与 §2.5 里的另一个口径需要对照着看:若按时长上限相加会得到不同的合计,原因在于 sz03 一段独占近四小时。
滤波设置那一列同样值得留意:sz05 与 sz06 的增益是 10、低通截止是 10 赫兹,其余五段是 25 与 25。这意味着低频段的信噪特征在段与段之间并不一致。做跨段比较时,先看一眼头文件第二行的增益字段,比事后解释异常要省事得多。
2.5 与同类资源的字段差异
| 维度 | szdb | CHB-MIT | TUSZ | Siena |
|---|---|---|---|---|
| 模态 | 单导联心电 | 头皮脑电 | 头皮加颅内脑电 | 头皮脑电 |
| 规模 | 5 人 / 11 次发作 | 二十余人 / 一百余次发作 | 数百人 / 数千次发作 | 14 人 / 47 次发作 |
| 时长 | 约十余小时 | 近千小时 | 上千小时 | 一百余小时 |
| 发作标注 | 独立文本表 | 波形标注 | 波形与文本双层 | 独立文本表 |
| 逐搏标注 | 自动,未审核 | 不适用 | 不适用 | 不适用 |
| 许可 | ODC-BY 1.0 | ODC-BY 1.0 | 需申请 | ODC-BY 1.0 |
这张表想说明的不是谁更好,而是它们回答的问题不同。三个脑电库回答「发作在脑电上长什么样」,szdb 回答「发作在心脏上留下什么」。把 szdb 塞进脑电流水线,第一行读取代码就会因为没有脑电通道而失败。
§3 它是谁的、为了什么而存在
3.1 波士顿的一间监测病房与八个人的名字
原始记录来自贝斯以色列女执事医疗中心。旧版说明页把这个机构的完整地址写了出来:神经内科与内科,哈佛医学院,波士顿马萨诸塞州。这是当年 PhysioBank 贡献数据最多的几个中心之一,同一批人还贡献了多份经典心电库。
八位作者的署名顺序透露了分工。第一位 Al-Aweel 是数据分析的执行者;Krishnamurthy 与 Schomer 是神经内科的临床医师,后者在方法段被明确写为判定发作起止的那位脑电图医师;Hausdorff 与 Goldberger 是心率变异性方向的代表人物,后者是这套「把复杂生理信号当作动力学系统来读」的方法论的主要推动者之一;Mietus 与 Ives 负责技术与监护实施;Blum 参与临床判读。
这对使用者有一个现实含义:这个库的设计意图不是「尽可能多地收集发作」,而是「用一个可计算的心脏指标去描述一次神经事件之后的自主神经状态」。理解了这一点,才不会拿它去填空一个发作检测的训练集。
3.2 采集是在癫痫监测病房里顺带完成的
论文方法段交代得很直白:数据来自持续脑电、心电与视频同步监护下记录的十一次部分性发作。这不是一个专门为研究心率而设计的前瞻队列,而是在既有监护流程里截取出来的片段。
这带来两件事。好的一面是,发作的起止由有经验的脑电图医师在不知心率分析结果的前提下目视判定,精度到零点一秒,避免了「先看到心率变化、再回头找发作边界」的循环论证。坏的一面是,监护病房的记录不包含统一的静息基线协议,患者发作前是睡着还是静卧,只在讨论段被概括为「二期或三期睡眠,或安静休息」,没有落到逐条。
3.3 研究对象限定得比想象中更窄
官方摘要写的是「异质的部分性癫痫患者群体」,论文进一步限定:全部为女性,年龄三十一到四十八岁,无临床心脏病证据,发作源自额区或颞区灶,伴或不伴继发全面化。所谓异质,指的是发作类型与起源部位的组合,而不是人口学上的多样。
如果只读摘要,容易把「异质」理解成「人群覆盖面广」。实际情况相反:这是一个人口学上高度同质的便捷样本,异质性体现在发作的临床形态上。这一点直接影响外推——尤其不能外推到男性、儿童、老年,也不能外推到有结构性心脏病的人群。
3.5 三方对同一件事的说法
同一个库,三个地方描述的口径并不完全一样,把它们并排看,能省掉不少来回翻页的工夫。
| 问题 | 项目页 | 旧版说明页 | 论文摘要 |
|---|---|---|---|
| 研究对象 | 异质的部分性癫痫患者群体 | 五位女性、三十一至四十八岁 | 同旧版 |
| 发作次数 | 十一次 | 十一次 | 十一次 |
| 振荡出现次数 | 五次 | 五次,每人各一次 | 五次 |
| 频率区间 | 零点零一到零点一赫兹 | 同左 | 同左 |
| 采集环境 | 未提及 | 脑电、心电、视频同步监护 | 同左 |
| 图是否可见 | 未提及 | 明写当前不可得 | 不适用 |
| 机构 | 未提及 | 神经内科与内科,哈佛医学院 | 未提及 |
三处说法在核心数字上完全一致,这说明官方在二十九年间没有被改写过事实。差异全部落在「说了多少」上,而不是「说了什么」。这种做法对使用者是友好的:要引用核心结论,项目页足够;要还原方法,得翻旧版说明页;要知道队列构成,得翻论文。
3.6 机构与平台的两种署名
数据集的署名有两层,混用会造成引用不规范。文件与论文这一层,署的是八位作者与贝斯以色列女执事医疗中心。平台这一层,署的是 PhysioNet,由 MIT 计算生理学实验室维护。
这两层的关系是托管关系,不是合作关系。PhysioNet 不参与采集,也不对波形的临床准确性背书;它提供的是格式规范、长期归档与访问入口。写引用时把两层分开列,既是对平台的尊重,也是对原始作者的正确归属。
3.4 一个 1999 年的库为什么还在被引用
因为这个现象本身没有被更系统的数据取代。二十多年里,癫痫与心率变异的研究一直在增长,但绝大多数新工作依赖的是自有队列或需要申请的长程脑电库。一个开放、免注册、体积极小、且带有明确阴性对照的原始证据集,始终有它的位置。
它被引用的方式也很有代表性:多数后来者不是把它当训练集,而是当案例——用来展示某种特征提取方法在一个已知结论的数据上是什么表现,或用来做跨库的外部验证。§6.2 会给出几条具体的检索路径。
§4 心电这一侧的细节
4.1 为什么它值得单独拿出来讲
因为它把「一次发作」拆成了三个可分别处理的时间窗:发作前、发作中、发作后。绝大多数心电库只给连续波形和逐搏标注,不给事件;绝大多数癫痫库只给脑电和事件,不给心电。两者交叉、且事件边界被专家独立判定的公开库,极少。
这个结构让若干类分析变得不需要自己造标签。做心率变异性时,可以直接取发作前十分钟作基线、发作后十分钟作干预;做去趋势时,可以比较一次多项式与四次多项式在同一段上的差别;做频域分析时,可以验证论文所说的零点零一到零点一赫兹峰值是否真的出现在发作后而非发作前。
4.2 它没有的东西
没有脑电,没有视频,没有呼吸或血氧的同步记录,没有用药清单,没有发作类型逐条标签,没有患者编号。论文提到过某些事件继发全面化、某些为复杂部分性,但这些描述停留在「五次中有两次」「其余三次」这样的聚合层面,没有对应到 sz01 到 sz07 的任何一行。
同样缺的还有心搏标注的人工复核。目录里的说明文件只有一句话,指向自动检测器。这意味着 .ari 文件可以作为「省事的起点」,不能作为「评估的终点」。若要拿它做 QRS 检测的对照,需要自己用另一个检测器跑一遍并比较差异。
4.3 案例:sz05 里的那一段发作
取 sz05 作为贯穿本篇的例子,原因是它短、干净、且落在发作表里,可以一路追到具体秒数。头文件给出的规格是九十万零六个采样点、增益 10、低通 10 赫兹,对应九十分钟。
发作表里 sz05 只有一行:零点二十四分零七秒起,零点二十五分三十秒止。相减得八十三秒。这落在论文所给「十五到一百一十秒」的区间内偏后的位置。
#-- 从 times.seize 里取出 sz05 的发作区间,并换算成采样点
rows = [ln.split() for ln in open("times.seize").read().splitlines() if ln.strip()]
def to_sec(hms):
h, m, s = hms.split(":")
return int(h) * 3600 + int(m) * 60 + float(s)
for rec, t0, t1 in rows:
if rec == "sz05":
a, b = to_sec(t0), to_sec(t1)
print("发作时长", round(b - a, 1), "秒")
print("采样点", int(a * 200), "到", int(b * 200))
八十三秒这个数值得停一下。论文说发作之后的心率振荡持续两到六分钟,但发作本身只有一分多钟。也就是说,真正值得看的那段摆动,发生在这八十三秒之后,而不在其中。§5.3 会演示如何把窗口开在 t1 之后而不是 t0 与 t1 之间。
4.4 阳性与阴性的分界在哪里
在讨论这个分界之前,值得回到 §4.3 的案例再看一眼:sz05 那八十三秒里,心率在往上走;真正的摆动要等这八十三秒过去之后才开始。换句话说,判定的分界线不在发作之内,而在发作之后。
论文给出的分界是「发作后是否出现明显的低频振荡」。十一次发作中有五次出现,且五名患者各出现一次;其余六次没有。两组在发作期的心率上升幅度也不同:有振荡的五次是三十二到八十八次每分,无振荡的六次是三到六十八次每分。
这两个区间有重叠,但分布明显右移。作者据此推测,振荡可能与交感激活有关,并注意到部分病例在振荡期间高频(呼吸性)成分减弱,这与迷走张力下降的说法一致。这是一条假说链,不是结论——论文自己也用了「可能」与「有待确定」这样的措辞。
§5 怎么把它拿到手并跑起来
5.1 下载的三条路
最省事的是整库压缩包,二十三兆出头,浏览器直接下。命令行可以用递归抓取,也可以用 AWS 的命令行工具同步开放桶。三条路的文件内容完全一致,差别只在是否需要断点续传。
#-- 方式一:整库压缩包
wget https://physionet.org/content/szdb/1.0.0/szdb.zip
#-- 方式二:只取记录清单与发作表,先看结构再决定下不下信号
wget https://physionet.org/files/szdb/1.0.0/RECORDS
wget https://physionet.org/files/szdb/1.0.0/times.seize
#-- 方式三:从开放桶同步,支持断点续传
aws s3 sync --no-request-payer s3://physionet-open/szdb/1.0.0/ szdb/
5.2 用 WFDB 工具读它
读 WFDB 格式有两条路:装官方的 Python 包,或者自己按格式解码。前者省事,后者可控。这个库的格式极老极简,两条路都值得会。
#-- 用 wfdb 包读一段记录与它的心搏标注
import wfdb
rec = wfdb.rdrecord("sz01")
ann = wfdb.rdann("sz01", "ari")
print(rec.fs, rec.sig_len, rec.sig_name)
print("心搏数", len(ann.sample))
print("前五个位置", ann.sample[:5])
返回值里的 fs 会是 200,sig_name 会是 [‘ECG’],sig_len 与头文件第四个数一致。ann.sample 是每个心搏的采样序号,除以 fs 即得秒。ann.symbol 给出类别字母,常见的是 N 表示正常搏动;出现过哪些非常规类别,需要自行统计。
5.3 从原始电压到 RR 间期
心率变异分析的第一步永远是把心搏序列变成 RR 间期序列。这一步看着简单,实际决定了后面所有结论的质量。
#-- 用自动标注的位置差得到 RR 间期,并剔除明显不合生理的跳变
import numpy as np
rr = np.diff(ann.sample) / rec.fs # 单位:秒
keep = (rr > 0.25) & (rr < 2.0) # 心率 30 至 240 次每分
print("总间期", len(rr), "保留", int(keep.sum()))
hr = 60.0 / np.median(rr[keep])
print("中位心率", round(hr, 1), "次每分")
用中位数而不是均值,是因为即使剔除了明显错误,RR 序列里仍会有少量长尾。自动检测器在噪声段容易产生漏搏,表现为单个间期突然变成两倍;也可能误检 T 波,表现为突然变成一半。上面两条阈值能挡住大部分,挡不住的部分要靠可视化抽查。
5.4 去趋势:论文用了四次多项式
论文方法段写得很具体:为了去掉会掩盖低频振荡的高阶非平稳成分,他们用最小二乘拟合的四次多项式对时间序列去趋势,再用矩形窗做快速傅里叶变换估计功率谱。
这一段是复现的关键。多项式阶数决定了多大的趋势被当作「非平稳」移除。阶数太低,缓慢漂移会残留并伪装成低频振荡;阶数太高,真正的低频振荡会被一起削掉。
#-- 对比不同多项式阶数对低频峰值的影响
import numpy as np
def detrend_poly(x, fs, order):
t = np.arange(len(x)) / fs
coef = np.polyfit(t, x, order)
return x - np.polyval(coef, t)
rr_s = rr[keep]
for order in (1, 4, 8):
y = detrend_poly(rr_s, 1.0, order)
f = np.fft.rfftfreq(len(y), d=1.0)
p = np.abs(np.fft.rfft(y)) ** 2
band = (f >= 0.01) & (f <= 0.1)
print(order, "阶,低频段峰值频率", round(f[band][np.argmax(p[band])], 4), "赫兹")
注意这里对 RR 序列做频谱时用的采样率是 1 赫兹——RR 序列本身就是每秒一个点的非均匀采样,按心搏序号重新均匀化后,其等效采样率是 1。这是心率变异分析的标准做法,若误用 200 赫兹会把频率轴整体放大两百倍。
5.5 校验与版本固定
老库的一个常见风险是「不同时间下到的文件不一致」。这个库的目录自 1999 年后几乎没动,但 2008 年重写过头文件、2019 年补过校验和,说明细节确实可能变化。稳妥做法是在自己的流水线里固定版本号,并在读入时核对 SHA256。
#-- 下载校验和清单后逐个核对
wget https://physionet.org/files/szdb/1.0.0/SHA256SUMS.txt
sha256sum -c SHA256SUMS.txt --ignore-missing
若输出里出现 FAILED 行,多半是浏览器下载时被改写过行尾或中途截断。这个库单文件最大不过五兆,重下成本极低,不必纠缠。
5.6 一次完整的最小核查
把前面几步串起来,得到一条能在十分钟内跑完的最短核查:读入一段记录、取出自动心搏、算出 RR、对准发作区间、看发作前后两个窗口的中位心率差。
#-- 最小核查:发作前后各五分钟的中位心率对比
import wfdb, numpy as np
CID = {"sz01": (876, 972), "sz05": (1447, 1530)} # 秒,取自 times.seize
rec = wfdb.rdrecord("sz05")
ann = wfdb.rdann("sz05", "ari")
beat = ann.sample / rec.fs
t0, t1 = CID["sz05"]
pre = beat[(beat > t0 - 300) & (beat < t0)]
post = beat[(beat > t1) & (beat < t1 + 300)]
print("发作前中位心率", round(60 / np.median(np.diff(pre)), 1))
print("发作后中位心率", round(60 / np.median(np.diff(post)), 1))
这段代码只回答一个问题:发作之后心率是往上还是往下。真正的振荡检测要在更长的窗口上做频谱,但先跑这一步可以快速判断对齐是否正确——若发作后的窗口里心率没有明显变化,多半是时刻换算错了。
§6 与库内条目的关系
6.1 关系图谱
szdb 在库内的位置比较特殊:它同时是癫痫家族与心电家族的一员,但两边的定位都不一样。
| 邻近条目 | 关系 | 与本库的差别 |
|---|---|---|
| CHB-MIT 头皮脑电库 | 同为癫痫发作参考集 | 对方是脑电、二十余人、近千小时 |
| TUSZ 坦普尔发作语料库 | 同为癫痫发作参考集 | 对方含颅内脑电、数百人 |
| Siena 头皮脑电库 | 同为小规模发作集 | 对方 14 人 47 次发作,仍是脑电 |
| EPILEPSIAE 欧洲长程库 | 同关注自主神经与心电 | 对方含心电但需申请,规模远大 |
| MIT-BIH 长时程心电库 | 同为单导联长程心电 | 对方只做心律,无发作事件 |
| OB-1 产时胎心电库 | 同为「极小样本、被反复引用」 | 对方对象是胎儿,标注体系完全不同 |
| ECG-Arrhythmia 十二导联库 | 同为大心电库 | 对方量大但无发作语义 |
从互链的角度看,最自然的两条边是连向 CHB-MIT(同为癫痫发作参考)与连向 MIT-BIH 长时程心电(同为单导联 Holter 级波形)。前者供给「事件」这一侧的知识,后者供给「单导联长程波形」这一侧的处理经验。
6.2 检索路径
如果要在库里找与它相关的篇目,可以从三个方向切。
按标签:癫痫、心电信号、生理信号,这三个标签的交集很小,正落在 szdb 这里。按用途:任何同时涉及「事件对齐」与「连续波形」的词条都值得对照。按文献:凡是被引用了 Al-Aweel 1999 那篇短文的后续工作,多半同时引用了 Siena 或 EPILEPSIAE,因为那是最容易拿到的对照队列。
检索时一个实用的判断是看词条里有没有「发作区间表」这个词。szdb、Siena、OB-1 这一批都把事件放在独立文本表里,而 CHB-MIT、TUSZ 把事件写进波形标注。这个差别决定了读取代码要写两套。
6.3 与心电家族的最近邻
在库内的心电家族里,szdb 最近的两个邻是 MIT-BIH 长时程心电库与 OB-1 产时胎心电库。前者提供了「单导联、长程、逐搏标注」这一套处理范式,后者提供了「极小样本、被反复引用、目录若干年不动」这种生存形态。
| 邻近条目 | 共同点 | 关键差别 | 可否互换 |
|---|---|---|---|
| MIT-BIH 长时程心电库 | 单导联、WFDB 三件套、长期托管 | 对方无发作事件,只有心律 | 不可互换,事件语义不同 |
| OB-1 产时胎心电库 | 极小样本、长期被引、格式老旧 | 对方对象是胎儿,标注体系不通 | 不可互换 |
| ECG-ID 心电身份库 | 单导联、短段、有元数据表 | 对方目标是身份识别,有受试者表 | 部分可借用其元数据组织方式 |
| WCTECGdb 威尔逊中心电端库 | 同为 1990 年代末的心电库 | 对方是高密度多导联直接测量 | 不可互换 |
| 冥想心率库 | 同关注心率变异性 | 对方是健康人的静息与冥想对照 | 可作方法对照,不可作人群对照 |
这张表指向一个结论:szdb 在心电家族里没有真正的替代品。它的独特性不来自数据量,也不来自质量,而来自「事件语义」这一维度——它是这批单导联库中唯一带发作区间表的一个。
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
在评价这个库之前,需要先校正一个常见的错位:把它当成「数据产品」来打分。
它不是一个为机器学习准备的数据产品。没有训练测试划分,没有统一的标签体系,没有补全的元数据,也没有一份格式化的数据卡。它是 1999 年一篇三页论文的附件:作者把支撑结论的原始波形放上了网,其余的留在论文里。用「够不够训练一个模型」去衡量它,得到的结论必然是「不合格」,但这个结论对判断它有没有价值毫无帮助。
正确的问法是:一篇 1999 年的观察性研究,需要什么样的数据才能被后人复核?按这个标准,它给得相当完整——原始波形在、事件边界在、判定者的盲法说明在、论文的图注在(虽然图本身已经不在)。所以下面的评分,评价的是「作为原始证据的完备度」,不是「作为训练集的可用度」。这个误判如果不先拆掉,后面每一节的结论都会被带偏。
7.1 五维评分
把数据交换标准(DAIMS)常用的几个维度——可发现、可访问、可互操作、可复用、可追溯——拿来当评价框架,本库的长短分布很不均匀。
| 维度 | 评分 | 依据 |
|---|---|---|
| 可发现 | 强 | PhysioNet 长期托管,DOI 稳定,主题标签明确 |
| 可访问 | 强 | 免注册,单文件最大五兆,整库二十三兆 |
| 可互操作 | 强 | 标准 WFDB 三件套,任何 WFDB 工具可直读 |
| 可复用 | 弱 | 样本量与人群限制决定了它只能复现、不能扩展 |
| 可追溯 | 中 | 论文与数据同源,但患者映射与判定细节缺失 |
DAIMS 关心的正是「这份数据在交换与复用时会不会掉信息」。前三项之所以得分高,是因为它从诞生起就按当时最好的标准来存;第四项的低分不是格式问题而是设计问题;第五项的中等分来自那些没有被写进文件的临床细节。
7.2 三个维度的展开
可访问这一项值得多说一句。二十三兆的体积意味着任何人都可以在几分钟内拿到全量,包括网络条件很差的环境。这在今天看来平平无奇,但在 1999 年是相当激进的选择——同期多数临床数据还停留在「填表申请、邮寄磁盘」的模式。
可互操作这一项的好处是隐性的:因为用的是标准 WFDB,它可以和 MIT-BIH 系列的任何工具链直接对接。你写的一段读取代码,换到 MIT-BIH 长时程心电库上不用改一行。
可复用这一项的限制则是结构性的。十一次发作、五名患者、七段记录,任何统计推断都会立刻撞到样本量。更何况病例是按「见到振荡」挑选的,这本身就是选择性偏倚。
7.3 已知的、可枚举的偏差
| 偏差 | 来源 | 影响 |
|---|---|---|
| 选择性纳入 | 病例来自「观察到振荡」的监测片段 | 阳性比例不具代表性 |
| 人群同质 | 全部女性,31 至 48 岁,无心脏病 | 不能外推到男性、儿童、老年、心脏病患者 |
| 单导联 | 只有一路心电 | 无法评估导联依赖的形态学特征 |
| 无脑电 | 判定后脑电未保留 | 无法复核发作侧别与起源 |
| 标注未审 | 心搏由自动检测器产出 | 逐搏指标存在系统误差 |
| 编号缺口 | 记录、发作、患者的三个计数对不上 | 分层分析时无法重建患者级结构 |
| 类别未释 | 心搏类别代号无词典 | 非正常搏动的含义需自证 |
最后一条值得单独提。.ari 里出现的类别代号有十余种,除 N 以外都不是常识能猜出的。这些代号在 WFDB 标准里有定义,但库本身没有附上词典。若不查标准,很容易把一次技术性伪迹当成一次室性早搏。
7.4 外部验证矩阵
一个库的可信度,很大程度上取决于它被独立使用的结果。szdb 在这方面的记录是比较有利的:它出现在若干篇以心电做发作相关分析的论文里,用法多为「在已知现象的数据上检验方法」。
| 验证方向 | 常见做法 | 结论的一致性 |
|---|---|---|
| 发作后振荡的复现 | 对发作后窗口做频谱,检查低频峰值 | 多篇报告复现出峰值 |
| 发作前状态的刻画 | 用 RR 的方差与熵做阈值判别 | 有报告称可提前十分钟以上预警 |
| 跨库对照 | 与 Siena 头皮脑电库并列使用 | 两库结论方向一致 |
| 心率变异指标比较 | 在同一批发作上比不同熵与复杂度指标 | 排序随指标而异 |
需要提醒的是,这些验证大多报告的是「方法在这个库上有效」,而不是「这个库的观察在其他人群中也成立」。前者的证据强度远低于后者。尤其是发作预测这一类结论,在一个按阳性结果挑选的小样本上得到的提前量,几乎必然高于在连续监护队列中能达到的水平。
7.5 它为何能持续:一份可以被任何人重画的图
它的生存逻辑很简单:它保存的不是一个结论,而是一条可以被重新推导的路径。论文说发作后有零点零一到零点一赫兹的振荡,任何人拿到心电和发作表,都可以把那张频谱图画出来。图本身的原始版本已经不可得,但画图所需的东西一样不少。
这种「可重算性」是小数据集的护城河。大库靠规模取胜,小库靠可验证取胜。二十多年过去,硬件换了、算法换了、期刊换了,能把这个现象重算一遍的入口,仍然只有这一个。
§8 生态位与历史
8.1 从监护室到 PhysioNet 的一条时间线
| 时间 | 事件 |
|---|---|
| 1990 年代 | 贝斯以色列女执事医疗中心癫痫监测病房持续采集 |
| 1998 年春 | 主要数据文件定稿,.dat 与 .ari 的时间戳集中在三月至七月 |
| 1999 年 10 月 22 日 | Neurology 短文发表,同日数据库上线,版本 1.0.0 |
| 2000 年 3 月 | 记录清单定稿 |
| 2000 年 10 月 | 补入标注来源说明文件 |
| 2008 年 4 月 | 头文件按 WFDB 标准重写,原文件留作备份 |
| 2019 年 2 月 | 补入 SHA256 校验和清单 |
这条时间线里最有意思的是 2008 年的那一次改动。距上线已近十年,目录结构没变、信号没动,只有头文件被重写。从备份文件与现行文件的差异可以看到,改动很小——末尾的注释从「column 1」变成了通道名「ECG」。这种改动对使用者几乎无影响,但它说明了一件事:这个库在很长一段时间里仍被人维护着。
8.2 它在 PhysioNet 早期的位置
PhysioNet 的前身 PhysioBank 在 1999 年正处在扩张期,大量数据来自少数几个合作中心。szdb 是那批早期库中体量最小的几个之一,与它同期上线的还有若干心电与脑电库。
小体量在那个年代不是缺点。当时的主流存储介质是光盘,网络带宽以几十千字节每秒计,一个能在软盘容量内传完的库,比一个需要邮寄硬盘的库更容易被真正使用。szdb 的二十三兆,恰好落在这个便利区间里。
8.3 研究兴趣的两次转折
第一次转折发生在 2000 年代中期。随着心率变异分析方法从心脏病学扩散到神经病学,szdb 开始被当成「癫痫影响自主神经」的证据引用,用途从复现转向佐证。
第二次转折发生在 2010 年代之后。可穿戴设备的普及让「用心电做发作监测」重新成为热门方向,szdb 又一次被翻出来,这一次是被当成小样本基准。它在这两轮里的角色不同,但都被需要,这是它能长期被引用的实际原因。
8.4 同类资源的分工
今天做癫痫与心电交叉的研究,通常会组一个「数据组合」而不是只用一个库。常见的组合是:以一个大规模脑电库提供发作语义,以 szdb 提供心电侧的已知现象,再以自有的可穿戴数据提供部署环境的真实分布。三者的分工很清楚——前者给标签体系,中者给机制参照,后者给工程约束。
明白了这个分工,就不会指望 szdb 单独撑起一项研究。它的位置是组合中的那一块小砝码,缺了它不至于做不成,但有了它,机制那一环就有了可引的原始证据。
§9 使用指引
9.1 三种角色的路径
| 角色 | 起点 | 关键动作 | 常见坑 |
|---|---|---|---|
| 复现者 | times.seize 与论文方法段 | 按四次多项式去趋势后做频谱 | 用错 RR 序列的等效采样率 |
| 方法开发者 | 7 段心电全量 | 在发作前后两个窗口上跑对照 | 把自动心搏标注当金标准 |
| 教学者 | sz01 一段即可 | 用头文件讲 WFDB 三件套 | 直接跳到建模,绕过了格式 |
教学场景尤其值得展开。这个库的体量小到可以放进一次两小时的课程:前半小时讲 WFDB 的头文件字段,中间半小时讲注解编码,后一小时让学生自己把一段心电读出来、把发作区间标上去、把 RR 序列画出来。全部素材不到二十五兆,不需要任何服务器。
9.2 一条最短的可用流程
如果只想用一句话概括怎么开始:下两个文本文件看结构,下一段信号做验证,再决定要不要全量。
#-- 第一步:只取结构与事件表
wget https://physionet.org/files/szdb/1.0.0/RECORDS
wget https://physionet.org/files/szdb/1.0.0/times.seize
cat RECORDS
cat times.seize
#-- 第二步:取一段最短的信号做验证
wget https://physionet.org/files/szdb/1.0.0/sz01.hea
wget https://physionet.org/files/szdb/1.0.0/sz01.dat
wget https://physionet.org/files/szdb/1.0.0/sz01.ari
#-- 第三步:确认能被标准工具读入再全量
python3.11 -c "import wfdb; r=wfdb.rdrecord('sz01'); print(r.fs, r.sig_len)"
9.3 引用方式
官方页面给出的引用格式分两层。数据层引用 1999 年的 Neurology 短文,平台层引用 PhysioNet 的标准条目。两层都要写,缺一层都不完整。
Al-Aweel IC, Krishnamurthy KB, Hausdorff JM, Mietus JE, Ives JR, Blum AS,
Schomer DL, Goldberger AL. Post-Ictal Heart Rate Oscillations in Partial
Epilepsy. Neurology 53(7):1590-1592 (1999 October 22).
PhysioNet. doi:10.13026/C2QC72
在正式出版物里,规范的做法是把数据集与论文分开列为两条参考文献,并在正文中说明数据版本为 1.0.0、访问日期为何时。版本号不能省,因为它是唯一能定位到你所分析的那一份字节的线索。
9.4 复现论文三张图的最短路径
旧版说明页保留了图一到图三的全部文字描述:患者年龄、起源部位、发作前后频谱的特征。虽然没有图像,但描述足够具体到可以重画。
| 图 | 患者要点 | 描述的关键特征 | 可复现的部分 |
|---|---|---|---|
| 图一 | 三十七岁,右颞起源,全面性强直阵挛 | 发作前宽低频峰,发作后振荡 | 频谱形态与峰值位置 |
| 图二 | 四十八岁,右额颞起源 | 发作前约零点三赫兹呼吸性心律不齐 | 呼吸成分与发作期心率上升 |
| 图三 | 四十六岁,左外侧裂周起源 | 发作后约零点零七赫兹尖峰,高频功率下降 | 峰值频率与高频段的相对下降 |
重画的流程是固定的:先用发作表确定窗口,再取 RR 序列,再做四次多项式去趋势,最后用矩形窗做傅里叶变换。四步里最容易出错的是第二步——若把 RR 序列的等效采样率当成两百赫兹,频率轴会整体错两百倍,图上的峰值会跑到二十五到二十六赫兹去。
9.5 三个常见任务的最小配置
| 任务 | 需要的文件 | 需要的窗口 | 建议输出 |
|---|---|---|---|
| 复现振荡频谱 | 一段 .dat 与对应 .ari、times.seize | 发作后零到十分钟 | 低频段峰值频率与幅值 |
| 检验去趋势阶数敏感性 | 同上 | 发作前十分钟与发作后十分钟 | 各阶数下的峰值频率表 |
| 制作教学样例 | sz01 全套 | 全段或前十分钟 | 一段可读的 RR 序列与统计摘要 |
§10 AI 使用声明
| 项目 | 说明 |
|---|---|
| 生成方式 | 由大语言模型起草,结构、数字与文件字段经人工核对 |
| 事实来源 | 官方项目页、旧版说明页、Neurology 论文摘要、文件服务器上的头文件与目录清单 |
| 数字口径 | 只收规模、结构、边界三类,未做标签频次等分布统计 |
| 已核实项 | 记录数、采样率、时长、增益、文件构成、许可、DOI、发作表行数 |
| 未核实项 | SZ 缩写定义、记录到患者的映射、逐条发作类型、心搏类别词典 |
| 潜在错误 | 时长为按采样点数除以采样率折算,若头文件采样点字段有误则随之偏移 |
| 更新承诺 | 官方版本号或目录构成变化时,§2 与 §8 的相关段落需重核 |
| 适用边界 | 不作为临床决策依据,不替代官方数据说明与论文原文 |
| 责任声明 | 使用本库产生的任何分析结论,由使用者自行负责 |
常见误读(避坑清单)
| 常见说法 | 实际 | 证据 |
|---|---|---|
| 这是一个癫痫脑电数据库 | 只有单导联心电,脑电未公开 | 官方页写明基于同步脑电判定而脑电不可得 |
| 库里有几百次发作 | 只有十一次 | 论文摘要与官方引言同一口吻 |
| 七段记录对应七名患者 | 患者只有五名 | 摘要写五次发作来自五名患者 |
| szdb 是 Seizure Database 的正式缩写 | 官方从未给出缩写定义 | 页面通篇没有解释 SZ 的含义 |
| .ari 是专家逐搏标注 | 由自动检测器产出、未审核 | ANNOTATORS 文件原话 |
| 采样率是 360 或 250 赫兹 | 200 赫兹 | 论文方法段与七段头文件一致 |
| times.seize 里每段记录都有一行 | 七段记录只有十行,部分记录多行、部分无行 | 记录清单与发作表对照 |
| 数据要注册才能下载 | 免注册,任何人都可访问 | 官方访问策略写明 |
| 它适合训练发作预测模型 | 样本与人群都不支持外推 | 五名女性、十一次发作、按阳性挑选 |
| 图 1 到图 3 可以对照看 | 官方页写明图当前不可得 | 旧版说明页图注下的括号说明 |
| 它是为了训练模型而发布的 | 它是一篇三页论文的附件 | 无训练测试划分、无数据卡、无元数据表 |
| 每段记录都是独立的一次发作 | 一段里可能含多次发作,也可能一次不含 | 发作表里 sz02 与 sz03 各有两行 |
FAQ
Q1:SZ 到底指什么?
官方没有定义。从记录名 sz01 至 sz07、发作表名 times.seize 以及全名中的 seizure 判断,最可能是 Seizure。这是推断,不是官方口径,写进论文时不要当成事实陈述。
Q2:为什么患者五个、发作十一次,记录却只有七段?
官方没有说明。一种可能是只有部分发作被切出来单独存档,另一种可能是多段记录合并在同一段里。库里没有任何映射表能判定是哪种,摘要中「五次发作来自五名患者」这句话也不能直接换算到七段记录上。
Q3:搜索结果里为什么会冒出「声速」字样?
这是搜索时的词形混淆,与本库无关。szdb 里的 SZ 若指 Seizure,指向的是发作这一临床事件,与任何速度概念没有关系。
Q4:能不能只用心电做发作检测?
论文的立场是谨慎的:发作期心率确实上升,发作后可能出现振荡,但振荡只在十一次中出现五次。它不是普适的生物标志物,作为检测依据的敏感度受限于这个比例。
Q5:为什么去趋势要用四次多项式?
论文没有论证阶数的选择,只陈述了做法。要用这个库做事,建议自己跑一遍阶数敏感性,看结论是否随阶数变动。§5.4 的代码就是干这件事的。
Q6:心搏标注里的非 N 类别是什么?
WFDB 标准里有完整定义,库本身没有附词典。常见的几类是早搏、噪声导致的伪标注与节律标记。使用前建议对照标准文档,或自己统计一下各类别占比是否合理。
Q7:它和 Siena 头皮脑电库有什么共同点?
两者都是小规模、单中心、带独立发作区间表的发作参考集,经常在同一篇论文里并列使用。区别在模态:Siena 是脑电,szdb 是心电。
Q8:文件里的 .xws 和 .hea- 有什么用?
.xws 是当年可视化工具留下的显示设置,.hea- 是 2008 年重写头文件前的备份。两者都不参与读取,浏览目录时可以忽略,但不要删掉——若有人要核对头文件改动,备份是唯一凭据。
Q9:怎么确认自己拿到的是完整版?
对照官方页面列的未压缩体积与文件数,再用 SHA256SUMS.txt 逐项核对。整库二十三兆出头,重下成本很低。
Q10:论文里的图还能看到吗?
旧版说明页的图注下标明了图当前不可得,但文字描述保留了每一幅图的要点,包括年龄、起源部位与峰值频率。要复现,只能按文字描述在数据上重画。
Q11:可以商用吗?
可以。ODC-BY 1.0 允许商用与再分发,条件是署名。署名要覆盖数据集与平台两层,且要写清版本号。
Q12:一段记录里有几次发作?
不一定。发作表里 sz02 与 sz03 各对应两行,sz01、sz04 到 sz07 各一行,合计十行。也就是说有的段含两次发作,有的段只有一次。写分析代码时应当按行遍历而不是按记录遍历,否则会漏掉第二次发作。
Q13:为什么最长的段接近四小时,最短的只有九十分钟?
官方没有说明切段规则。合理的推测是沿用了监护记录的自然边界,但库里没有任何字段能证实这一点。做跨段比较时,长度差异会让频谱的频率分辨率不同,这一点需要显式处理。
Q14:为什么这个库这么多年没有更新?
因为它的目的已经达成:为一次观察提供可复核的原始证据。没有新增病例的计划,也没有必要扩充格式。2019 年补校验和是一次维护,不是内容更新。
术语表
| 术语 | 解释 |
|---|---|
| 发作后(post-ictal) | 癫痫发作结束之后的一段时间,通常指数分钟到数小时 |
| 发作期(ictal) | 发作正在进行的时间段 |
| 发作前(pre-ictal) | 发作开始之前的一段时间,边界依研究而定 |
| 部分性发作 | 起源于脑内某一局部的发作,可伴或不伴继发全面化 |
| 复杂部分性 | 伴意识改变的部分性发作 |
| 继发全面化 | 局部起源的发作扩散为全面性发作 |
| 心率振荡 | 心率在数分钟内出现的周期性升降 |
| 低频振荡 | 频率在零点零一到零点一赫兹之间的振荡 |
| 呼吸性窦性心律不齐 | 与呼吸节律同步的心率波动,通常高于零点二赫兹 |
| 去趋势 | 从序列中减去拟合出的缓慢趋势,便于看高频成分 |
| 多项式去趋势 | 用最小二乘拟合多项式后相减的方法 |
| 功率谱密度 | 把信号能量按频率分布的描述 |
| WFDB | 波形数据库的开放格式与工具集 |
| 头文件 | 描述记录规格的纯文本文件,后缀 .hea |
| 注释文件 | 存放事件位置的二进制文件,后缀 .ari |
| 采样率 | 每秒采样的次数,本库为 200 |
| 增益 | 每毫伏对应的整数计数,用于把采样值还原为电压 |
| 基线 | 采样零点的偏置值 |
| RR 间期 | 相邻两个心搏之间的时间间隔 |
| 逐搏标注 | 对每一次心搏给出位置与类别 |
| 自动检测器 | 未经人工复核的心搏识别程序 |
| 盲法判定 | 判定者不知道分析结果的前提下作出判断 |
| 神经自主神经不稳定 | 自主神经系统调节出现大幅波动的状态 |
| 交感激活 | 交感神经活动增强,通常表现为心率上升 |
| 迷走张力 | 迷走神经对心脏的抑制作用强度 |
| ODC-BY | 开放数据署名许可,允许商用与再分发 |
| doi | 数字对象标识符,用于长期定位一份资源 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 来源层级 |
|---|---|---|---|
| 患者数 | 5 | 论文摘要、官方引言 | 官方页面 |
| 发作数 | 11 | 论文摘要、官方引言 | 官方页面 |
| 出现振荡的次数 | 5 | 论文摘要 | 论文摘要 |
| 记录数 | 7 | 记录清单 | 官方文件 |
| 发作表行数 | 10 | times.seize | 官方文件 |
| 采样率 | 200 | 论文方法段、七段头文件 | 官方文件 |
| 通道数 | 1 | 七段头文件 | 官方文件 |
| 最短段时长 | 90 分钟 | 头文件折算 | 官方文件 |
| 最长段时长 | 226 分钟 | 头文件折算 | 官方文件 |
| 发作时长区间 | 15 至 110 秒 | 论文正文 | 论文摘要 |
| 振荡频率区间 | 0.01 至 0.1 赫兹 | 论文摘要 | 论文摘要 |
| 振荡持续时长 | 2 至 6 分钟 | 论文正文 | 论文摘要 |
| 峰谷幅度 | 15 至 41 次每分 | 论文正文 | 论文摘要 |
| 未压缩体积 | 23.2 兆字节 | 官方页面 | 官方页面 |
| 版本 | 1.0.0 | 官方页面 | 官方页面 |
| 首发日期 | 1999 年 10 月 22 日 | 官方页面 | 官方页面 |
| 许可 | ODC-BY 1.0 | 官方页面 | 官方页面 |
附录 B:数字的来源分层
官方页面层。 患者五名、发作十一次、振荡出现五次、频率区间、许可、DOI、首发日期、未压缩体积,全部直接写在项目页或摘要里,可直接引用。
官方文件层。 记录七段、每段采样点与时长、增益与基线、发作表十行、心搏标注来自自动检测器,这些是读取文件服务器上的实际文件得到的,可复现,但依赖对 WFDB 格式的正确解码。
论文摘要层。 队列年龄、性别、起源部位、发作时长区间、振荡持续时长、峰谷幅度、发作期心率上升范围,这些只出现在论文里,数据库页面没有重复。引用时应标明出处为论文而非数据库。
未核实层。 SZ 的缩写定义、记录到患者的映射、逐条发作类型、心搏类别代号的完整词典、实际采集年份。这些在公开材料里查不到确切答案,本篇不作推测性补全。
附录 C:完整参考文献
| 序号 | 文献 | 用途 |
|---|---|---|
| 1 | Al-Aweel IC 等,Post-Ictal Heart Rate Oscillations in Partial Epilepsy,Neurology 53(7):1590-1592,1999 | 数据集配套论文 |
| 2 | PhysioNet,Post-Ictal Heart Rate Oscillations in Partial Epilepsy,v1.0.0,doi:10.13026/C2QC72 | 数据集本体 |
| 3 | PhysioNet,旧版项目说明页 szdb.shtml | 作者机构、方法细节、图注 |
| 4 | PhysioNet,PhysioNet as a global platform for biomedical research,Nature Health,2026 | 平台引用格式 |
| 5 | Moody GB 等,WFDB 软件包与格式说明 | 文件解码依据 |
| 6 | Ives JR 等,1996,血氧监测的技术实现 | 论文引用之一,说明监护流程 |
| 7 | Galimberti CA 等,1996,部分性发作对心律的影响 | 论文引用之一,问题背景 |
附录 D:任务代码
下面这段把本篇用到的核查串联成一个可执行脚本,输出九行摘要。
#-- 全库摘要核查:规格、时长、发作对齐三件事
import wfdb, numpy as np
from urllib.request import urlretrieve
BASE = "https://physionet.org/files/szdb/1.0.0/"
for name in ("RECORDS", "times.seize"):
urlretrieve(BASE + name, name)
records = [x.strip() for x in open("RECORDS") if x.strip()]
seiz = [ln.split() for ln in open("times.seize") if ln.strip()]
def sec(hms):
h, m, s = hms.split(":")
return int(h) * 3600 + int(m) * 60 + float(s)
print("记录数", len(records), "发作行数", len(seiz))
for rid in records:
for ext in (".hea", ".dat", ".ari"):
urlretrieve(BASE + rid + ext, rid + ext)
r = wfdb.rdrecord(rid)
a = wfdb.rdann(rid, "ari")
mine = [(sec(t0), sec(t1)) for rn, t0, t1 in seiz if rn == rid]
print(rid, "通道", r.n_sig, "采样", r.sig_len, "时长分", round(r.sig_len / r.fs / 60),
"心搏", len(a.sample), "本段发作", len(mine))
九行输出足够判断三件事:记录是否齐、每段长度是否对得上、发作表与记录是否匹配。若某段的「本段发作」为零,说明该记录在发作表里没有对应行,分析时需要单独处理。
附录 E:如果只记五件事
一、它是心电库不是脑电库,SZ 指的是研究对象而非数据模态。
二、五名女性、十一次发作、七段记录,三个数字互不相等,官方没有给出映射。
三、发作区间在独立文本表里,心搏标注是自动产出的、未经审核。
四、200 赫兹、单导联、总计十来个小时,整库二十三兆,免注册。
五、它的价值在于可重算,不在于可训练。
编辑说明
本篇所有事实性表述以官方项目页、旧版说明页、该库配套论文摘要与文件服务器上的实际文件为准;页面与文件不一致处两说并列为两口径,不作裁判。时长由头文件采样点除以采样率折算,若官方采样点字段有误则随之偏移。SZ 的全称、记录与患者的对应关系、逐条发作类型、心搏类别词典均为未核实项,本篇不作推测性补全。核验时间为 2026 年 10 月 28 日,核验方式为逐页抓取官方页面与逐文件读取文件服务器上的头文件、清单与发作表。2026 年 10 月 28 日复核时,官方页面访问正常,版本仍为 1.0.0。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- siena-scalp-eeg — 共享标签:生理信号 / 癫痫 / 神经科学
- bonn-eeg — 共享标签:生理信号 / 癫痫 / 神经科学
- brain-wearable-monitoring — 共享标签:生理信号 / 心电信号 / 神经科学
- tuev — 共享标签:生理信号 / 癫痫 / 神经科学
- argo — 共享标签:生理信号 / 心电信号
- icehg-ds — 共享标签:生理信号 / 心电信号
- helsinki-neonatal-eeg — 共享标签:生理信号 / 癫痫 / 神经科学
- wctecgdb — 共享标签:生理信号 / 心电信号
- aami-ec13 — 共享标签:生理信号 / 心电信号
- adfecgdb — 共享标签:生理信号 / 心电信号
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

