EEG代码实践:SEED数据集解读与批量读取

2023/8/10 -  脑机接口学习内容一览:

        本文主要针对上海交通大学的SJTU(SEED)数据集进行检查和整合,旨在之后通过更加标准流程的实现分类。


数据集介绍

数据集背景

        SJTU 情感脑电数据集(SEED)是由BCMI实验室提供的EEG数据集的集合,该实验室由吕宝粮教授领导 。

数据集详情与情况展示

        图1 文件夹详情

        数据集文件夹情况如上图所示,Preprocessed_EEG中存放我们使用的数据集文件(.mat格式),不用python专门格式当然是因为我没有,而且对mat数据集的处理其实也没什么很大的区别。该子文件夹中的情况如下所示(除了数据集之外包括一个readme.txt以及一个label.mat文件):

 图2 Preprocessed_EEG文件夹情况

        这里读取第一个文件,查看数据集情况,读取代码和结果如下:

import mne
import scipy.io as sio


def read_one_file(path, file_name):
    # 读取单个.mat文件
    data = sio.loadmat(path + file_name)
    print(data.keys())
    print(data['djc_eeg1'].shape)
    print(data['djc_eeg1'])


read_one_file("Preprocessed_EEG/", "dujingcheng_20131027.mat")

        该代码读取到一个包含以下keys的字典:

 dict_keys(['__header__', '__version__', '__globals__', 'djc_eeg1', 'djc_eeg2', 'djc_eeg3', 'djc_eeg4', 'djc_eeg5', 'djc_eeg6', 'djc_eeg7', 'djc_eeg8', 'djc_eeg9', 'djc_eeg10', 'djc_eeg11', 'djc_eeg12', 'djc_eeg13', 'djc_eeg14', 'djc_eeg15'])

        选取前两个'djc_eeg'打印shape得到如下结果:

djc_eeg1.shape is  (62, 47001)
djc_eeg2.shape is  (62, 46601)

        由此得到数据集的基本情况,每个文件应该都包括15个试次 ,每个试次包括62个通道的数据以及一定数量的数据点。根据官方文件通道数据的排列顺序如下所示:

FP1 FPZ FP2 AF3 AF4 F7 F5 F3 F1 FZ F2 F4 F6 F8 FT7 FC5 FC3 FC1 FCZ FC2 FC4 FC6 FT8 T7 C5 C3 C1 CZ C2 C4 C6 T8 TP7 CP5 CP3 CP1 CPZ CP2 CP4 CP6 TP8 P7 P5 P3 P1 PZ P2 P4 P6 P8 PO7 PO5 PO3 POZ PO4 PO6 PO8 CB1 O1 OZ O2 CB2

        Preprocessed_EEG文件夹中还包含一个label.mat文件,上图未截出。因为前文读取的数据明显缺少标签。打印label.mat数据得到标签信息如下:

{'__header__': b'MATLAB 5.0 MAT-file, Platform: PCWIN64, Created on: Sat Apr 18 22:14:56 2015', '__version__': '1.0', '__globals__': [], 'label': array([[ 1,  0, -1, -1,  0,  1, -1,  0,  1,  1,  0, -1,  0,  1, -1]], dtype=int16)}

         由此可得所有mat文件的数据标签都是统一的,每份文件的15个试次分别对应以下标签[ 1,  0, -1, -1,  0,  1, -1,  0,  1,  1,  0, -1,  0,  1, -1],其中-1表示消极,0表示中立,+ 1表示积极。

预处理

        该数据集已经经过了官方的预处理,理论上可以直接使用。

        官方采用的预处理操作如下:

        1.数据下采样到200hz;

        2.0-75hz的带通滤波;

        以上即为本文对该数据集详情的解释。


附录

        批量读取数据的代码如下,方便之后增加特征提取和分类部分。

        批量读取速度较慢,这里只读取了前三个文件,通过调整函数中的max_files_num参数可改变读取文件个数(上限为45个文件),默认只读取第一个文件。

import mne
import scipy.io as sio
import os

# 超参数
# 通道名顺序
ch_names = ['FP1', 'FPZ', 'FP2', 'AF3', 'AF4', 'F7', 'F5', 'F3', 'F1',
            'FZ', 'F2', 'F4', 'F6', 'F8', 'FT7', 'FC5', 'FC3', 'FC1',
            'FCZ', 'FC2', 'FC4', 'FC6', 'FT8', 'T7', 'C5', 'C3', 'C1',
            'CZ', 'C2', 'C4', 'C6', 'T8', 'TP7', 'CP5', 'CP3', 'CP1',
            'CPZ', 'CP2', 'CP4', 'CP6', 'TP8', 'P7', 'P5', 'P3', 'P1',
            'PZ', 'P2', 'P4', 'P6', 'P8', 'PO7', 'PO5', 'PO3', 'POZ',
            'PO4', 'PO6', 'PO8', 'CB1', 'O1', 'OZ', 'O2', 'CB2']
# 采样频率
sfreq = 200
# 每个.mat文件中的数据label
basic_label = [1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 0, 1, -1]


def read_one_file(file_path):
    """
    input:单个.mat文件路径
    output:raw格式数据
    """
    data = sio.loadmat(file_path)
    # 获取keys并转化为list,获取数据所在key
    keys = list(data.keys())[3:]
    # print(keys)
    # 获取数据
    raw_list = []
    for i in range(len(keys)):
        # 获取数据
        stamp = data[keys[i]]
        # print(stamp.shape)
        # 创建info
        info = mne.create_info(ch_names=ch_names, sfreq=sfreq, ch_types='eeg')
        # 创建raw,取第5秒开始的数据
        raw = mne.io.RawArray(stamp, info).crop(tmin=5)
        # 添加到raw_list
        raw_list.append(raw)
    return raw_list


def read_all_files(path, max_files_num=1):
    # 读取文件夹下所有.mat文件
    print("read_all_files start...")
    # 遍历Preprocessed_EEG文件夹下所有.mat文件
    data_list = []
    # 读取文件数量(每个文件中有15段数据)
    files_num = 0
    for root, dirs, files in os.walk(path):
        for file in files:
            if os.path.splitext(file)[1] == '.mat':
                file_path = os.path.join(root, file)
                raw_list = read_one_file(file_path)
                # 将raw_list中的每一个元素添加到data_list
                data_list.extend(raw_list)
                files_num += 1
                if files_num == max_files_num:
                    break

    # 生成所有数据的label(每个文件中有15段数据,每段数据的label相同)
    label_list = []
    for i in range(int(files_num)):
        label_list.extend(basic_label)
    # 将label_list添加到data_list
    print("共读取了{}个文件".format(files_num))
    print("共有{}段数据".format(len(data_list)))
    print("read ended...")
    return data_list, label_list


# read_all_files("Preprocessed_EEG/", 1)

UPDATE

2023/08/12

在代码中优化了了max_files_num的使用,从超参数改为函数中的参数。

### SEED 数据集预处理方法教程 #### 加载必要的工具包 为了对 SEED 数据集进行有效的预处理,需要加载一系列 MATLAB 工具箱来辅助操作。这些工具箱通常包括信号处理工具箱 (Signal Processing Toolbox),用于执行滤波和其他频域分析。 ```matlab % Load necessary toolboxes and initialize environment settings. addpath('toolbox'); % Add custom or required toolbox paths here ``` #### 导入原始 EEG 文件 SEED 数据集中的 `Preprocessed_EEG` 文件夹包含了多个 `.mat` 格式的文件,每个文件代表一次实验记录的数据集合。对于特定的文件如 `1_20131027.mat`,可以利用 MATLAB 的 `load()` 函数将其导入到工作空间中[^1]。 ```matlab filename = 'data/Preprocessed_EEG/1_20131027.mat'; eegData = load(filename); disp(eegData); % Display loaded data structure to understand its components ``` #### 提取并清理数据 一旦成功读取了 .mat 文件的内容,下一步就是提取有用的 EEG 通道信息,并去除任何不必要的变量或噪声干扰。这可能涉及到选择特定电极位置对应的列向量以及应用带通滤波器以消除工频干扰和肌肉活动带来的影响[^2]。 ```matlab % Assuming eegData contains a field named 'EEG' which holds the actual signal matrix signalMatrix = eegData.EEG; % Apply band-pass filter between 1-45 Hz using butterworth filter design method [b,a]=butter(4,[1/(250/2),45/(250/2)],'bandpass'); filteredSignals = filtfilt(b, a, signalMatrix); % Remove mean from each channel for better normalization later on detrendedSignals = detrend(filteredSignals,'constant'); ``` #### 特征工程标注转换 完成基本的去噪和平滑化之后,可以根据研究目的进一步构建特征表示形式。例如,在情绪识别任务里,可能会计算功率谱密度(Power Spectral Density)作为输入给分类模型的关键属性之一。同时也要注意将原本的时间序列标签映射成适合机器学习算法使用的类别编码。 ```matlab % Calculate PSD across all channels as an example of feature extraction fs = 250; % Sampling frequency is typically set at 250Hz according to documentation windowSize = round(fs*2); % Window size could be defined based on domain knowledge overlapRatio = 0.5; nfft = nextpow2(windowSize); psdFeatures = []; for i=1:size(detrendedSignals,1) [pxx,freqs] = pwelch(detrendedSignals(i,:),hamming(windowSize),... overlapRatio*nfft,nfft,fs); psdFeatures = cat(1,psdFeatures,mean(pxx)); end % Convert original labels into numeric class indices if not already done so if ~isnumeric(labels) uniqueLabels = unique(labels); [~,~,labelIdx] = intersect(uniqueLabels,labels); else labelIdx = double(labels)-min(double(labels))+1; end ``` #### 存储预处理后的结果 最后一步是保存经过上述流程得到的新版本数据集,以便后续建模阶段可以直接调用而无需重复相同的准备工作。可以选择再次存储为 .mat 文件或者其他更通用的数据交换格式比如 CSV 或 HDF5 等。 ```matlab outputFilename = fullfile(outputDir,['preprocessed_',basename]); save(outputFilename,'psdFeatures','labelIdx','-v7.3'); % Save with v7.3 format ensures compatibility ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值