当前位置:主页 > python教程 > Python CNN时序数据分类

Python利用CNN实现对时序数据进行分类

发布:2023-03-28 15:25:01 59


给网友朋友们带来一篇相关的编程文章,网友巴哲圣根据主题投稿了本篇教程内容,涉及到Python、CNN时序数据分类、Python、CNN数据分类、Python、CNN、Python CNN时序数据分类相关内容,已被692网友关注,如果对知识点想更进一步了解可以在下方电子资料中获取。

Python CNN时序数据分类

一、数据集介绍

数据集利用的是CPSC2020数据集。

训练数据包括从心律失常患者收集的10个单导联心电图记录,每个记录持续约24小时。

下载完成后的TrainingSet数据集包括两个文件夹,分别是data和ref。data和ref文件夹内分别有10个mat文件。

  • data文件夹存储数据文件,每个文件以mat格式存储,n ∗ 1 n*1n∗1数组表示;
  • ref文件夹为标签文件夹,每个文件以mat文件存储,结构体存储,包括S_ref,V_ref两个n*1数组,分别存储对应标签(S,V)的位置;

采样率为 400。

  • S:室上早搏(SPB);
  • V:心室早搏(PVC);

数据集链接如下:http://2020.icbeb.org/CSPC2020

二、数据预处理

2.1 获取原始数据

查看一下前1000个心电图数据:

datafile = 'E:/Wendy/Desktop/TrainingSet/data/A04.mat'# 采样率400
data = scio.loadmat(datafile)
#rint(data) # dict

sig = data['ecg']# (x,1)
#print(sig)
sig = np.reshape(sig,(-1)) # (x,)转换为一维向量
print(sig)
sigPlot = sig[1:5*200]# # 获取前1000个信号
fig = plt.figure(figsize=(20, 10),dpi=400)
plt.plot(sigPlot)
plt.show()

运行结果:

2.2 获取原始标签

将标签数据转化为一维向量

datafile = 'E:/Wendy/Desktop/TrainingSet/ref/R04.mat'# 采样率400
data = scio.loadmat(datafile)
#print(data)
label = data['ref'][0][0]
S_ref = label[0];
S_ref = np.reshape(S_ref,(-1)) # 转换为一维向量
V_ref = label[1];
V_ref = np.reshape(V_ref,(-1)) # 转换为一维向量

2.3 数据分割

数据分割为5s一个片段

思路:房早室早心拍和前后两个心拍均有关系,按照平均心率72计算,平均每个心拍的时间为60/72,因此5个心拍的时间为60/725=4.1667 4.1667s不好计算,故选择5s 5 ( 秒 ) s a m p r = 5 ∗ 400 = 2000 个 s a m p l e 5(秒)sampr = 5*400=2000个sample5(秒)sampr=5∗400=2000个sample

定义标签:0:其他;1:V_ref; 2:S_ref;

a = len(sig)
Fs = 400 # 采样率为400
segLen = 5*Fs # 2000
num = int(a/segLen)
print(num)

运行结果:

17650

其中Fs为采样率,segLen为片段长度,num为片段数量。

2.4 整合数据和标签

接下来需要整合数据和标签:

all_data=[]
all_label = [];
i=1
while i

运行结果:

(17650, 2000)
(17650,)

17650为数据长度,2000为数据个数。

2.5 保存

将数据保存为字典类型:

import pickle
res = {'data':all_data, 'label':all_label} # 字典类型dict
with open('./cpsc2020.pkl', 'wb') as fout: # #将结果保存为cpsc2020.pkl
    pickle.dump(res, fout)

三、数据训练

3.1 读取数据并进行处理

将数据归一化并进行标签编码,划分训练集和测试集,训练集为90%,测试集为10%,打乱数据并将其扩展为二维:

import numpy as np
import pandas as pd
import scipy.io
from matplotlib import pyplot as plt
import pickle
from sklearn.model_selection import train_test_split
from collections import Counter
from tqdm import tqdm

def read_data_physionet():
    """
    only N V, S
    """
    # read pkl
    with open('./cpsc2020.pkl', 'rb') as fin:
        res = pickle.load(fin) # 加载数据集
    ## 数据归一化
    all_data = res['data']
    for i in range(len(all_data)):
        tmp_data = all_data[i]
        tmp_std = np.std(tmp_data) # 获取数据标准差
        tmp_mean = np.mean(tmp_data) # 获取数据均值
        if(tmp_std==0):   # i=1239-1271均为0
            tmp_std = 1 
        all_data[i] = (tmp_data - tmp_mean) / tmp_std  # 归一化
    all_data = []
    ## 标签编码
    all_label = []
    for i in range(len(res['label'])):
        if res['label'][i] == 1:
            all_label.append(1)
            all_data.append(res['data'][i])
        elif res['label'][i] == 2:
            all_label.append(2)
            all_data.append(res['data'][i])
        else:
            all_label.append(0)
            all_data.append(res['data'][i])       
    all_label = np.array(all_label)
    all_data = np.array(all_data)

    # 划分训练集和测试集,训练集90%,测试集10%
    X_train, X_test, Y_train, Y_test = train_test_split(all_data, all_label, test_size=0.1, random_state=15)
    
 
    print('训练集和测试集中 其他类别(0);室早(1);房早(2)的数量: ')
    print(Counter(Y_train), Counter(Y_test))
    
    # 打乱训练集
    shuffle_pid = np.random.permutation(Y_train.shape[0])
    X_train = X_train[shuffle_pid]
    Y_train = Y_train[shuffle_pid]

    # 扩展为二维(x,1)
    X_train = np.expand_dims(X_train, 1)
    X_test = np.expand_dims(X_test, 1)

    return X_train, X_test, Y_train, Y_test
X_train, X_test, Y_train, Y_test = read_data_physionet()

运行结果:

训练集和测试集中 其他类别(0);室早(1);房早(2)的数量:
Counter({1: 8741, 0: 4605, 2: 2539}) Counter({1: 1012, 0: 478, 2: 275})

3.2 构建数据结构

自行构建数据集:

# 构建数据结构 MyDataset
# 单条数据信号的形状为:1*2000
import numpy as np
from collections import Counter
from tqdm import tqdm
from matplotlib import pyplot as plt
from sklearn.metrics import classification_report 

import torch
import torch.nn as nn
import torch.optim as optim
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader

class MyDataset(Dataset):
    def __init__(self, data, label):
        self.data = data
        self.label = label
    #把numpy转换为Tensor
    def __getitem__(self, index):
        return (torch.tensor(self.data[index], dtype=torch.float), torch.tensor(self.label[index], dtype=torch.long))

    def __len__(self):
        return len(self.data)

3.3 搭建神经网络

搭建CNN网络结构:

# 搭建神经网络
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.conv1 = nn.Sequential(         # input shape (1, 1, 2000)
            nn.Conv1d(
                in_channels=1,
                out_channels=16,
                kernel_size=5,
                stride=1, 
                padding=2,
            ),                              # output shape (16, 1, 2000)
            nn.Dropout(0.2),
            nn.ReLU(),
            nn.MaxPool1d(kernel_size=5),    # choose max value in 1x5 area, output shape (16, 1, 400)2000/5
        )
        self.conv2 = nn.Sequential(         # input shape (16, 1, 400)
            nn.Conv1d(16, 32, 5, 1, 2),     # output shape (32, 1, 400)
            nn.Dropout(0.2),
            nn.ReLU(),
            nn.MaxPool1d(kernel_size=5),    # output shape (32, 1, 400/5=80)
        )
        self.out = nn.Linear(32 *  80, 3)   # fully connected layer, output 3 classes

    def forward(self, x):
        x = self.conv1(x)
        x = self.conv2(x)
        x = x.view(x.size(0), -1)
        output = self.out(x)
        #output.Softmax()
        return output, x
cnn = CNN()
print(cnn)

运行结果:

CNN(
(conv1): Sequential(
(0): Conv1d(1, 16, kernel_size=(5,), stride=(1,), padding=(2,))
(1): Dropout(p=0.2, inplace=False)
(2): ReLU()
(3): MaxPool1d(kernel_size=5, stride=5, padding=0, dilation=1, ceil_mode=False)
)
(conv2): Sequential(
(0): Conv1d(16, 32, kernel_size=(5,), stride=(1,), padding=(2,))
(1): Dropout(p=0.2, inplace=False)
(2): ReLU()
(3): MaxPool1d(kernel_size=5, stride=5, padding=0, dilation=1, ceil_mode=False)
)
(out): Linear(in_features=2560, out_features=3, bias=True)
)

3.4 开始训练

优化器利用的是Adam优化器,损失函数使用crossEntropy函数。

代码略

50个epoch的运行效果如下:

以上就是Python利用CNN实现对时序数据进行分类的详细内容,更多关于Python CNN时序数据分类的资料请关注码农之家其它相关文章!


参考资料

相关文章

  • 最新python 字符串数组互转问题

    发布:2023-03-26

    这篇文章主要介绍了最新python 字符串数组互转问题,主要介绍了字符串转list数组问题和list数组转字符串问题,本文结合示例代码给大家介绍的非常详细,需要的朋友可以参考下


  • 拓扑排序Python实现的过程

    发布:2023-04-24

    这篇文章主要介绍了拓扑排序Python实现的过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教


  • Python爬虫解析方法和爬虫实现过程总结

    发布:2019-06-05

    本文想针对某一网页对 python 基础爬虫的两大解析库( BeautifulSoup 和 lxml )和几种信息提取实现方法进行分析,及同一网页爬虫的四种实现方式,需要的朋友参考下吧


  • Python实现PDF转Word的方法详解

    发布:2023-04-07

    由于PDF的文件大多都是只读文件,有时候为了满足可以编辑的需要通常可以将PDF文件直接转换成Word文件进行操作。本文为大家整理了一些实现方法,希望对大家有所帮助


  • 基于Python递归函数实现二分查找算法

    发布:2020-01-23

    这篇文章主要介绍了Python递归函数 二分查找算法实现解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下


  • Python3.6及TensorFlow的安装和配置流程(图解)

    发布:2018-09-19

    这篇文章主要为大家详细介绍了python3.6.3及TensorFlow安装配置方法图文教程,具有一定的参考价值,感兴趣的读者们可以参考一下


  • 一文带你了解Python中的type,isinstance和issubclass

    发布:2023-04-29

    这篇文章主要为大家详细介绍了Python中的type、isinstance和issubclass的使用,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下


  • python中argparse模块及action='store_true'详解

    发布:2023-04-14

    argparse 是一个用来解析命令行参数的 Python 库,它是 Python 标准库的一部分,这篇文章主要介绍了python中argparse模块及action=‘store_true‘详解,需要的朋友可以参考下


网友讨论