MITBIH数据处理分析day2——二分类数据处理(自留)

(一)代码解读

对于day1的代码进行分析:

首先,处理MIT-BIH数据库的数据,MIT-BIH的数据主要分为三个类型:.hea .dat .atr,首先要对这三种数据进行分析处理

def load_dataset():
    """加载并处理MIT-BIH数据集"""
    all_beats = []
    all_labels = []

    valid_symbols = {'N', 'L', 'R', 'B', 'A', 'a', 'J', 'S', 'V',
                     'r', 'F', 'e', 'j', 'n', 'E', '/', 'f', 'Q', '?'}

    for record in Config.RECORDS:
        try:
            # 读取数据
            record_path = os.path.join(Config.BASE_PATH, str(record))
            signal = wfdb.rdrecord(record_path, channels=[0]).p_signal.flatten()
            annotation = wfdb.rdann(record_path, 'atr')

            # 处理每个心拍
            for i, (symbol, sample) in enumerate(zip(annotation.symbol, annotation.sample)):
                if symbol not in valid_symbols:
                    continue

                # 截取心拍
                start = sample - Config.SAMPLE_LENGTH // 2
                end = sample + Config.SAMPLE_LENGTH // 2

                if start < 0 or end > len(signal):
                    continue

                beat = signal[start:end]
                beat = (beat - np.min(beat)) / (np.max(beat) - np.min(beat))  # 归一化

                # 生成标签
                label = 0 if symbol == 'N' else 1

                all_beats.append(beat)
                all_labels.append(label)

        except Exception as e:
            print(f"Error processing record {record}: {str(e)}")
            continue

    # 转换为numpy数组并添加通道维度
    X = np.array(all_beats)[..., np.newaxis]
    y = np.array(all_labels)

    return X, y

然后就是创建模型阶段,这里使用的是1D CNN(一维卷积神经网络)

  • 输入层:接收形状为input_shape的心电信号片段,表示每个心电信号片段的长度和通道数(这里是1个通道)。

  • 卷积层1

    • 使用32个卷积核,每个卷积核的大小为5,用于提取局部特征。

    • 使用ReLU激活函数,增加模型的非线性表达能力。

    • padding='same'确保输出的长度与输入相同,避免信息丢失。

  • 批量归一化层:对卷积层的输出进行归一化处理,加速训练过程,提高模型的稳定性。

  • 池化层1:使用最大池化,池化窗口大小为2,用于降低特征维度,减少计算量,同时保留重要特征。

  • 卷积层2

    • 使用64个卷积核,每个卷积核的大小为5,进一步提取更高级的特征。

    • 同样使用ReLU激活函数和padding='same'

  • 批量归一化层:对第二个卷积层的输出进行归一化处理。

  • 池化层2:再次使用最大池化,进一步降低特征维度。

  • Flatten层:将多维的特征图展平成一维向量,为全连接层做准备。

  • 全连接层:包含64个神经元,使用ReLU激活函数,用于整合提取到的特征。

  • Dropout层:以0.5的概率随机丢弃神经元,防止过拟合,提高模型的泛化能力。

  • 输出层:包含1个神经元,使用Sigmoid激活函数,输出一个介于0和1之间的概率值,表示样本属于正类的可能性。

def create_model(input_shape):
    """创建1D CNN模型"""
    model = models.Sequential([
        layers.Input(shape=input_shape),
        layers.Conv1D(32, 5, activation='relu', padding='same'),
        layers.BatchNormalization(),
        layers.MaxPooling1D(2),
        layers.Conv1D(64, 5, activation='relu', padding='same'),
        layers.BatchNormalization(),
        layers.MaxPooling1D(2),
        layers.Flatten(),
        layers.Dense(64, activation='relu'),
        layers.Dropout(0.5),
        layers.Dense(1, activation='sigmoid')
    ])

    model.compile(
        optimizer=tf.keras.optimizers.Adam(Config.INIT_LR),
        loss='binary_crossentropy',
        metrics=[
            'accuracy',
            tf.keras.metrics.AUC(name='auc'),
            tf.keras.metrics.Recall(name='recall'),
            tf.keras.metrics.Precision(name='precision')
        ]
    )
    return model

(二)数据预测

由于没有现成的数据,所以本文直接基于MITBIH作为要预测的数据,方便后续进行。

这里对数据的处理,我一开始希望用训练好的模型参数来进行预测,然后将患者的所有数据进行列出,但是只处理100-109的数据,花费了十分钟之久,导出的Excel数据有255列,2w行的数据...所以我改变了思路,直接将分类后的患者基本数据进行打印,并且对原始的hea数据增加一个标签:diagnosis(normal/abnormal),这样就可以减少因为列出数据而造成的时间浪费,提高代码的运行效率。运行结果如下:

然后将再用一个csv文件将所有的患者的基本信息进行打印,方便进行初步筛选。

这样,我们就完成了对的是否患病实现了基本的分类,在后续使用大模型处理时,就可以先对csv中abnormal的患者编号记下来,然后在处理时,对原始的数据,根据编号进行上传处理。

(三)修改建议

这里的思路其实还可以进行优化,可以再一次使用二分类对患者的风险进行评估(也可以使用多分类一次对结果进行分析),结果分为高风险和一般风险,这样,在初步处理时就可以直接确定严重的患者,然后直接通知医生对其进行急救。

但是,由于时间缘故,暂时不能实现,这里仅仅提供一个思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值