PTB-XL心电信号处理
ECG-Classfier
选修了一门模式识别的课程,这篇博客是对本人模式识别课程设计的一个简单的总结,相关的代码已经上传至github,详情参见后文的github链接
PTB-XL database
首先是数据的说明,这里用到的心电数据来自PTB-XL数据库,以下数据库的说明来自官方网站,详情可以参看PTB-XL详情页。
简介
在1989年10月至1996年6月的近七年中,使用Schiller AG的设备收集了PTB-XL ECG数据集的基础波形数据。通过从Schiller AG收购原始数据库,将全部使用权转让给了Schiller AG。 PTB。在Physikalisch-Technische Bundesanstalt(PTB)的一个长期项目中,整理了这些记录并将其转换为结构化数据库。该数据库已在许多出版物中使用,但是直到现在,访问仍然受到限制。机构伦理委员会批准了匿名数据在开放访问数据库(PTB-2020-1)中的发布。在2019年的公开发布过程中,对现有数据库进行了简化,特别是针对机器学习社区的可用性和可访问性。
数据采集
- 原始信号数据已记录并以专有压缩格式存储。对于所有信号,我们在右臂上提供12组标准导线(I,II,III,AVL,AVR,AVF,V1,…,V6),并带有参考电极。
- 一般对应的元数据(如age,sex,weight和height)被收集在数据库中。
- 每条记录都用报告字符串(由心脏病专家生成或由ECG设备自动解释)进行注释,该报告字符串将转换为一组标准化的SCP-ECG声明(scp_codes)。对于大多数记录,还提取了心脏的轴(heart_axis)和梗塞区(infarction_stadium1和infarction_stadium2,如果存在的话)。
- 大部分记录已由第二位心脏病专家确认。
- 所有记录均由主要关注信号特性的技术专家验证。
数据预处理
心电图和患者由唯一的标识符(ecg_id和patient_id)标识。元数据中的个人信息(例如,验证心脏病专家,护士的姓名和记录的记录地点(医院等))是假名。出生日期仅作为ECG记录时的年龄,其中符合HIPAA标准的89岁以上的年龄在300的范围内。此外,每位患者的所有ECG记录日期均偏移了随机偏移量。用于注释记录的ECG声明遵循SCP-ECG标准。
数据集说明
数据集组织结构如下所示
ptbxl
├── ptbxl_database.csv
├── scp_statements.csv
├── records100
│ ├── 00000
│ │ ├── 00001_lr.dat
│ │ ├── 00001_lr.hea
│ │ ├── ...
│ │ ├── 00999_lr.dat
│ │ └── 00999_lr.hea
│ ├── ...
│ └── 21000
│ ├── 21001_lr.dat
│ ├── 21001_lr.hea
│ ├── ...
│ ├── 21837_lr.dat
│ └── 21837_lr.hea
└── records500├── 00000│ ├── 00001_hr.dat│ ├── 00001_hr.hea│ ├── ...│ ├── 00999_hr.dat│ └── 00999_hr.hea├── ...└── 21000├── 21001_hr.dat├── 21001_hr.hea├── ...├── 21837_hr.dat└── 21837_hr.hea
将下载后数据集解压后拷贝至data
文件夹下:
PTB-XL-CLASSFIER
├── code
├── dataPreprocess.ipynb
├── data├── ptbxl_database.csv├── scp_statements.csv├── records100│ ├── 00000│ │ ├── 00001_lr.dat│ │ ├── 00001_lr.hea│ │ ├── ...│ │ ├── 00999_lr.dat│ │ └── 00999_lr.hea│ ├── ...│ └── 21000│ ├── 21001_lr.dat│ ├── 21001_lr.hea│ ├── ...│ ├── 21837_lr.dat│ └── 21837_lr.hea└── records500├── 00000│ ├── 00001_hr.dat│ ├── 00001_hr.hea│ ├── ...│ ├── 00999_numhr.dat│ └── 00999_hr.hea├── ...└── 21000├── 21001_hr.dat├── 21001_hr.hea├── ...├── 21837_hr.dat└── 21837_hr.hea...
该数据集包含18885名患者的10837秒的21837条临床12导联ECG记录,其中52%是男性,48%是女性,年龄范围从0到95岁(中位数为62,分位数范围为22)。数据集的价值来自对许多不同的同时发生病理的全面收集,也来自于大部分健康对照样品。诊断的分布如下,为了简化起见,我们将诊断语句限制为聚合到超类中的诊断语句(注意:由于每个记录可能有多个标签,因此语句的总和超过了记录数):
Records | Superclass | Description |
---|---|---|
9528 | NORM | Normal ECG |
5486 | MI | Myocardial Infarction |
5250 | STTC | ST/T Change |
4907 | CD | Conduction Disturbance |
2655 | HYP | Hypertrophy |
波形文件以16位精度以WaveForm数据库(WFDB)格式存储,分辨率为1μV/ LSB,采样频率为500Hz(records500/)。为了方便用户,我们还以100Hz(records100/)的采样频率发布了下采样版本的波形数据。
所有相关的元数据ptbxl_database.csv均以标识,每条记录存储一行。它包含28个列,可以分为:ecg_id
- 标识符:每个记录都由唯一的来标识ecg_id。对应的患者通过编码patient_id。原始记录(500 Hz)的路径和记录的降采样版本(100 Hz)存储在filename_hr和中filename_lr。
- 常规元数据:人口统计和记录元数据,例如年龄,性别,身高,体重,护士,部位,设备和recording_date。
- ECG语句:核心组件是(SCP-ECG语句作为字典,带有以下形式的条目)
scp_codesstatement: likelihood,其中可能性(如果未知,则设置为0)并进行报告(报告字符串)。附加字段,,,,,和。 - 信号元数据:信号质量,例如噪声(和),基线漂移()和其他伪像,例如。我们还提供了计数额外的心脏收缩和起搏器的信号模式,以指示起搏器处于活动状态。
- 交叉验证折叠:建议进行10倍火车测试拆分(heart_axisinfarction_stadium1infarction_stadium2validated_bysecond_opinioninitial_autogenerated_reportvalidated_by_human
static_noiseburst_noisebaseline_driftelectrodes_problemsextra_beats
strat_fold)是在尊重患者分配的同时通过分层抽样获得的,即特定患者的所有记录都分配了相同的首折。第9和10折中的记录至少经过了一次人工评估,因此具有特别高的标签质量。因此,我们建议将1-8倍用作训练集,将9倍用作验证集,将10倍用作测试集。
与使用的注释方案有关的所有信息都存储在专用文件中,该文件中充斥着与其他注释标准(例如AHA,aECGREFID,CDISC和DICOM)的映射。我们提供了其他附带信息,例如可以将每个语句分配给的类别(诊断,形式和/或节奏)。对于诊断语句,我们还提供了一个建议的层次结构到和中。scp_statements.csvdiagnostic_classdiagnostic_subclass
获取数据
当然处理数据的第一步不可获取的需要获取数据,获取数据的网页连接和方法如下:
- 该数据集的下载页面在这里:PTB-XL
- 压缩的数据集下载:下载ZIP文件
- 在终端下载可以直接通过
wget
命令行实现
wget -r -N -c -np https://physionet.org/files/ptb-xl/1.0.1/
得到的12通道的数据如下图所示:
数据预处理
数据预处理通过code/dataPreprocess.ipynb
处理实现
主要的流程包括:平滑滤波、50Hz陷波、R波分段提取、基线漂移去除、数据集划分
平滑滤波
通过窗口滑动平均滤波实现,这里采用的是10点平滑滤波,最开始是尝试的5点平滑滤波,但是根据导师的建议,平滑滤波的点数 NNN 是通过采样频率 fsfsfs 和工频干扰频率 fcfcfc 的比值得到的,具体的计算公式:
N=fs/fcN = fs/fc N=fs/fc
调用的是np的卷积函数:
# 平滑滤波函数
def np_move_avg(a,n,mode="same"):return(np.convolve(a, np.ones((n,))/n, mode=mode))
# 调用平滑滤波函数
ecg_filtered = np_move_avg(ecg_original, 5)
平滑滤波的效果如下图所示:
50Hz陷波
通过scipy.signal.iirnotch
实现
最开始的处理没有考虑到平滑滤波的点数,导致50Hz的公频没用去掉,所以尝试使用一个陷波器去除 公频干扰,如果之前的平滑滤波在500Hz采样频率信号的点数为10点的话,工频干扰基本可以去除的很干净,之后就不用采用陷波处理了
R波分段提取
R波的检测是通过固定差分阈值实现,基本原理是设定一个固定的峰值阈值作为限定条件,一般通过获取某一段时间内心电信号最大值和最小值,来设置捕获条件阈值,计算式如下:
Threshhold=(max(x)−min(x))×0.7+min(x)Threshhold = (max(x)-min(x)) \times 0.7 + min(x) Threshhold=(max(x)−min(x))×0.7+min(x)
这里主要是通过II导联的心电信号进行差分阈值得到R波的位置
基线漂移去除
基线漂移的去除是采用PR
段作为基线,先取每个导联PR
段上10个数据点的均值作为基线的近似值,然后用所有的数据减去该近似值,即可得到去基线的心电图数据
关于要不要去除基线这个问题持保留情况,主要是心电信号在低频部分也有部分很重要的有用信号,例如ST段,考虑到基线对心电前期预处理没有太大的干扰,这里就没有去除基线漂移
导师给的意见是如果要想模型建立的更加稳定精确,最好去除一下基线漂移
机器学习模型分类
这部分的内容就较为简单,主要是调用sklearn库函数实现分类,具体实现的模块在mlModel.ipynb
数据超采样
这里的心电数据样本存在样本不均衡的问题,所有的分类中正样本比例均显著低于负样本比例,如果采用欠采样的话会使训练集丢失部分数据,而过采样会导致一个数据点在高维空间出现多次,增加过拟合风险,很多研究通过在过采样中加入少量随机噪声来减少这类风险
这里需要安装imblearn
包,使用以下的命令行安装
pip install imbalanced-learnoversampler = SMOTE(random_state=42)os_features, os_label = oversampler.fit_sample(X_train.reshape(len(X_train), 6000), y_train)
PCA降维
在进行最后的分类前,可以看到数据输入的维度较大为6000,在真实分类之前首先对训练数据进行PCA降维,将6000维的数据降为240维的数据。这样得到降维后的数据还保留原始数据超过99%的信息,而且在训练中计算量大大减少,也可以在一定程度上降低过拟合的情况。
from sklearn.decomposition import PCApca_train = PCA(n_components=240)
pca_train.fit(os_features)
分类模型
尝试了下svm,运行的时间太慢了,实在等不下去了,测试了下随机森林分类,效果在预期之内,就利用随机森林跑了一下分类,之后有时间再修改一下
from sklearn.linear_model import SGDClassifiersgd_clf = SGDClassifier(random_state=42)
sgd_clf.fit(X_train_pca, y_train_norm)
利用随机森林对特定分类的病例二分类的分类器的准确率如下:
class | accuracy | precision | recall | f1-score | roc score |
---|---|---|---|---|---|
MI | 0.904 | 0.993 | 0.535 | 0.695 | 0.950 |
STTC | 0.899 | 0.987 | 0.516 | 0.678 | 0.936 |
CD | 0.905 | 0.911 | 0.587 | 0.714 | 0.914 |
HYP | 0.940 | 0.990 | 0.720 | 0.833 | 0.963 |
得到的不同类别的病症的分类roc曲线如下图所示:
代码地址
本文的相关代码已经上传到github,后续的改进可能不会在CSDN及时更新,可以在github查询
github网址
也可以在百度网盘查看相关代码和文件:链接 密码: la01
个人博客地址:madao’s blog
PTB-XL心电信号处理相关推荐
- 基于MATLAB实现ECG心电信号处理
原文出处基于MATLAB的心电信号预处理_这孩子谁懂哈的博客-CSDN博客_matlab心电信号处理 这是原文的代码,直接复制后无法运行,显示M和TIME没有定义. 需要一个ramat函数把心电数据读 ...
- python处理心电图_ECG心电信号处理:使用WFDB对MIT-BIH数据集进行读取(Python)
本文的主要内容是详细介绍MIT-BIH心电数据集的读取,主要使用WFDB-python工具进行操作,能够读取心电信号数据到array中,读取annatations以及使用matplotlib绘制相应的 ...
- matlab心电信号处理,基于Matlab的心电信号自动处理系统的设计与开发 毕业论文设计.doc...
您所在位置:网站首页 > 海量文档  > 计算机 > matlab 基于Matlab的心电信号自动处理系统的设计与开发 ...
- ECG心电信号处理:初识ECG
本文主要介绍心电信号的基础知识,包括心电图的典型波形和波段,以及常见的心率不起分类和一些用于心电分类的数据集,能对心电信号及处理有一个最基本的认识. 声明:本博客的内容来源于各大论文和互联网,其正确性 ...
- 从0开始学心电信号处理(2)——心电信号的预处理
目录 一.心电信号噪声 二.心电信号预处理 一.心电信号噪声 EGG信号具有微弱.低幅值.低频.随杋性的特点,很容易被噪声干扰,而噪声可能来自生物体内,如呼吸.肌肉颤抖,也可能因为接触不良而引起体外干 ...
- 基于matlab的心电信号处理毕业论文,浅议仿真基于MATLAB的“数字信号处理”仿真实验毕业论文范文...
论文导读:),通过扬声器可以听到"重庆邮电大学,重庆邮电大学"声音,对原始语音信号进行FFT 频谱分析,程序关键代码如下: figure: t=(0:length(x)-1)/Fs ...
- 基于指数平滑对心电信号进行PQRST模拟(第二种方案)
基于指数平滑对心电信号进行PQRST模拟,对下面的流程中的橙色部分进行实现. 第一种方案流程请见[1] 最终结果如下: 上述圆圈处是异常信号(幅度异常,以及与其他心拍距离异常),删除. 局部放大效果如 ...
- Matlab心电信号的PQRST模拟-实验报告
心电信号处理算法设计-实验要求 data4 是一段实际采样得到的心电数据, 采样频率为 100Hz, 波形如下图所示.设计相应的算法, 计算心率, 单位为: 次/分钟.可能会用到的知识为数字滤波器的设 ...
- 心电信号的PQRST模拟matlab代码(转载+自己调研汇总)
目前PQRST网上现成的代码有两份[1][2] 我们采用[2],原因是[1]中采用了lowpass这个函数, [3]中提到:"注意,只有2018年之后的matlab才有lowpass, ba ...
- 根据心电信号计算心率的matlab代码
先说说现有的资料: [1][2]弄了FIR1还有hamming窗,搞得老麻烦了,扔一边先. --------------------------------------------------自己另外 ...
最新文章
- 第一个使用计算机图形学术语,计算机图形学考题
- Django web框架
- Python基础(11)--面向对象1
- Object的finalize方法
- linux脚本打印循环次数,shell脚本编程基础(3)——循环用法
- Docker pull镜像报错问题
- 授人以鱼不如授人以渔,UCHome全面大解析培训【第二集】
- Cython 3.0 中文文档校对活动 | ApacheCN
- HTML不熟悉方法总结
- 在HTML中添加图片阴影,html – 如何在CSS中为图像添加内部阴影[复制]
- 删除WIN10右键解压缩菜单
- 解决H61、H81、B85以上的主板安装XP系统蓝屏
- 【交换机在江湖】第十四章 VLAN通信篇
- 基于Python的RRT算法实现
- 什么是OFD格式文档?一文教你读懂OFD格式文档
- 数据清洗的主要类型及步骤
- 【渝粤题库】陕西师范大学201821 宋词研究 作业(专升本)
- 向工程腐化开炮 | manifest 治理
- 2021年中国粮食行业发展现状分析,粮食播种面积、产量再度迎来上涨「图」
- 植物大战僵尸存档任务C1-01
热门文章
- 如何调试微信浏览器内嵌H5
- php花店会员信息管理系统,PHP网上花店管理系统
- power supply surges detected
- netperf工具的使用
- js 封装原生XMLHttpRequest
- 强悍!winrar妙用-将bat脚本打包成exe可执行文件并实现自动执行
- 【网络架构理论系列】简述分布式的定义、分类、技术发展历史进程
- 深度学习面试100题
- 塔菲克蓝牙适配器驱动_TAFIQ蓝牙适配器驱动(TAFIQ蓝牙设备驱动程序)V4.1 正式版...
- 台式计算机可以连接蓝牙吗,台式电脑可以连接蓝牙音响吗