信息速览
心脏病学的公开数据里有一条长期的裂缝:心电、心音、脉搏波、胸壁振动这四类信号,各自都有成熟的库,却几乎从不同框出现。做无袖带血压的人拿到脉搏波,却没有同一时刻的心电当锚点,脉搏传导时间的分母无从确定;做心音分类的人拿到录音,却没有同步的脉搏波去算机电延迟,收缩时间间期只能靠估;做运动心率的人拿到加速度,却缺一个可以对照的参考节律。于是凡是需要跨模态对齐的研究,要么只能用自己实验室的小样本去凑,要么只能把不同库的数据拼起来,并假装它们的时间轴可以互信。塞尔维亚温查核科学研究所与贝尔格莱德大学的团队用一台自制的多导记录仪去补这条裂缝,他们把它称作多导心动记录仪。这台设备在同一时刻同步采集心电、心音、双位点双波长的光电容积脉搏波与胸壁单轴加速度,一共十个通道,全部经以太网汇聚到同一台个人电脑。更关键的是采集协议:每位受试者先在站立位静息录三段,再在运动之后反复记录,直到心率回落到只比静息高十到二十跳。这样一来,同一个人的机电耦合关系不是被拍了一张照片,而是沿着心率这条轴被扫了一遍。该资源以 1.0.0 版本于 2024 年 12 月 19 日发布在 PhysioNet 上,按 CC BY 4.0 开放,共 338 段三十秒记录,来自 32 名健康志愿者。它的边界同样清楚:全是健康人,全是三十秒短段,电极摆放为了降噪而不是为了诊断标准。它不是任何疾病队列,也不是长时程监护库。一句话概括,SensSmartTech 同步心血管库给出的是同一颗心脏在同一时刻的十个观察角度,代价是没有病人,也没有时间纵深。
下面这张表是它的一屏速览,十六个维度一次看完。
| 维度 | 内容 |
|---|---|
| 全名 | SensSmartTech database of cardiovascular signals synchronously recorded by an electrocardiograph, phonocardiograph, photoplethysmograph and accelerometer |
| 发布方 | PhysioNet;原始采集由塞尔维亚温查核科学研究所与贝尔格莱德大学电气工程学院、医学院共同完成 |
| 首次发布 | 2024 年 12 月 19 日,版本 1.0.0,官方标注为初次发布 |
| 最近改动 | 无后续修订版本,1.0.0 为唯一版本 |
| 记录数 | 338 段,每段 30 秒 |
| 受试者数 | 32 名健康志愿者,18 名女性、14 名男性,平均年龄 34.0 ± 8.6 岁,平均体质指数 25.1 ± 4.3 kg/m² |
| 通道数 | 10:4 导心电(lead I、lead II、V3、V4)、1 路心音、4 路光电容积脉搏波、1 路胸壁加速度 |
| 原始采样率 | 心电 500 Hz、心音 1 kHz、光电容积脉搏波 100 Hz,均由 16 位模数转换器数字化 |
| 分发格式 | CSV 保留原始采集时间;WFDB 全部重采样到 1 kHz 并共用同一时间轴 |
| 重采样后长度 | 每段 29994 个采样点(1 kHz,约 30 秒) |
| 文件组织 | 每段记录拆成四个文件,后缀分别为 ecg、pcg、ppg、acc,两种格式各一份 |
| 文件总数 | 4060 个:CSV 目录 1352 个、WFDB 目录 2704 个、根目录 4 个 |
| 心率跨度 | 58–173 bpm;集合平均最低值 83 ± 11 bpm,平均最高值 143 ± 14 bpm |
| 标签粒度 | 段级:中位心率与运动前后状态标记,无逐搏注释 |
| 文件格式 | CSV 纯文本、WFDB 头文件 .hea 与信号文件 .dat |
| 许可 | Creative Commons Attribution 4.0 International(CC BY 4.0),开放访问无需注册 |
| 典型用途 | 多传感器心率估算对照、收缩时间间期与脉搏传导时间测算、QT 间期与心率变异性的心率依赖建模、机电耦合动力学 |
§1 它要解决的具体麻烦
1.1 四个传感器各有各的时间观
心血管系统的四类常用无创信号,测的其实不是同一件事。心电记录的是电活动,除极波扫过心肌的那一瞬间它就有反应,时间分辨率高,但对机械收缩什么时候发生几乎无话可说。心音记录的是瓣膜关闭与血流冲击产生的振动,机械事件的起点在这里,但前一个心搏的余振与呼吸音会混进来。光电容积脉搏波记录的是某段血管里血液容积随时间的涨落,它是压力波沿着动脉树传播到某个位置的结果,包含传播时间,却以容积变化而不是压力绝对值呈现。胸壁加速度记录的是心脏跳动传递给胸壁的机械振动,也就是心震图,它的每一次搏动有两个主要峰,分别对应主动脉瓣的开与关。
这四者之间存在固定的时间差,而这些时间差恰恰是临床上最有价值的东西之一。收缩时间间期的定义就是从心电的 QRS 起点到心音主动脉瓣成分之间的间隔,它在心力衰竭的诊断里有几十年的应用历史;脉搏传导时间则是同一个心电锚点到外周脉搏波某个特征点的间隔,是无袖带血压监测里最常被拿来做代理变量的量。两件事都要求信号在同一个时间轴上对齐。
麻烦在于,真实设备上这四个传感器的采样率根本不一致。心电在诊断级设备上是几百赫兹,光电容积脉搏波在低功耗可穿戴芯片上常常只有五十到一百赫兹,加速度又能轻松做到几千赫兹。把它们倒进一个统一的模型,最常见的做法是全部重采样到同一个频率,而重采样本身就已经抹掉了毫秒级的细节。官方页面把这个边界说得很直白:这台设备的精度由各传感器的采样率决定,不同传感器的采样时刻并不相同,只是采集过程被同步,因此不同传感器的时间轴不同,但可以延拓到一个共同的零点。这句话既是承诺,也是警告。
1.2 三条常见的错误期待
第一条,期待它是疾病队列。入组标准明确写着:年满十八岁、无心血管病史或疾病,包括心肌梗死、心力衰竭、狭窄、危险性心律失常与相关处方用药都不接受,只有良性心律失常的志愿者被允许进入。它是一份正常生理的样本,任何拿它训练「识别异常」的思路都会立刻遇到负样本缺失问题。
第二条,期待它有逐搏或节律级标注。它没有任何 PhysioBank 式的注释文件。唯一的逐段标签是人口学表里的中位心率与运动前后状态标记。想做心搏分类的人会发现无米下锅;想做精细时间界标标定的人会发现没有标准答案。
第三条,期待它是躺着的、标准的十二导联。它的心电只有四个通道:两个肢体导联加 V3 与 V4。胸前其余电极(V1、V2、V5、V6)被官方明确说明放在了右上臂,是为了避免垂悬导联引入噪声。所有记录都在站立位完成。这意味着任何依赖标准十二导联形态的知识都无法直接套用。
1.3 它能给到的与给不到的
| 你的需求 | 它给的 | 够不够 |
|---|---|---|
| 多传感器心率估算的横向对照 | 同一时刻心电、心音、脉搏波、加速度四路并行 | 够,这是它设计的核心目的 |
| 收缩时间间期的测算与校正 | 心电 QRS 起点与心音成分在同一时间轴 | 够,且覆盖宽心率范围 |
| 脉搏传导时间与无袖带血压代理变量 | 心电加颈动脉与肱动脉两处、两种波长的脉搏波 | 够,两个传播距离可以互相比较 |
| QT 间期与心率变异性的心率依赖建模 | 每人静息与运动后多次记录,心率被拉开 | 够,但没有 QT 间期的官方标定值,需要自己提取 |
| 心率依赖的生物标志物校正 | 宽心率跨度且每段都有对应的中位心率 | 够,官方明确点名为主要临床价值 |
| 心搏级别的形态分类 | 库内没有对应的相关标注 | 不够,无任何逐搏注释 |
| 心律失常或疾病判别 | 库内没有对应的病理样本 | 不够,全部为健康志愿者 |
| 十二导联形态学任务 | 仅四个通道,且胸前电极改位 | 不够 |
| 长时程昼夜节律分析 | 每段三十秒,段间有间隔 | 不够,无连续覆盖 |
1.4 你的处境与它能帮到的事
| 你的处境 | 它能帮你什么 | 下一步该做什么 |
|---|---|---|
| 你在做光电容积脉搏波的心率估计,想知道心率快速变化时它差多少 | 同一时刻有心电当参考,且覆盖了从静息一路升到接近 173 bpm 的过程 | 用中位心率分层,分别比较各心率档下的估计偏差 |
| 你在做无袖带血压,需要脉搏传导时间的公开验证数据 | 提供两个传播距离(颈动脉、肱动脉)与两个波长,可两两组合 | 先固定特征提取口径,再比较四个组合的一致性 |
| 你在校核某个生物标志物的心率校正公式 | 横跨 58–173 bpm 的宽心率范围,每段都有中位心率 | 以受试者编号做分组,避免同一人的多段跨越两侧 |
| 你在研究运动伪影如何影响可穿戴光电传感器的读数 | 同一位点有两套脉搏波通道,且传感器用无弹性魔术贴固定 | 对比两个波长与两个位点在运动后记录中的差异 |
| 你想把心音与心震图放在一起对齐 | 一路心音与一路胸壁加速度在同一时间轴 | 用 WFDB 版本保证两者共用时间轴,不要拿 CSV 自行对齐 |
| 你在寻找机电耦合的非线性动力学证据 | 同一人多段、心率单调回落的一段序列 | 把同一个人的各段按时序排列,观察随心率变化的系统性漂移 |
1.5 一句话判断
它不是更大的训练集,而是更窄的变量扫描仪:用三十秒的短窗,把心率这个最难缠的混杂变量变成被显式控制的条件。它的价值来自设计,不来自体量。
1.6 不适合谁:四条边界
不适合拿来做疾病判别。 全部受试者无心血管病史。用它训练出来的模型学到的是健康人心血管信号的多样性,不是疾病形态。
不适合拿来训练需要海量样本的深度学习模型。 338 段来自 32 人。三十二这个数字决定了任何按人划分的交叉验证都只有很小的组数。
不适合拿来做标准的十二导联形态研究。 心电只有四个通道,胸前其余电极为了降噪被挪到了右上臂,这与临床标准摆放不是一回事。
不适合拿来做长时程节律统计。 每段三十秒,段与段之间有时间间隔,不构成连续的监护时间流。想要心率变异性的标准时域指标,三十秒窗口在多数文献约定下都偏短。
§2 数据构成与规格
2.1 一条记录是四个文件,不是一个文件
多数波形库的逻辑是一条记录对应一个文件,多通道并列在同一个矩阵里。这里的逻辑不同:一条完整的多导记录被拆成四个同名的文件,后缀分别是 _ecg、_pcg、_ppg、_acc。命名规则是「受试者编号_起始时刻_模态」,起始时刻写成 hh-mm-ss 的形式,例如 1_10-09-54_ecg。这意味着文件名里的下划线承担了分隔符的角色,而起始时刻本身用的是短横线。
之所以要拆开,直接原因在于采样率不一致。心电五百赫兹、心音一千赫兹、光电容积脉搏波一百赫兹,三者塞进同一个二维表,只能在时间列上做近似,或者填写大量空白。拆开之后,每个文件维持自己的采样节奏,CSV 版本甚至保留了每个采样点的真实采集时刻。
代价是多了一道拼接工序。如果你的模型要求十通道输入,你必须先读四个文件,再在时间轴上把它们合起来。WFDB 版本替你做掉了这件事,代价是重采样带来的信息损失(§2.5)。
2.2 通道字典:十个通道各自的物理含义
| 通道 | 所在文件 | 官方通道名 | 物理含义 | 采集位置 |
|---|---|---|---|---|
| lead I | _ecg |
I | 左上肢与右上肢之间的电位差 | 肢体电极导出 |
| lead II | _ecg |
II | 左下肢与右上肢之间的电位差,节律判读最常用 | 肢体电极导出 |
| V3 | _ecg |
V3 | 胸前导联 | 胸前电极 |
| V4 | _ecg |
V4 | 胸前导联 | 胸前电极 |
| pcg | _pcg |
pcg | 心音,瓣膜关闭与血流冲击产生的振动 | 听诊器置于胸骨、V3 电极右侧,弹性带固定 |
| carotid_880nm | _ppg |
carotid_880nm | 颈动脉脉搏波,长波长光束 | 颈部左侧颈动脉,无弹性魔术贴固定 |
| carotid_660nm | _ppg |
carotid_660nm | 颈动脉脉搏波,短波长光束 | 颈部左侧颈动脉,同一个探头双波长 |
| brachial_880nm | _ppg |
brachial_880nm | 肱动脉脉搏波,长波长光束 | 左上臂,无弹性魔术贴固定 |
| brachial_660nm | _ppg |
brachial_660nm | 肱动脉脉搏波,短波长光束 | 左上臂,同一个探头双波长 |
| az | _acc |
az | 胸壁加速度单轴分量 | 贴于 V3 与 V4 之间的自粘电极上 |
十个通道的物理单位各不相同,这一点在读 WFDB 头文件时能一次看清:心电与心音的增益单位都是毫伏,光电容积脉搏波的单位是任意单位,加速度的单位是重力加速度。把十列数直接拼成一个矩阵喂给网络而不做归一化,等于把量纲混乱直接送进第一层权重。
2.3 完整字段字典
本库的字段分布在三处:人口学表的列、WFDB 头文件的关键字行、CSV 文件的表头。下表把它们逐条列出。
| 信息项 | 所在位置 | 取值形态 | 含义 | 使用注意 |
|---|---|---|---|---|
| File number | 人口学表第 1 列 | 从 1 起的整数 | 表自身的行编号 | 与文件名编号不一定对齐,不要混用 |
| Subject number | 人口学表第 2 列 | 1–32 | 受试者编号 | 划分数据集时的分组键 |
| Recording time | 人口学表第 3 列 | hh:mm:ss | 记录起始时刻 | 与文件名中的 hh-mm-ss 对应 |
| Gender | 人口学表第 4 列 | M / F | 性别 | 官方说明女性十八人、男性十四人 |
| Age | 人口学表第 5 列 | 年份整数 | 受试者年龄 | 同一人的多行取同一个值 |
| Height | 人口学表第 6 列 | 厘米 | 身高 | 无特殊注意 |
| Weight | 人口学表第 7 列 | 千克 | 体重 | 无特殊注意 |
| Body-mass index | 人口学表第 8 列 | 两位小数 | 体质指数 | 无特殊注意 |
| ECG / PPG / PCG / ACC 四列 | 人口学表第 9–12 列 | 文件名字符串 | 四个模态各自对应的文件名 | 拼接记录时靠这四列做主键 |
| Before / After activity | 人口学表第 13 列 | B / A | 运动前或运动后 | B 与 A 的对比是本库的核心设计 |
| Median heart rate | 人口学表第 14 列 | 一位小数 | 中位心率(bpm) | 官方定义为记录内 RR 间期中位数的倒数 |
| 记录名 | .hea 第 1 行第 1 字段 |
如 1_10-09-54_ecg |
记录标识 | 与 .dat 文件名前缀一致 |
| 信号条数 | .hea 第 1 行第 2 字段 |
4 或 1 | 该文件内的通道数 | ecg 与 ppg 为 4,pcg 与 acc 为 1 |
| 采样率 | .hea 第 1 行第 3 字段 |
1000 | 重采样后的统一采样率 | 不是原始采样率 |
| 采样点数 | .hea 第 1 行第 4 字段 |
29994 | 该文件长度 | 除以 1000 得约 30 秒 |
| 格式码 | .hea 信号行第 2 字段 |
32 | WFDB 存储格式码 | 由读写工具处理,使用者通常不必关心 |
| 增益 | .hea 信号行第 3 字段 |
如 6990.5(0)/mV |
每物理单位对应的整数值 | 心电 6990.5、心音 36.4、脉搏波 100.0、加速度 327.68 |
| 位分辨率 | .hea 信号行第 4 字段 |
32 | 模数转换位数 | 与格式码一致 |
| ADC 零值 | .hea 信号行第 5 字段 |
0 | 零电平对应的整数值 | 换算时先减这个值 |
| 初始值 | .hea 信号行第 6 字段 |
如 19148 | 首采样点整数值 | 无特殊注意 |
| 校验和 | .hea 信号行第 7 字段 |
如 33394 | 采样点累加和 | 用于校验 .dat 是否完整 |
| 通道名 | .hea 信号行第 9 字段 |
如 I、pcg、az |
通道标识 | 顺序与 .dat 内的列顺序一致 |
| t | CSV 第 1 列 | 毫秒浮点 | 该采样点的真实采集时刻 | 单位是毫秒,不是采样序号 |
| 各通道列 | CSV 第 2 列起 | 浮点 | 原始采样值 | CSV 不含增益信息,物理换算要回查 .hea |
2.4 一条记录的完整解剖
以受试者 1 的 1_10-09-54 为例。它的 WFDB 心电头文件只有五行:
1_10-09-54_ecg 4 1000 29994
1_10-09-54_ecg.dat 32 6990.5(0)/mV 32 0 19148 33394 0 I
1_10-09-54_ecg.dat 32 6990.5(0)/mV 32 0 -37925 4022 0 II
1_10-09-54_ecg.dat 32 6990.5(0)/mV 32 0 -28304 21859 0 V3
1_10-09-54_ecg.dat 32 6990.5(0)/mV 32 0 -36116 32743 0 V4
第一行是记录行:记录名、四条信号、采样率一千赫兹、长度二九九九四个点。从右往左读信号行:最后一列 I 是通道名;倒数第二列 0 是块大小;33394 是校验和;19148 是初始值;0 是 ADC 零值;32 是位分辨率;6990.5(0)/mV 是增益,括号里的零是基线值;32 是格式码;首字段则是文件名。四个通道共用同一个 .dat 文件,这一点与其他波形库的惯例一致。
心音、脉搏波、加速度三个文件的结构相同,只是通道数与增益不同:
1_10-09-54_pcg 1 1000 29994
1_10-09-54_pcg.dat 32 36.4(0)/mV 32 0 4 45988 0 pcg
1_10-09-54_ppg 4 1000 29994
1_10-09-54_ppg.dat 32 100.0(0)/au 32 0 98 1233 0 carotid_880nm
1_10-09-54_ppg.dat 32 100.0(0)/au 32 0 152 61054 0 carotid_660nm
1_10-09-54_ppg.dat 32 100.0(0)/au 32 0 -30 906 0 brachial_880nm
1_10-09-54_ppg.dat 32 100.0(0)/au 32 0 6 58551 0 brachial_660nm
1_10-09-54_acc 1 1000 29994
1_10-09-54_acc.dat 32 327.68(0)/g 32 0 1765 55732 0 az
脉搏波通道名里出现的八百八十纳米是一个值得当场记住的细节,因为官方正文里写的两色波长是一个短波与八百纳米,文件里写的却是八百八十纳米。这个问题在 §2.4、§5.6 与 §10 各说明一次。
CSV 版本的结构要朴素得多。CSV/1_10-09-54_ppg.csv 的表头是 t,carotid_880nm,carotid_660nm,brachial_880nm,brachial_660nm,第一列 t 是采集时刻(毫秒),后面四列是原始采样值。直接读这几行就明白了:
t,carotid_880nm,carotid_660nm,brachial_880nm,brachial_660nm
3.7,97.73,152.37,-30.06,6.4949
13.6,97.73,152.37,-32.06,6.4949
23.5,94.73,151.37,-33.06,5.4949
时间列从 3.7 毫秒开始,相邻两步大约相差 9.9 毫秒,与官方给出的一百赫兹一致。心电文件的相邻步长约 2 毫秒,与官方给出的五百赫兹一致;心音文件相邻步长约 1 毫秒,与官方给出的一千赫兹一致。加速度文件的步长同样约 2 毫秒,但官方页面没有给出加速度的采样率,这一项是依据文件观察而非官方声明,使用前请自行确认。
2.5 两种格式怎么选:CSV 与 WFDB
| 维度 | CSV | WFDB |
|---|---|---|
| 采样率 | 各传感器原始采样率(心电 500 Hz、心音 1 kHz、脉搏波 100 Hz) | 全部重采样到 1 kHz |
| 时间轴 | 每模态独立,靠首列的真实采集时刻对齐 | 四个文件共用同一条时间轴 |
| 预处理 | 原始信号,但已做官方说明的滤波与去均值 | 含有同样的滤波,且经过重采样 |
| 物理单位 | 无单位信息,换算需回查 WFDB 头文件 | 头文件带增益与单位 |
| 读取成本 | 通用表格库即可 | 需要 wfdb 工具链 |
| 适合场景 | 关心毫秒级时间差、想自己决定对齐方式 | 想直接拼成十通道矩阵、做机器学习的输入 |
| 官方态度 | 明确说是原始信号 | 明确说是重采样后的版本 |
这张表的选择依据是明确的:如果你要算的是毫秒级的量,比如收缩时间间期的绝对值,用 CSV;如果你要做的是跨模态特征融合的训练,用 WFDB。把 WFDB 当成无损版本是最常见的错误,它恰恰是有损的那一版。
2.6 与同类多模态库的通道差异
| 资源 | 通道组合 | 是否同步 | 是否覆盖运动 | 是否含疾病队列 |
|---|---|---|---|---|
| 本库 | 心电 4 + 心音 1 + 脉搏波 4 + 加速度 1 | 是 | 是,含运动后恢复期 | 否,全健康志愿者 |
| PTT-PPG 多传感器库 | 心电 + 多指端脉搏波 + 其他传感器 | 是 | 视具体设计而定 | 否 |
| 五设备同步生理库 | 多台商用设备并行 | 是 | 部分 | 否 |
| 智能手表心电库 | 手表单导心电 + 参考机 | 是 | 否 | 否 |
| OpenOximetry 脉搏血氧库 | 脉搏血氧 + 参考血气 | 是 | 否 | 是,含患者 |
| 通气研究心肺联合库 | 心电 + 呼吸力学 | 是 | 否 | 否 |
本库在其中的位置很特殊:它是唯一把健康人放在统一千赫兹时间轴上,并且把心率作为被扫过的自变量、而不是被控制住的常量的那一个。这个位置决定了评价它的标准不是数据量,而是设计密度。
§3 它是谁的数据
3.1 贡献者与机构
十位作者分属塞尔维亚的三个机构,这一点对判断数据的工程属性很重要:它不是临床科室顺手留存的病例资料,而是一个由核科学研究所牵头的传感器工程项目产出。
| 作者 | 机构 | 可从页面推断的角色 |
|---|---|---|
| Aleksandar Lazović | 温查核科学研究所,贝尔格莱德大学 | 第一作者,关联数据论文的牵头人 |
| Predrag Tadić | 贝尔格莱德大学电气工程学院 | 信号采集与处理 |
| Natalija Đorđević | 贝尔格莱德大学电气工程学院 | 信号采集与处理 |
| Vladimir Atanasoski | 温查核科学研究所 | 硬件与同步 |
| Maša Tiosavljević | 贝尔格莱德大学电气工程学院 | 采集与试验执行 |
| Marija D. Ivanović | 温查核科学研究所 | 数据处理 |
| Ljupčo Hadžievski | 温查核科学研究所 | 项目层面的参与 |
| Arsen Ristić | 贝尔格莱德大学医学院 | 临床口径把关 |
| Vladan Vukčević | 贝尔格莱德大学医学院 | 临床口径把关 |
| Jovana Petrović | 温查核科学研究所 | 官方指定的答疑联系人 |
医学背景的作者参与,解释了为什么入组标准写的是「无心肌梗死、心力衰竭、狭窄、危险性心律失常」,而不是笼统的「健康受试者」。这个写法有临床含义,同时也给它划定了适用边界。
3.2 时间线
| 时间 | 事件 | 出处 |
|---|---|---|
| 2022 年 | 伦理批件编号 116-18-2/2022-000 签发 | 官方页面的伦理一节 |
| 2024 年 4 月 24 日 | 人口学表的文件时间戳 | 官方文件目录表 |
| 2024 年 10 月 22 日 | README.txt 的时间戳 | 官方文件目录表 |
| 2024 年 10 月 24 日 | RECORDS 的时间戳 | 官方文件目录表 |
| 2024 年 12 月 10 日 | LICENSE.txt 的时间戳 | 官方文件目录表 |
| 2024 年 12 月 19 日 | 版本 1.0.0 正式发布,校验和清单同日生成 | 官方页面发布信息与文件目录表 |
截至核验时间,1.0.0 是唯一版本,官方发布说明只有一行「初始发布」。这意味着版本号本身不构成使用风险,但也意味着没有任何后续的勘误记录可以查。
3.3 采集场景:站立位、静息与运动后恢复
协议写得很具体,值得逐句拆开。受试者站在地上;每位先在静息状态下录三段三十秒;录完之后研究者当场计算心率;运动之后再重复记录,直到心率回落到只比静息心率高十到二十跳。这三句话里藏着三层设计意图。
第一层是控制体位。全部记录都在站立位完成,避免了卧立转换带来的血流动力学重分布,但也意味着数据里没有体位这一变量。第二层是控制参考点。静息心率是由研究者当场算出的,而不是从某个设备屏幕读到的,因此它带有明显的人工成分。第三层是控制扫描范围。运动之后的重复记录,让同一个人在心率缓慢回落的过程中被多次采样,这才让心率依赖这个命题可以被真正检验。
设备侧的细节同样具体。心音用放入麦克风的心血管专用听诊器采集,采样率一千赫兹,听诊头置于胸骨、V3 电极的右侧,用弹性带固定。心电采集用 ADS1298 芯片,采样率设到 500 Hz,四个肢体电极加 V3 与 V4;V1、V2、V5、V6 这四片冗余的胸前电极被放在右上臂,官方明确说是为了消除垂悬导联的噪声。脉搏波传感器用 MAX86150EFF+T 芯片,配置了一个双波长血氧结构,两个探头分别用无弹性魔术贴固定在左颈动脉与左上臂肱动脉上,采样率一百赫兹。加速度计用 MPU6050,量程设为正负 1 g,贴在 V3 与 V4 之间,只取垂直胸壁的那个轴。所有传感器输出信号由十六位模数转换器数字化,整机经以太网把数据传输到个人电脑。
3.4 数据来源的三个层次
第一个层次是原始硬件层,也就是四个传感器各自的采样值。CSV 目录里的东西最接近这一层,但它已经过滤波处理,所以严格说是第一次经过处理的硬件层。
第二个层次是重采样层,也就是 WFDB 目录。四个模态被强制拉到同一条一千赫兹的时间轴上,物理含义没有变,时域分辨率发生了变化。
第三个层次是表格层,也就是人口学表。它把年龄、性别、身高、体重、体质指数、运动前后状态、中位心率与四个模态的文件名汇成一行。绝大多数使用者真正接触的其实是这一层,因为它是唯一可以直接用表格库读进来做筛选的东西。
层次递进的代价是信息逐步被固化。想越过第三层回到第一层,只能用文件名做反查;想越过第二层回到真实的采样时刻,必须回到 CSV。这条路是通的,但要自己走。
§4 它最独特的东西
4.1 稀缺的不是数据量,是心率扫描
多模态同步这件事,近几年已经不算稀奇。真正稀奇的是同一个人在宽心率区间内被重复采样。多数公开的多模态库给的是每个受试者一段,或者每个受试者几种状态,本库给的是每个受试者一条心率轨迹。这条轨迹让心率从一个需要被消除的干扰变量,变成了一个可以被系统地扫过的自变量。
官方把这个价值讲得很直接:宽心率范围内的多个心率回落期记录,使得研究心血管动力学并洞察相应的心肺耦合与机电耦合成为可能;特别具有临床意义的是,它提供了推导多参数生物标志物心率校正系数的机会。这段话值得被单独拿出来读——它想解决的不是某个模型准不准,而是所有随心率变化的生物标志物,它们的基准值该怎么校正。
举例说,QT 间期本身随心率变化,绝大多数校正公式都是在特定人群里拟合出来的。想检验或重新拟合一个校正公式,需要同一个人在多个心率档下的数据。用人群之间的差异去拟合心率的影响,是把两个完全不同的变异源混为一谈;用同一个人的心率变化去拟合,才是干净的。本库提供的正是后者。
4.2 每一段三十秒窗口背后都有一个标定值
三十秒听起来很短,但这里的每一段都配了一个官方给出的中位心率,定义为该段内 RR 间期中位数的倒数。也就是说,338 段记录不仅仅是 338 份波形,而是 338 个带条件的采样点,条件是「在这个心率下,这十通道波形长这样」。
这个结构的用法很直接:把 338 段按中位心率排序或者分箱,就能观察某个特征值如何随心率变化。难点在于这些点并不独立——同一位受试者贡献了多段,这些段共享同一颗心脏、同一套传感器、同一种呼吸方式。把它们当成独立样本去做线性回归,标准误会收缩到不可信的程度。正确做法是把受试者编号作为分组变量。
4.3 案例:同一次心搏在四个模态上的时间差
设想一个具体的用法。取一条记录,从心电里找出 QRS 波的起点,从心音里找出主动脉瓣关闭相关的成分峰值,从颈动脉脉搏波里找出波足,从加速度里找出收缩期的主峰。四者在时间轴上依次出现,互相之间的间隔就是几个不同的生理学量。
心电 QRS 起点到心音的相关成分之间,间隔大致对应电机械延迟加等容收缩时间,这就是收缩时间间期家族的一部分。心电 QRS 起点到颈动脉脉搏波波足之间,包含心脏射血前的准备时间与压力波传播到颈动脉的时间。同一个 QRS 起点到肱动脉脉搏波之间,因为传播距离更远,时间自然更长,两者的差就是一段动脉树上的传导时间。三种度量拿到同一套数据上同时算,可以在不变换设备、不变换人群的条件下互相校核——这正是单模态数据集做不到的事情。
需要注意,上面这些特征点本库都没有标注。所有的界标识别都要使用者自己做,并且不同论文对同一特征点的定义可能不同。这一点极大地影响了结果的可比性,也是写论文时必须交代清楚的东西。
4.4 标注的粒度:段级心率,没有逐搏注释
官方给的最细标签是每段一个中位心率值加一个运动前后标记。没有逐搏位置,没有心搏类型,没有节律注释,没有 QT 间期的测量值,没有同步血压,没有独立的呼吸通道(虽然脉搏波的基线漂移里含呼吸信息,官方也明确提到了这一点)。
这决定了它的适用任务形态:它适合抽取型研究——你自己从波形里抽特征,然后拿中位心率当条件变量;它不适合流水线式的监督学习——没有现成标签可喂。
一个经常被忽略的推论是:既然没有同步血压,那么想用它做无袖带血压的监督训练是不成立的。它可以做的是验证脉搏传导时间与血压的关系这一类研究,前提是你别指望从这套数据里拿到血压真值。
4.5 边界条件:什么情况下它不再适用
心率超出 58–173 bpm 区间的情形不适用。这是官方给出的边界,超过了这个范围的行为是外推,不是插值。
平均三十四岁这个年龄带之外的群体不适用。全部受试者年满十八岁,没有未成年人,也没有老年人。老年人群里常见的动脉硬化会显著改变脉搏波形态与传播速度,本库盖不到。
需要长时间连续记录的场景不适用。每段三十秒、段间有间隔,不构成连续监护流。
需要病理对照的场景不适用。健康人库的天花板就在这里:它告诉你正常长什么样,这与异常长什么样是互补而非替代的关系。
§5 怎么拿到
5.1 目录结构与下载面
根目录只有四个条目:人口学表(49.2 KB)、LICENSE.txt(14.5 KB)、README.txt(1.7 KB)、RECORDS(27.3 KB)。两个数据目录分别是 CSV 与 WFDB。
| 目录或文件 | 内容 | 条目数 |
|---|---|---|
CSV/ |
338 段 × 四个模态的原始采样 CSV | 1352 |
WFDB/ |
338 段 × 四个模态的头文件与信号文件 | 2704 |
Demographics.csv |
人口学表,含各模态文件名、运动前后标记、中位心率 | 1 |
RECORDS |
wfdb 工具识别的记录清单,列出 WFDB 目录下的一千三百五十二条记录名 | 1 |
README.txt |
摘要、用法说明、版本、许可、联系人邮箱 | 1 |
LICENSE.txt |
CC BY 4.0 全文 | 1 |
SHA256SUMS.txt |
四千零六十个文件的校验和清单 | 1 |
整库未压缩体积 775.0 MB,官方提供的压缩包 264.9 MB。
5.2 批量下载
官方给了若干条路径,任选其一。需要注意的是,这个库不需要注册也不需要签署数据使用协议,因此匿名命令行路径都可用。
wget -r -N -c -np https://physionet.org/files/senssmarttech/1.0.0/
aws s3 sync --no-sign-request s3://physionet-open/senssmarttech/1.0.0/ DESTINATION
python3.11 -m pip install physionet
physionet download senssmarttech --version 1.0.0
前两条是直连方式,第三条走官方客户端,第四条是页面上提供的压缩包直链。校验用官方提供的核对表 SHA256SUMS.txt。它的行数是四千零六十,正好等于两个数据目录的文件总数加根目录四个文件,因此可以用行数快速确认下载是否完整。
5.3 用 wfdb 直接流式读取
WFDB 版本支持远程直读,不必先下完整库。
import wfdb
#-- 四个模态共用同一条 1 kHz 时间轴,逐模态读取
base = '1_10-09-54'
for mod in ['ecg', 'pcg', 'ppg', 'acc']:
rec = wfdb.rdrecord(f'{base}_{mod}', pn_dir='senssmarttech/1.0.0/WFDB')
print(mod, rec.fs, rec.sig_len, rec.sig_name, rec.units)
import numpy as np
#-- 把四个模态拼成一条十通道矩阵,按最短长度截断
parts, names, units = [], [], []
for mod in ['ecg', 'pcg', 'ppg', 'acc']:
rec = wfdb.rdrecord(f'1_10-09-54_{mod}', pn_dir='senssmarttech/1.0.0/WFDB')
parts.append(rec.p_signal)
names += rec.sig_name
units += rec.units
n = min(p.shape[0] for p in parts)
X = np.concatenate([p[:n] for p in parts], axis=1)
print(X.shape, names, units)
第二段代码的输出应当是一个接近三万乘十的矩阵、一个长度十的名称列表与同样长度的单位列表。这里之所以要取最短长度,是因为不同模态虽然在名义上写定了同样的采样点数,实际处理前仍应先各自对齐再合并。
5.4 转成通用的表结构
人口学表是整个库的中心索引,把它读进来再按行取文件名,是最省力的组织方式。
import pandas as pd
dem = pd.read_csv('https://physionet.org/files/senssmarttech/1.0.0/Demographics.csv')
dem = dem.loc[:, ~dem.columns.str.startswith('Unnamed')]
print(dem.shape, list(dem.columns))
#-- 每行给出四个模态的文件名,按行即可定位一条完整记录
row = dem.iloc[0]
print(row['Subject number'], row['Recording time (hh:mm:ss)'],
row['Before (B) / after (A) activity'], row['Median heart rate (bpm)'])
注意两处易错点。列名 Before (B) / after (A) activity 在 B 后面是两个空格,抄写时容易写成单个空格。表尾还有大量空列,官方在数据表后补了许多逗号,读进来会产生列名以 Unnamed 开头的空列,必须手动剔除。
下表给出转换前后的对应关系,便于在不打开原文件的情况下复原结构。
| 转换目标 | 来源 | 处理方式 |
|---|---|---|
| 主表 | 人口学表 | 剔除空列,保留十四列 |
| 分组键 | Subject number | 分组交叉验证的分组参数 |
| 条件变量 | Median heart rate (bpm) | 连续值或按区间离散 |
| 状态标签 | Before / After activity | B 与 A 二类 |
| 波形定位 | ECG / PPG / PCG / ACC 四列 | 拼出四个文件名 |
5.5 CSV 版本的时间对齐
如果要用 CSV 保留的真实采集时刻,对齐工序要自己做。核心思路是把每条时间轴减去各自的首值,再插值到公共栅格。
import numpy as np
import pandas as pd
#-- 读四个 CSV,各自减去起始时刻,再插值到公共栅格
def load(path):
df = pd.read_csv(path)
t = df['t'].to_numpy()
return t - t[0], df.drop(columns=['t']).to_numpy(), list(df.columns[1:])
grid = np.arange(0, 29994) #-- 与 WFDB 一致的公共时间栅格(毫秒)
out = {}
for mod in ['ecg', 'pcg', 'ppg', 'acc']:
t, y, cols = load(f'CSV/1_10-09-54_{mod}.csv')
v = np.stack([np.interp(grid, t, y[:, i]) for i in range(y.shape[1])], axis=1)
out[mod] = v
print(mod, y.shape, '->', v.shape)
这段代码把每个模态在自己的时间栅格上插值,代价是完全放弃了原始时刻信息的精度优势。如果你关心的是毫秒级的绝对间隔,那就不要用它,直接用原始时间戳做减法。
5.6 五个最容易出错的地方
第一,把 WFDB 当成无损版本。它明确是重采样到 1 kHz 的产物,原始采样率只有心电 500 Hz、脉搏波 100 Hz。用它算出来的毫秒差里,有一部分是插值造成的位移,而不是真实生理。
第二,忽略受试者编号造成的泄漏。同一个人的多段记录共享同一套电极、同一个胸壁形态与同一种呼吸习惯。按记录随机划分会把同一个人的样本放进训练与测试两侧,指标会虚高。
第三,把四种物理单位混为一谈。心电与心音是毫伏,脉搏波是任意单位,加速度是重力加速度。十通道直接拼矩阵而不归一化,等于把量纲混乱送进模型第一层。
第四,照着官方正文去写波长。正文说的是短波与八百纳米的组合,文件里写的是八百八十纳米与短波的组合。以列名为准,并在论文里注明你依据的是哪一种说法。
第五,指望它能拿来训练疾病判别模型。三十二位受试者全部为无心血管病史的健康志愿者,没有任何病理样本可供监督学习。
§6 与库内条目的关系
6.1 关系图谱
本库在站内 AI-Ready 数据集百科里的近邻,主要集中在三类:同为多模态同步采集的资源、以光电容积脉搏波为核心的资源、以及以可穿戴设备对照评测为目的的资源。
| 相邻资源 | 与本库的关系 | 该看哪一个取决于 |
|---|---|---|
| PTT-PPG 多传感器库 | 同样以脉搏波传导时间为目标,是最直接的对照对象 | 你要的是多个指端的传感位点,还是宽心率范围内的重复采样 |
| 五设备同步生理库 | 多台商用设备并行的同步方案对照 | 关心自研设备的精度,还是商用设备之间的一致性 |
| 智能手表心电库 | 可穿戴设备与参考机的对照评测 | 关心成品设备的测量质量 |
| OpenOximetry 脉搏血氧库 | 光学测量与侵入式参考值的对照 | 需要真实的血气参考值 |
| 通气研究心肺联合库 | 心与肺同时记录的多模态资源 | 关心呼吸与心血管的耦合 |
| fNIRS 与 EEG 运动伪差对照库 | 另一类运动伪影对照资源 | 关心运动伪影而非机电耦合 |
| NSTDB 噪声压力测试库 | 用于给本库的信号叠加受控噪声 | 想做噪声鲁棒性实验 |
| MIT-BIH P 波标注库 | 提供逐搏标注的心电资源 | 需要心电侧的逐搏参考 |
6.2 检索路径
从三个方向可以找到它。按模态检,走「多模态时序」加「可穿戴设备」两个标签。按器官系统检,走「心血管监测」加「生理信号」。按用途检,走「无袖带血压」或「机电耦合」这类关键词。
反向检索同样重要:如果你已经在看 PTT-PPG 多传感器库,那么本库是它的自然下一步——前者给出更多的传感位点,后者给出更宽的心率范围。如果你在看各种同步测量资源,本库则是自研设备这一类里的样本,与商用设备拼装那一类互为对照。两者之间的差别不在数据质量,而在你想验证的东西是物理极限还是产品表现。
6.3 与其他库的分工判据
| 你要做的事 | 用它 | 用别的 |
|---|---|---|
| 心率依赖现象建模 | 是,这是它的设计目的 | 否 |
| 逐搏心电形态分类 | 否,无注释 | P 波标注库、心律失常类长程库 |
| 商用可穿戴设备评测 | 否,自研设备 | 智能手表心电库 |
| 血氧准确度验证 | 否,无参考血气 | OpenOximetry 脉搏血氧库 |
| 长时程昼夜监测 | 否,三十秒短段 | 心律失常类长程库 |
| 多模态时间对齐研究 | 是,十通道同步 | 五设备同步生理库 |
§7 质量评估与局限性
7.0 阅读本节前的一个前置校正
评价这个库时最容易犯的错误,是用数据量这把尺子去量它。按这个标准它是小的:三十二人、三百三十八段、三十秒一段,总时长不到三小时。但它的设计目标从来不是规模。它的设计目标是在心率这个维度上做受控扫描,这个目标三十二人就够了,甚至三十二人比三百二十人更合适——因为后者很难做到让每个人都沿着心率被系统地扫一遍。因此本节评价的是设计与执行,不是体量。
7.1 五维评分
| 维度 | 评价 | 依据 |
|---|---|---|
| 设计密度 | 高 | 每模态参数、采集协议、入组标准、预处理全部写明 |
| 采集一致性 | 高 | 单一设备、单一团队、单一地点 |
| 文档完整度 | 高 | 页面含摘要、背景、方法、数据描述、用法、伦理、致谢 |
| 人群多样性 | 低 | 三十二人,单一国家,单一年龄带 |
| 标签可用性 | 低 | 仅段级中位心率与运动前后标记,无逐搏注释 |
7.2 标注质量的两层
第一层是官方给出的中位心率。它的定义披露得很干净:记录内 RR 间期中位数的倒数。这是个可复现的定义,不依赖任何黑盒算法,这一点值得肯定。它的问题在于它是个集中趋势量——在心率正在快速变化的运动后记录里,中位值会把段内的变化抹平。用它当条件变量时,要意识到它代表不了整段。
第二层是运动前后标记。B 与 A 的划分来自协议本身,不依赖任何人工判断,因此这一层的可靠性很高。
除此之外没有其他标注。所有更细的标签——QRS 起点、心音成分、脉搏波波足、波形质量好坏——都要使用者自己产生,结果的可重复性完全取决于你怎么描述这个产生过程。
7.3 已知的、可枚举的偏差
| 偏差来源 | 表现 | 可以怎么处理 |
|---|---|---|
| 年龄带窄 | 平均 34.0 ± 8.6 岁,无老年人 | 不要把结论外推到老年人群 |
| 性别构成 | 女性十八人、男性十四人 | 分组分析时样本量偏小 |
| 单一中心 | 全部来自塞尔维亚一处采集点 | 只能做跨库而非跨中心的验证 |
| 健康人筛选 | 排除心血管疾病与相关用药 | 无法建立病理对照 |
| 站立位 | 全部信号在站立位采集 | 与其他体位的数据不可直接比较 |
| 短窗 | 每段三十秒 | 不适用于需要长程稳定性的统计量 |
| 电极改位 | 胸前冗余电极挪到右上臂 | 不可套用标准十二导联判读规则 |
| 缺乏无创血压 | 无同步血压真值 | 无袖带血压只能做到相关性研究 |
7.4 外部验证矩阵
| 验证方式 | 可行性 | 说明 |
|---|---|---|
| 与 NSTDB 噪声库叠加做鲁棒性 | 可行 | 本库信号干净且保留基线漂移,适合做受控加噪 |
| 与智能手表心电库的器具对照 | 部分可行 | 本库是自研设备,两者口径不同 |
| 与 PTT-PPG 库的算法对照 | 可行 | 同一套特征提取算法可以在两套数据上分别跑 |
| 与血氧库的真值对照 | 不可行 | 本库无参考血气值 |
| 与长程心律失常库的对照 | 不可行 | 时间跨度与人群均不匹配 |
7.5 它为何能持续
发布至今被引不多,官方页面显示只有三篇文献引用。这个数字不必被看作负面信号。一个二〇二四年末发布、粒度特殊、标签稀薄的资源,在短时间尺度里被少量人深度使用,是正常形态。真正决定它生命力的是那件事:没有任何其他公开库能在同一时刻给你心电图、心音、两个位点的双波长脉搏波与胸壁加速度,并且把心率系统地扫过一遍。只要多参数生物标志物的心率校正还是个未决问题,这个组合就不会失去价值。
§8 生态位与历史
8.1 历史沿革
二〇二二年伦理批件签发,二〇二四年底完成发布,中间是采集、整理与去标识化的工作区段。官方明确记录了去标识化措施:所有日期从记录中被移除,发布的数据不包含任何可识别或提供合理识别依据的个人信息,并声明符合健康保险携带与责任法案关于个人健康信息共享的要求。文件名中保留的所谓起始时刻是当天内的钟点,不是日历日期,这也是去标识化处理的一部分。
资金支持来自两条渠道:塞尔维亚共和国科学基金的一个多传感器与人工智能服务心力衰竭诊断项目,以及科学与教育部的两项机构资助。这种一个具体项目加两项机构经费的结构,说明它是计划内的产出,而不是顺手留存的材料。
8.2 与挑战赛的关系
它与任何 PhysioNet 挑战赛都没有隶属关系,官方页面既未出现在任何挑战赛的数据来源清单里,也没有挑战赛反向引用它。它是一个独立的资源型贡献,而不是某个赛事的副产品。这带来一个直接后果:没有官方定义的训练与测试划分,也没有排行榜可以参考。任何使用它发表的指标,都是私有划分下的结果,跨论文比较必须回到那个问题——对方用的是什么划分。
8.3 生态位:一把游标卡尺而不是一片平原
在整个生态里,它占的位置是对照尺。大规模的心电图库是主力粮仓,负责把模型喂饱;商用设备的评测库负责告诉工程界这款设备行不行;噪声库负责给算法做压力测试。本库负责的是一件更窄的事:在一组生理学意义上的健康人身上,把心率这个变量从混杂因素变成自变量,并且在同一个时刻给出四个视角的观察。它不解决规模问题,它解决的是这个效应能不能被干净地拆出来。
8.4 谁在用它,用来做什么
官方页面给出的被引清单里,有一篇正是同一团队发表在《Scientific Data》上的数据论文,标题把这几路信号并列写进了题目——这通常意味着作者希望把这个资源确立为标准引用对象。另外两篇分别来自不同的信号处理方向,一篇把它作为算法验证的数据来源,一篇是在做含心音与心震图的力描记数据集时把它作为相关资源援引。三篇文献的分布说明它被当成背景资源而不是训练集使用,这与其设计定位是吻合的。
§9 使用指引
9.1 三种角色的路径
| 角色 | 最短路径 | 要避开的坑 |
|---|---|---|
| 可穿戴算法工程师 | 用 WFDB 拼十通道矩阵,以中位心率分层,比较各传感器的心率估计误差 | 别把 WFDB 当原始采样率 |
| 生理信号研究者 | 用 CSV 保留毫秒时间戳,自己定义特征点,算收缩时间间期与脉搏传导时间 | 别把同一人的多段当独立样本 |
| 生物标志物方法学家 | 按受试者编号分组,把中位心率当自变量拟合校正关系 | 别用人群间差异代替个体内心率变化 |
9.2 一条最短的可用流程
import numpy as np
import pandas as pd
import wfdb
ROOT = 'https://physionet.org/files/senssmarttech/1.0.0'
#-- 1. 读人口学表,剔掉表尾的空列
dem = pd.read_csv(f'{ROOT}/Demographics.csv')
dem = dem.loc[:, ~dem.columns.str.startswith('Unnamed')]
#-- 2. 取一条记录,拼出十通道矩阵
def ten_channels(row):
parts = []
for k in ['ECG', 'PCG', 'PPG', 'ACC']:
rec = wfdb.rdrecord(row[k], pn_dir='senssmarttech/1.0.0/WFDB')
parts.append(rec.p_signal)
n = min(p.shape[0] for p in parts)
return np.concatenate([p[:n] for p in parts], axis=1)
X = ten_channels(dem.iloc[0])
print(X.shape, dem.iloc[0]['Median heart rate (bpm)'])
#-- 3. 按受试者分组切分,保证同一人不跨两侧
from sklearn.model_selection import GroupKFold
groups = dem['Subject number'].to_numpy()
for tr, te in GroupKFold(n_splits=5).split(dem, groups=groups):
assert set(groups[tr]).isdisjoint(set(groups[te]))
break
9.3 引用方式
PhysioNet 的惯例是同时引用资源本身与平台。
| 引用对象 | 内容 |
|---|---|
| 资源 | Lazović, A., Tadić, P., Đorđević, N., Atanasoski, V., Tiosavljevic, M., Ivanovic, M., Hadzievski, L., Ristic, A., Vukcevic, V., & Petrovic, J. (2024). SensSmartTech database of cardiovascular signals synchronously recorded by an electrocardiograph, phonocardiograph, photoplethysmograph and accelerometer (version 1.0.0). PhysioNet. https://doi.org/10.13026/fy9p-n277 |
| 平台 | PhysioNet 平台综述论文,按官方页面的引用按钮生成 |
| 关联数据论文 | 同团队发表于《Scientific Data》的数据论文,官方被引清单列为最新两篇之一 |
| 联系人 | 官方 README.txt 指定 Jovana Petrovic 为答疑联系人 |
论文里建议同时交代四件事:使用的版本号(1.0.0)、用的是 CSV 还是 WFDB、划分是否按受试者编号、以及十通道是否做了单位归一化。少了任何一条,他人的复现都会失之毫厘。
§10 AI 使用声明
| 项目 | 声明 |
|---|---|
| 文本生成 | 本文由 AI 辅助撰写,编辑把关结构与事实 |
| 数字来源 | 规模、结构、边界三类数字来自 PhysioNet 官方页面与文件目录 |
| 文件核验 | RECORDS、四个模态的头文件、四份 CSV 的表头、人口学表表头、校验和清单经直接访问确认 |
| 不一致说明 | 官方正文称脉搏波两色波长为短波与八百纳米,文件名与头文件通道名写的是短波与八百八十纳米;摘要称心音测于心尖,方法段称听诊器置于胸骨、V3 电极右侧。两处文中以文件名与方法段为准并已注明 |
| 论文信息 | 关联数据论文仅见于官方页面的被引清单,未读全文 |
| 未核验内容 | 加速度通道的采样率(官方未给,文中依据 CSV 时间列步长的观察值并已标注)、每位受试者各自的记录段数、运动形式与实际强度、逐段信号的可用性分级 |
| 图像 | 无配图;封面为生成式提示词,不含真实波形 |
| 免责 | 本文不构成临床建议;数据使用须遵守 CC BY 4.0 的署名要求 |
常见误读(避坑清单)
| 说法 | 实际 | 证据 |
|---|---|---|
| 一条记录是一个文件 | 一条记录拆成四个文件,后缀分别是 ecg、pcg、ppg、acc | 文件清单与人口学表的四列文件名 |
| WFDB 是原始采样率 | WFDB 重采样到 1 kHz,原始为心电 500 Hz、心音 1 kHz、脉搏波 100 Hz | 官方数据描述段与 CSV 时间列 |
| 存在十通道的单一数据文件 | 十通道分布在四个文件里,必须自己拼 | 四个头文件的信号条数字段分别为 4、1、4、1 |
| 它是标准十二导联 | 只有肢体导联加 V3、V4,胸前冗余电极被放到右上臂 | 官方方法段明确说明 |
| 两色波长是六百六十与八百纳米 | 文件通道名写的是六百六十与八百八十纳米 | 头文件通道名与 CSV 表头 |
| 它含有患者数据 | 三十二人全部为无心血管病史的健康志愿者 | 官方入组标准与数据描述 |
| 它有逐搏标注 | 只有每段一个中位心率与运动前后标记 | 人口学表列名与官方描述 |
| 记录是在卧位静息完成的 | 全部在站立位,且明确包含运动后恢复期的重复记录 | 官方方法段的采集协议 |
| 按记录随机划分就行 | 同一位受试者贡献多段,共享电极与生理特质 | 人口学表的受试者编号列 |
| 三十秒乘以三百三十八段就是它的全部限制 | 真正的限制在人群而不在时长:全是健康人、单一中心、单一年龄带 | 官方数据描述段与伦理一节 |
FAQ
Q1:三百三十八段记录到底是怎么确证的?
官方摘要写明库由三百三十八段三十秒的多参数信号组成。文件侧的交叉核验很干净:CSV 目录下每种模态正好三百三十八份文件,四种模态合计一千三百五十二个;WFDB 目录里每种模态各有一份头文件与一份信号文件,合计两千七百零四个;再加根目录的四份文件,总数正好等于校验和清单的行数四千零六十。换句话说,记录数不是靠数文本行得来的,而是靠每个模态文件数相等这个结构约束确认的。用行计数命令去数 RECORDS 有可能得到一个偏小的数,因为该文件最后一行是否以换行符结尾并不确定,这种数法的可靠性天然不如按模态文件数交叉核验。想要万无一失,就下载校验和清单,按 CSV 目录的行数除以四来算。
Q2:为什么有的地方说三十秒,有的地方说二九九九四个采样点?
两者都对,说的是不同层面。官方把每段记录称为三十秒;WFDB 文件里每个文件的采样点数是二九九九四个,在一千赫兹的采样率下等于二十九点九九四秒。零点零零六秒的差异来自重采样时的截断处理,对绝大多数任务没有影响。需要注意的是这不是记录长度的真实误差,而是重采样之后的长度舍入,所以不要把它当成时钟不同步或者丢包的证据。此外,不同模态的原始采样率差了一个数量级,三十秒这个名义长度在原始信号侧的表现完全不同:心电大约一万五千个点,心音大约三万个点,脉搏波大约三千个点。看到这三个数字不要以为数据缺失,那是采样率差异的正常结果。
Q3:CSV 和 WFDB 到底该用哪一个?
取决于你要的量是不是毫秒级的。如果你关心的是收缩时间间期、脉搏传导时间这类以毫秒计的间隔,只能用 CSV,因为 WFDB 已经把脉搏波从一百赫兹插值到了一千赫兹,插值本身会移动波足的位置,直接改变你测出来的毫秒数——从一百赫兹插值到一千赫兹,等于在原本十毫秒一个点的地方凭空造出九个中间点,任何依赖波足或二阶导数的特征都会被这个过程改写。反过来,如果你要做跨模态特征融合、把十通道拼成矩阵喂网络,用 WFDB 更省事,因为它保证四个模态共用同一条时间轴。两者都经过了官方说明的同一种滤波处理,因此在是否干净这件事上没有区别,区别只在时间轴。
Q4:它能用来训练无袖带血压模型吗?
不能直接训练,可以做相关性研究。库里没有同步的血压真值,既没有袖带测量也没有侵入式动脉压,所以拿不出监督学习的标签。它能支持的是另一类工作:从心电图与脉搏波里提取脉搏传导时间,验证这个量与血压的关系是否稳定、是否随心率变化、在两个传播距离上是否一致。官方也明确把后者列为它的主要优势之一,即用于无袖带血压监测的瞬时脉搏传导时间研究。想做真正的血压回归,你需要的是带血压真值的数据集;本库在其中的角色是提供一套高质量的多模态波形,用来校核你算出来的传导时间是不是可靠。
Q5:为什么要按受试者编号划分而不是按记录划分?
因为同一个人的多段记录不是独立样本。每位受试者先在静息状态录三段,再在运动后反复录到心率回落,这意味着同一个人的各段共享同一次贴电极、同一个胸壁形态、同一种呼吸方式、同一颗心脏的电轴与传导特性。按记录随机切分时,同一个受试者会同时出现在训练集与测试集里,模型只要学会这个人的波形长什么样就能白拿分。这种做法出来的指标在换到另一批人或另一台设备时会大幅下滑,因为它验的不是泛化能力。官方虽然没有明说划分方式,但人口学表里专门设了受试者编号这一列,本意就是让人拿它做分组键,用分组交叉验证或者直接按编号区间切分都可以,唯一的标准是同一个人绝不出现在两侧。
术语表
| 术语 | 解释 |
|---|---|
| 多导心动记录仪 | 本库团队自研的同步采集设备,官方称 polycardiograph |
| 光电容积脉搏波 | 用光照射组织、测量反射或透射光强变化得到的血容积随时间波形 |
| 心音图 | 记录心脏瓣膜关闭与血流冲击产生振动的信号 |
| 心震图 | 胸壁加速度,反映心脏跳动传递给胸壁的机械振动 |
| 收缩时间间期 | 从心电 QRS 起点到心音主动脉瓣成分之间的间隔,用于心衰诊断 |
| 脉搏传导时间 | 压力波从心脏传播到外周测量点所用的时间,无袖带血压的代理变量 |
| 机电耦合 | 心脏电活动与机械收缩之间的时间关系 |
| 中位心率 | 本库定义:一段记录内 RR 间期中位数的倒数 |
| RR 间期 | 相邻两次心搏之间的时间间隔 |
| 波形数据库格式 | WFDB,PhysioNet 使用的波形存储规范,含头文件与信号文件 |
| 头文件 | .hea 纯文本文件,声明采样率、增益、通道名等元信息 |
| 增益 | 每物理单位对应的整数值,用于从存储值还原物理量 |
| ADC 零值 | 零电平对应的整数值,换算时先减 |
| 校验和 | 采样点累加和,用于检测文件是否完整 |
| 受试者级划分 | 同一受试者的所有记录只进训练或只进测试 |
| 双波长血氧 | 同一探头发射两种波长的光,利用不同波长下血红蛋白吸收差异测血氧 |
| 双位点测量 | 在颈动脉与肱动脉两处同时放置脉搏波探头 |
| 垂悬导联噪声 | 未固定的导联线晃动引入的干扰 |
| 基线漂移 | 信号缓慢偏离零位的低频成分,脉搏波中的基线漂移含呼吸信息 |
| 重采样 | 把信号从一种采样率变换到另一种采样率 |
| 电机械延迟 | 心肌电激动到机械收缩开始之间的时间差 |
| 去标识化 | 移除可识别个人信息的数据处理步骤 |
| CC BY 4.0 | 知识共享署名许可,允许任意用途,条件为署名 |
| PhysioNet | 由麻省理工学院等机构维护的生物医学信号数据平台 |
附录 A:核心数字核对表
| 项 | 值 | 来源 | 来源层级 |
|---|---|---|---|
| 记录数 | 338 段 | 官方摘要;各模态文件数交叉核验 | 官方页面 + 官方文件 |
| 每段时长 | 30 秒 | 官方摘要;WFDB 采样点数 29994 ÷ 1000 | 官方页面 + 官方文件 |
| 受试者数 | 32 名 | 官方数据描述段 | 官方页面 |
| 性别构成 | 女性 18 名、男性 14 名 | 官方数据描述段 | 官方页面 |
| 平均年龄 | 34.0 ± 8.6 岁 | 官方数据描述段 | 官方页面 |
| 平均体质指数 | 25.1 ± 4.3 kg/m² | 官方数据描述段 | 官方页面 |
| 通道总数 | 10 | 官方摘要;四个文件信号条数字段 4/1/4/1 | 官方页面 + 官方文件 |
| 心电采样率 | 500 Hz | 官方方法段;CSV 时间列步长约 2 毫秒 | 官方页面 + 官方文件 |
| 心音采样率 | 1 kHz | 官方方法段;CSV 时间列步长约 1 毫秒 | 官方页面 + 官方文件 |
| 脉搏波采样率 | 100 Hz | 官方方法段;CSV 时间列步长约 9.9 毫秒 | 官方页面 + 官方文件 |
| 模数转换位数 | 16 位 | 官方方法段 | 官方页面 |
| 重采样后采样率 | 1 kHz | 官方数据描述段;头文件记录行第 3 字段 | 官方页面 + 官方文件 |
| 重采样后长度 | 29994 点 | 头文件记录行第 4 字段 | 官方文件 |
| 心率范围 | 58–173 bpm | 官方背景段 | 官方页面 |
| 平均最低心率 | 83 ± 11 bpm | 官方摘要 | 官方页面 |
| 平均最高心率 | 143 ± 14 bpm | 官方摘要 | 官方页面 |
| 静息记录段数 | 每人 3 段 | 官方方法段采集协议 | 官方页面 |
| 运动终止条件 | 心率回落到静息值加 10–20 bpm | 官方方法段采集协议 | 官方页面 |
| CSV 目录文件数 | 1352 | 校验和清单清点 | 官方文件 |
| WFDB 目录文件数 | 2704 | 校验和清单清点 | 官方文件 |
| 文件总数 | 4060 | 校验和清单行数 | 官方文件 |
| 未压缩体积 | 775.0 MB | 官方页面文件区 | 官方页面 |
| 压缩包体积 | 264.9 MB | 官方页面文件区 | 官方页面 |
| 版本与发布日 | 1.0.0,2024-12-19 | 官方页面发布信息 | 官方页面 |
| 许可 | CC BY 4.0 | 官方页面;许可文件首行 | 官方页面 + 官方文件 |
| 本版本 DOI | 10.13026/fy9p-n277 | 官方页面发现信息 | 官方页面 |
| 最新版本 DOI | 10.13026/z1de-fn10 | 官方页面发现信息 | 官方页面 |
| 被引文献数 | 3 | 官方页面被引清单 | 官方页面 |
附录 B:数字的来源分层
第一层:官方页面与官方文件。 记录数、受试者数、性别年龄体质指数、通道构成、采样率、转换位数、心率范围、协议细节、文件体积、版本与许可,全部来自项目主页的摘要、方法、数据描述三个段落,以及 RECORDS、四个头文件、CSV 表头、人口学表表头、校验和清单。
第二层:文件层面的观察。 CSV 时间列的相邻步长、人口学表表尾的空列、列名里 B 之后的两个空格这些细节,是靠直接读取文件得到的。它们属于结构描述而非统计推断,但仍然提醒你:官方文档没有覆盖到的一切,都应当以文件为准。
第三层:未核实。 加速度通道的确切采样率(官方未给出,正文中的观察值已标注来源);每一位受试者各自贡献多少段记录;运动的具体形式与实际强度;每段信号的质量分级。这些需要下载全量后逐条处理,超出了本篇的范围,正文中凡是涉及的地方都只做定性表述。
附录 C:完整参考文献
| 编号 | 文献 | 链接 | 用途 |
|---|---|---|---|
| 1 | SensSmartTech 数据库 v1.0.0 | https://physionet.org/content/senssmarttech/1.0.0/ | 全部规模、结构、边界数据的来源 |
| 2 | 该库的文件目录 | https://physionet.org/files/senssmarttech/1.0.0/ | RECORDS、头文件、CSV 表头、人口学表 |
| 3 | Lazović 等,《Scientific Data》数据论文 | 见官方页面被引清单 | §7.5 与 §8.4 的背景 |
| 4 | PhysioNet 平台综述 | https://doi.org/10.1038/s44360-026-00096-z | 托管模式与引用规范 |
| 5 | Dehkordi 等,心脏时间间期估算方法比较 | https://doi.org/10.3389/fphys.2019.01057 | 官方参考文献 1,§4.3 背景 |
| 6 | Weissler 等,心力衰竭患者的收缩时间间期 | https://doi.org/10.1161/01.CIR.37.2.149 | 官方参考文献 2,§4.3 背景 |
| 7 | Ji 等,冠心病患者的机电耦合测量 | https://doi.org/10.3390/e18040153 | 官方参考文献 3,§4.1 背景 |
| 8 | Elgendi 等,光电容积脉搏波用于高血压评估 | https://doi.org/10.1038/s41746-019-0136-7 | 官方参考文献 4,§1.1 背景 |
| 9 | Jarchi 与 Casson,运动状态下的腕部光电容积脉搏波库 | https://doi.org/10.3390/data2010001 | 官方参考文献 5,§2.6 对照 |
| 10 | ScientISST MOVE 多模态可穿戴库 | https://doi.org/10.13026/sg89-qq52 | 官方参考文献 6,§2.6 对照 |
| 11 | Pulse Transit Time PPG 数据集 | https://doi.org/10.13026/jpan-6n92 | 官方参考文献 7,§2.6 与本站点对照 |
| 12 | PhysioBank、PhysioToolkit 与 PhysioNet 综述 | https://doi.org/10.1161/01.CIR.101.23.e215 | 官方参考文献 8,平台背景 |
附录 D:任务代码
任务一:按受试者分组的心率分层对照
import numpy as np
import pandas as pd
from sklearn.model_selection import GroupKFold
dem = pd.read_csv('Demographics.csv')
dem = dem.loc[:, ~dem.columns.str.startswith('Unnamed')]
#-- 用官方给的中位心率分层,观察某个特征随心率的变化
for band, sub in dem.groupby(pd.cut(dem['Median heart rate (bpm)'],
bins=[50, 90, 120, 150, 180])):
print(band, '记录数', len(sub), '受试者数', sub['Subject number'].nunique())
#-- 按受试者编号五折切分
groups = dem['Subject number'].to_numpy()
for tr, te in GroupKFold(n_splits=5).split(dem, groups=groups):
print('训练集受试者数', len(set(groups[tr])), '测试集受试者数', len(set(groups[te])))
break
注意这段代码只按区间计数,不输出任何派生比例。想比较组间差异时,记得每个区间的受试者数是不同的,三十二这个总数是硬约束。
任务二:从 CSV 取两个模态的时间轴对照
import numpy as np
import pandas as pd
#-- 读原始 CSV,保留毫秒时间戳
ecg = pd.read_csv('CSV/1_10-09-54_ecg.csv')
ppg = pd.read_csv('CSV/1_10-09-54_ppg.csv')
t_ecg = ecg['t'].to_numpy()
t_ppg = ppg['t'].to_numpy()
print('心电时间戳覆盖范围', float(t_ecg.min()), float(t_ecg.max()))
print('脉搏波时间戳覆盖范围', float(t_ppg.min()), float(t_ppg.max()))
print('两条时间轴的起始偏移差', float(abs(t_ecg.min() - t_ppg.min())))
第二段代码刻意没有把脉搏传导时间算完。原因很简单:如何定义心电锚点与脉搏波波足,是每篇论文都要自行论证并公开交代的事,写成一行成品反而会掩盖这个选择带来的影响。把两个数组的时间覆盖范围对照清楚,比给出一个可疑的毫秒数更有用。
附录 E:如果只记五件事
| 序号 | 记住什么 | 为什么 |
|---|---|---|
| 1 | 338 段 30 秒、32 名健康人、10 通道、四模态同步 | 这四个数字定义了全部的用法与限制 |
| 2 | CSV 是原始采样率,WFDB 是重采样到 1 kHz | 算毫秒级量必须用 CSV |
| 3 | 十个通道分布在四个文件里,必须自己拼 | 没有单文件十通道这回事 |
| 4 | 只有段级中位心率与运动前后标记,无逐搏注释 | 它是抽取型研究的资源,不是流水线训练集 |
| 5 | 按受试者编号划分,不按记录划分 | 同一个人的多段共享太多特质 |
编辑说明
本文的核验时间为 2026 年 10 月 29 日。核对方式为直接访问 PhysioNet 项目页与文件目录,逐一确认了 RECORDS 的记录清单、四个模态的头文件、四份 CSV 的表头与首几行、人口学表的表头与首几行、以及校验和清单的完整清点;论文侧只查阅了官方页面提供的被引清单与参考文献链接,未读全文。官方处的两处不一致已在 §2.4、§5.6 与 §10 各说明一次。未覆盖的内容包括:加速度通道的确切采样率、每位受试者各自的记录段数、运动形式与实际强度、以及逐段信号的可用性分级。这些需要下载全量后统计,本文按要求只写规模、结构、边界三类数字。
相关数据集导航
以下为站内 AI-Ready 数据集百科中与本词条共享多个主题标签的相关数据集,按相关度降序排列:
- pulse-transit-time-ppg,共享标签:生理信号 / 光电容积脉搏波 / 心血管监测 / 可穿戴设备
- simultaneous-measurements,共享标签:生理信号 / 可穿戴设备 / 心电信号 / 多模态时序
- respiratory-heartrate-dataset,共享标签:生理信号 / 心电信号 / 多模态
- ecg-capable-smartwatches,共享标签:生理信号 / 心电信号 / 可穿戴设备
- openox-repo,共享标签:生理信号 / 脉搏血氧 / 医疗设备评估
- motion-artifact,共享标签:生理信号 / 伪影去除
- nstdb,共享标签:生理信号 / 噪声与伪迹 / 算法评测
- pwave,共享标签:生理信号 / 心电信号 / 人工标注
- prcp,共享标签:生理信号 / 心电信号 / 血压信号
- cps-dataset-sleep,共享标签:生理信号 / 多导睡眠图 / 临床数据集
导航说明:本章节由全站统一标签体系自动计算生成(标签重合度算法),双向可达;点击链接可跳转至对应数据集词条。

