前言
看了的博主https://me.youkuaiyun.com/weixin_42559479文章跟着动手做的复现,论文题目是An Improved Convolutional Neural Network Based Approach for Automated Heartbeat Classification。(我是小白,大佬请绕行!)
数据预处理
1.采用文章里提到的小波去噪的方法
滤波将小于5hz和大于90hz的小波系数替换为0,只保留第3和第6细节子带之间的系数进行重构。
# 小波去噪
def Wtfilt_1d(sig):
# 将信号进行小波分解,选用Daubechies8小波
coeffs = pywt.wavedec(sig, 'db6', level = 9) # dec分解滤波值,level分解阶次(要变换多少层)
coeffs[-1] = np.zeros(len(coeffs[-1]))
coeffs[-2] = np.zeros(len(coeffs[-2]))
coeffs[0] = np.zeros(len(coeffs[0]))
sig_filt = pywt.waverec(coeffs, 'db6') # rec重构滤波值
return sig_filt
# 绘制图片(以100为例)
record = wfdb.rdsamp("MIT-BIH/100", sampto = 100)[0][:,0]
plt.plot(record)
plt.title("Raw sigal")
plt.show()
record1 = Wtfilt_1d(record)
plt.plot(record1)
plt.title("De-noised signal using wavelet techniques")
plt.show()
2.心拍截取(R峰定位等基准点检测不是本次研究的重点,直接采用给定的R峰索引)
- 取R峰前0.4s(=0.4 * 360=144)+R峰后0.5s(=0.5s * 360=180)共324个点作为一个心拍
# 心拍截取
def Heartbeat(file):
N_Seg = []
SVEB_Seg = []
VEB_Seg = []
F_Seg = []
Q_Seg = []
#去掉指定的四个导联的头文件
de_file = [path[:-1] + "\\102.hea", path[:-1] + "\\104.hea", path[:-1] + "\\107.hea", path[:-1] + "\\217.hea"]
# set的集合运算
# b有a无 list(set(b).difference(set(a)))
file = list(set(file).difference(set(de_file))) # 去掉指定四个导联后的集合
for i in range(len(file)):
annotation = wfdb.rdann(path + file[i][-7:-4], "atr")
record_name = annotation.record_name # 读取记录名称
raw_record = wfdb.rdsamp(path + record_name)[0][:,0] # 只读取一个导联
record = Wtfilt_1d(raw_record)
label = annotation.symbol # 心拍标签列表
label_index = annotation.sample # 标签索引列表
for j in range(len(label_index)):
if (label_index[j] >= 144) and ((label_index[j] + 180) <= 650000):
if label[j] == "N" or label[j] == "." or label[j] == "L" or label[j] == "R" or label[j] == "e" or label[j] == "j":
seg = record[label_index[j] - 144: label_index[j] + 180]
segment = resample(seg, 251, axis = 0) # 重新采样到251
N_Seg.append(segment)
if label[j] == "A" or label[j] == "a" or label[j] == "J" or label[j] == "S":
seg = record[label_index[j] - 144: label_index[j] + 180]
segment = resample(seg, 251, axis = 0)
SVEB_Seg.append(segment)
if label[j] == "V" or label[j] == "E" :
seg = record[label_index[j] - 144: label_index[j] + 180]
segment = resample(seg, 251, axis = 0)
VEB_Seg.append(segment)
if label[j] == "F":
seg = record[label_index[j] - 144: label_index[j] + 180]
segment = resample(seg, 251, axis = 0)
F_Seg.append(segment)
if label[j] == "/" or label[j] == "f" or label[j] == "Q":
seg = record[label_index[j] - 144: label_index[j] + 180]
segment = resample(seg, 251, axis = 0)
Q_Seg.append(segment)
N_Segment = np.array(N_Seg)
SVEB_Segment = np.array(SVEB_Seg)
VEB_Segment = np.array(VEB_Seg)
F_Segment = np.array(F_Seg)
Q_Segment = np.array(Q_Seg)
print(N_Segment.shape, SVEB_Segment.shape, VEB_Segment.shape, F_Segment.shape, Q_Segment.shape)
# np.zeros返回来一个给定形状和类型的用0填充的数组;
# np.ones根据所给的形状和类型返回一个元素全部为1的数组, 默认numpy.float64类型
label_N = np.zeros(N_Segment.shape[0])
label_SVEB = np.ones(SVEB_Segment.shape[0])
label_VEB = np.ones(VEB_Segment.shape[0]) * 2
label_F = np.ones(F_Segment.shape[0]) * 3
label_Q = np.ones(Q_Segment.shape[0]) * 4
# np.concatenate对多个数组进行拼接:axis = 0数组的第一维度,axis = 1数组的第二维度
# 要求:一是相同维度的数组,二是除了axis外,数组的其余维度对应相等
label = np.concatenate((label_N, label_SVEB, label_VEB, label_F), axis = 0)
data = np.concatenate((N_Segment, SVEB_Segment, VEB_Segment, F_Segment), axis = 0)
return data, label