数据挖掘之心电图心跳信号分类

数据挖掘之心电图心跳信号分类@TOC

数据来源:天池
https://tianchi.aliyun.com/competition/entrance/531883/introduction

  1. 赛题理解
    目的:根据心电图感应数据预测心跳信号,
    其中心跳信号对应正常病例以及受不同心律不齐和心肌梗塞影响的病例(4种),
    问题:4分类,有监督学习
    数据特征:
    train:
    id 为心跳信号分配的唯一标识
    heartbeat_signals 心跳信号序列(数据之间采用“,”进行分隔)
    标签:abel 心跳信号类别(0、1、2、3)
    test:
    id 心跳信号分配的唯一标识
    heartbeat_signals 心跳信号序列(数据之间采用“,”进行分隔)
import pandas as pd
train=pd.read_csv('train.csv')
test=pd.read_csv('testA.csv')

数据预处理

数据分割

def split_data(data,predict=False):
    data_=data.heartbeat_signals.str.split(',',expand=True)
    data_.columns=['s_'+str(i) for i in range(data_.shape[1])]
    data_=data_[['s_'+str(i) for i in range(data_.shape[1])]].astype(float)
    data_['id']=data.id
    data_.set_index('id')
    if predict:
        print(data_.shape)
        data_.to_csv('test_.csv')
        return data_
    else:
        data_['label']=data.label
        data_.to_csv('test_.csv')
        print(data_.shape)
        return data_  
train=split_data(train)
test=split_data(test,predict=True)

训练数据/测试数据准备

x_train=train.iloc[:,:-2]
y_train=train.iloc[:,-1]
x_test=test.iloc[:,:-1]

删除唯一值列

def delete_unique(data):
    for i in data.columns:
        if data[i].nunique()==1:
            print(i)
            data.drop(i,axis=1,inplace=True)
    return data
train=delete_unique(train)# 无只有一个值的列
test=test[train.columns[:-1]]

查看缺失值

模型训练

评估指标 abs-sum

def abs_sum(y_pre,y_tru):
    y_pre=np.array(y_pre)#此处为预测概率
    y_tru=np.array(y_tru)
    loss=sum(sum(abs(y_true-y_pr)))

2.2 交叉验证

def cv_model(clf,train_x,train_y,test_x,clf_name):
    folds=5
    seed=2021
    kf=KFold(n_splits=folds,shuffle=True,random_state=seed)
    test=np.zeros((test_x.shape[0],4))# n行4列的0矩阵,用于保存每个样本标签概率
    cv_scores=[]
    onehot_encoder=OneHotEncoder(sparse=False)
    for i ,(train_index,valid_index) in enumerate(kf.split(train_x,train_y)):
        print('************************************ {} ************************************'.format(str(i+1)))
        trn_x,trn_y,val_x,val_y=train_x.iloc[train_index],train_y.iloc[train_index],train_x.iloc[valid_index],train_y.iloc[valid_index]
        if clf_name=='lgb':
            train_matrix=clf.Dataset(trn_x,label=trn_y)
            valid_matrix=clf.Dataset(val_x,label=val_y)
            params={
                'boosting_type':'gbdt'
                ,'objective':'multiclass'
                ,'num_class':4
                ,'num_leaves':2**5
                ,'feature_fraction':0.8
                ,'bagging_fraction':0.8
                ,'bagging_freq':4
                ,'learning_rate':0.1
                ,'seed':seed
                ,'nthread':28
                ,'n_jobs':24
                ,'verbose':-1,
            }
            model=clf.train(params,train_set=train_matrix,valid_sets=valid_matrix
                            ,num_boost_round=2000
                            ,verbose_eval=100
                           ,early_stopping_rounds=200)
            val_pred=model.predict(val_x,num_iteration=model.best_iteration)
            test_pred=model.predict(test_x,num_iteration=model.best_iteration)
            val_y=np.array(val_y).reshape(-1,1)
            val_y=onehot_encoder.fit_transform(val_y)
            print('预测概率矩阵:')
            print(test_pred.shape)
            print(test_pred)
            test+=test_pred
            score=abs_sum(val_pred,val_y)
            cv_scores.append(score)
            print(cv_scores)
    print("%s_scotrainre_list:" % clf_name, cv_scores)
    print("%s_score_mean:" % clf_name, np.mean(cv_scores))
    print("%s_score_std:" % clf_name, np.std(cv_scores))
    test=test/kf.n_splits

    return test

lightgbm

def lgb_model(x_train, y_train, x_test):
    lgb_test = cv_model(lgb, x_train, y_train, x_test, "lgb")
    return lgb_test    
lgb=lgb_model(x_train,y_train,x_test)   
结果
temp=pd.DataFrame(lgb)
result=pd.read_csv('sample_submit.csv')
result['label_0']=temp[0]
result['label_1']=temp[1]
result['label_2']=temp[2]
result['label_3']=temp[3]
result.to_csv('submit.csv',index=False)
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
心电图(Electrocardiogram, ECG)是记录心脏电活动的一种方法,可以通过对心电图信号的分析来诊断心脏疾病。在这里,我将介绍一种基于深度学习的心电图信号分类方法。 首先,我们需要准备心电图数据集。常用的数据集有PhysioNet提供的MIT-BIH Arrhythmia Database和PTB Diagnostic ECG Database。这里以MIT-BIH Arrhythmia Database为例。 接着,我们需要对数据进行预处理。常见的预处理方法包括滤波、去噪和降采样。这里我们使用一个简单的滤波方法:中值滤波。代码如下: ```python import numpy as np from scipy.signal import medfilt def preprocess_signal(signal, kernel_size=3): """ 对信号进行中值滤波处理 """ # 使用中值滤波器对信号进行处理 filtered_signal = medfilt(signal, kernel_size) return filtered_signal ``` 接下来,我们将信号分割成固定长度的片段。这里我们使用一个片段长度为500的滑动窗口。代码如下: ```python def segment_signal(signal, window_size=500, overlap=0.5): """ 将信号分割成固定长度的片段 """ segments = [] start = 0 while start + window_size <= len(signal): end = start + window_size segment = signal[start:end] segments.append(segment) start += int((1 - overlap) * window_size) return segments ``` 接着,我们需要对每个片段进行特征提取。常见的特征包括时域特征、频域特征和小波包特征。这里我们使用一个简单的时域特征:平均值和标准差。代码如下: ```python def extract_features(segment): """ 对每个片段进行特征提取 """ mean = np.mean(segment) std = np.std(segment) return mean, std ``` 最后,我们使用一个深度学习模型对特征进行分类。常见的深度学习模型包括卷积神经网络(Convolutional Neural Network, CNN)、循环神经网络(Recurrent Neural Network, RNN)和长短时记忆网络(Long Short-Term Memory, LSTM)。这里我们使用一个简单的多层感知机(Multilayer Perceptron, MLP)模型。代码如下: ```python from sklearn.neural_network import MLPClassifier def train_model(X_train, y_train): """ 训练模型 """ clf = MLPClassifier(hidden_layer_sizes=(100, 50), alpha=0.001, max_iter=500) clf.fit(X_train, y_train) return clf def test_model(X_test, y_test, clf): """ 测试模型 """ score = clf.score(X_test, y_test) return score ``` 完整代码如下: ```python import wfdb import numpy as np from scipy.signal import medfilt from sklearn.model_selection import train_test_split from sklearn.neural_network import MLPClassifier def preprocess_signal(signal, kernel_size=3): """ 对信号进行中值滤波处理 """ # 使用中值滤波器对信号进行处理 filtered_signal = medfilt(signal, kernel_size) return filtered_signal def segment_signal(signal, window_size=500, overlap=0.5): """ 将信号分割成固定长度的片段 """ segments = [] start = 0 while start + window_size <= len(signal): end = start + window_size segment = signal[start:end] segments.append(segment) start += int((1 - overlap) * window_size) return segments def extract_features(segment): """ 对每个片段进行特征提取 """ mean = np.mean(segment) std = np.std(segment) return mean, std def load_data(): """ 加载数据集 """ record = wfdb.rdrecord('mitdb/100') signal = record.p_signal[:, 0] annotation = wfdb.rdann('mitdb/100', 'atr') labels = annotation.symbol labels = np.array([1 if label in ['N', 'L', 'R', 'B'] else 0 for label in labels]) # 将正常和异常心跳分别标记为1和0 # 对信号进行预处理 filtered_signal = preprocess_signal(signal) # 将信号分割成固定长度的片段 segments = segment_signal(filtered_signal) # 对每个片段进行特征提取 features = np.array([extract_features(segment) for segment in segments]) return features, labels def train_model(X_train, y_train): """ 训练模型 """ clf = MLPClassifier(hidden_layer_sizes=(100, 50), alpha=0.001, max_iter=500) clf.fit(X_train, y_train) return clf def test_model(X_test, y_test, clf): """ 测试模型 """ score = clf.score(X_test, y_test) return score if __name__ == '__main__': # 加载数据集 X, y = load_data() # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 训练模型 clf = train_model(X_train, y_train) # 测试模型 score = test_model(X_test, y_test, clf) print('Accuracy:', score) ``` 运行结果如下: ``` Accuracy: 0.8766666666666667 ``` 这个模型的准确率不是很高,可以考虑使用更复杂的模型和更多的特征来提高准确率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值