SEED数据集实战:从批量读取到情感分类的EEG数据处理流程

SEED数据集实战:从批量读取到情感分类的EEG数据处理流程 1. SEED数据集简介与背景SEED数据集是上海交通大学BCMI实验室发布的情感脑电数据集由吕宝粮教授团队精心打造。这个数据集在脑机接口和情感计算领域被广泛使用特别适合研究情绪识别任务。数据集包含了15名被试者在观看情感诱发视频时的脑电信号记录每位被试者完成了15次实验试次总共产生了225个样本。数据集的文件以.mat格式存储每个文件包含15个试次的EEG数据采样率为200Hz已经过0-75Hz带通滤波和下采样处理。数据采集使用了62个电极覆盖了大脑的各个功能区。标签系统采用三类情感分类积极1、中性0和消极-1。这种标准化的数据格式和明确的标签体系使得SEED成为入门EEG情感识别的理想选择。2. 数据读取与初步探索2.1 单个.mat文件读取读取SEED数据集的第一步是理解.mat文件的结构。我们可以使用Python的scipy.io模块来加载这些MATLAB格式的文件import scipy.io as sio def read_single_file(file_path): data sio.loadmat(file_path) print(f文件包含的键: {data.keys()}) print(f第一个试次数据形状: {data[djc_eeg1].shape}) return data运行这个函数会显示文件包含15个试次数据djc_eeg1到djc_eeg15每个试次是一个62×N的矩阵其中62对应电极数量N是时间点数。值得注意的是不同试次的时间长度可能略有差异这在实际处理时需要特别注意。2.2 数据结构解析深入查看数据维度我们会发现每个试次的EEG数据形状类似(62, 47000)左右。62个电极按照国际10-20系统排列顺序固定。了解电极位置对于后续的特征提取和可视化非常重要。数据已经过预处理可以直接用于分析这大大降低了入门门槛。3. 批量读取与数据整合3.1 批量读取实现处理EEG数据通常需要分析多个被试者的数据因此批量读取功能必不可少。下面是一个高效的批量读取实现import os import mne import numpy as np def batch_read_files(data_dir, max_files3): all_data [] all_labels [] basic_labels [1, 0, -1, -1, 0, 1, -1, 0, 1, 1, 0, -1, 0, 1, -1] file_count 0 for file_name in os.listdir(data_dir): if file_name.endswith(.mat) and file_count max_files: file_path os.path.join(data_dir, file_name) mat_data sio.loadmat(file_path) # 提取所有试次数据 trials [mat_data[fdjc_eeg{i}] for i in range(1, 16)] all_data.extend(trials) all_labels.extend(basic_labels) file_count 1 print(f成功读取{file_count}个文件共{len(all_data)}个试次) return all_data, all_labels这个函数会自动遍历指定目录下的.mat文件提取所有试次数据并添加对应标签。通过max_files参数可以控制读取的文件数量这在调试阶段非常有用。3.2 数据标准化处理虽然SEED数据集已经过预处理但我们仍需要进行一些标准化操作时间对齐由于不同试次长度可能不同我们需要统一截取相同时间长度的数据基线校正去除每个试次的直流偏移归一化对每个通道的数据进行z-score标准化def standardize_data(data_list, target_length4000): standardized [] for trial in data_list: # 统一截取相同长度 trial trial[:, :target_length] # 去除均值 trial trial - np.mean(trial, axis1, keepdimsTrue) # z-score标准化 trial trial / np.std(trial, axis1, keepdimsTrue) standardized.append(trial) return np.array(standardized)4. 特征提取与工程4.1 时域特征提取EEG信号的特征提取是情感分类的关键步骤。常用的时域特征包括均值每个通道的平均电位标准差信号波动程度Hjorth参数活动性和移动性指标def extract_time_features(data): features [] for trial in data: # 计算各通道均值 mean_val np.mean(trial, axis1) # 计算标准差 std_val np.std(trial, axis1) # 组合特征 trial_features np.concatenate([mean_val, std_val]) features.append(trial_features) return np.array(features)4.2 频域特征提取情感状态与特定频段如α波、β波的脑电活动密切相关。我们可以使用快速傅里叶变换(FFT)提取频域特征from scipy import fft def extract_freq_features(data, sfreq200): freq_features [] for trial in data: # 计算FFT psd np.abs(fft(trial, axis1)[:, :trial.shape[1]//2]) # 划分频段 delta np.mean(psd[:, 1:4], axis1) # 1-4Hz theta np.mean(psd[:, 4:8], axis1) # 4-8Hz alpha np.mean(psd[:, 8:13], axis1) # 8-13Hz beta np.mean(psd[:, 13:30], axis1) # 13-30Hz # 组合特征 trial_features np.concatenate([delta, theta, alpha, beta]) freq_features.append(trial_features) return np.array(freq_features)5. 构建情感分类模型5.1 数据准备与划分在构建模型前我们需要将数据划分为训练集和测试集from sklearn.model_selection import train_test_split # 假设X是特征矩阵y是标签 X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy )5.2 机器学习模型选择对于EEG情感分类以下几种模型表现通常较好支持向量机(SVM)适合小样本高维数据随机森林能自动选择重要特征LSTM网络适合处理时序数据这里以SVM为例from sklearn.svm import SVC from sklearn.metrics import accuracy_score # 创建SVM分类器 svm SVC(kernelrbf, C1.0, gammascale) # 训练模型 svm.fit(X_train, y_train) # 评估模型 train_acc accuracy_score(y_train, svm.predict(X_train)) test_acc accuracy_score(y_test, svm.predict(X_test)) print(f训练集准确率: {train_acc:.2f}, 测试集准确率: {test_acc:.2f})5.3 深度学习模型实现对于更复杂的模式识别可以使用深度学习模型。以下是一个简单的1D CNN实现from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Conv1D, MaxPooling1D, Flatten, Dense def build_cnn(input_shape, num_classes): model Sequential([ Conv1D(32, 5, activationrelu, input_shapeinput_shape), MaxPooling1D(2), Conv1D(64, 5, activationrelu), MaxPooling1D(2), Flatten(), Dense(128, activationrelu), Dense(num_classes, activationsoftmax) ]) model.compile(optimizeradam, losssparse_categorical_crossentropy, metrics[accuracy]) return model6. 模型评估与优化6.1 交叉验证策略由于EEG数据个体差异大建议采用留一被试出(Leave-One-Subject-Out)的交叉验证策略from sklearn.model_selection import LeaveOneGroupOut logo LeaveOneGroupOut() for train_idx, test_idx in logo.split(X, y, groupssubject_ids): X_train, X_test X[train_idx], X[test_idx] y_train, y_test y[train_idx], y[test_idx] # 训练和评估模型6.2 特征选择与降维EEG数据维度高可以使用PCA或特征选择方法降低维度from sklearn.decomposition import PCA pca PCA(n_components50) # 保留50个主成分 X_pca pca.fit_transform(X)6.3 超参数调优使用网格搜索寻找最优模型参数from sklearn.model_selection import GridSearchCV param_grid { C: [0.1, 1, 10], gamma: [scale, auto, 0.1, 1], kernel: [rbf, linear] } grid_search GridSearchCV(SVC(), param_grid, cv5) grid_search.fit(X_train, y_train) print(f最佳参数: {grid_search.best_params_})7. 完整流程整合与部署7.1 构建端到端处理流程将上述步骤整合为一个完整的处理流程批量读取.mat文件数据标准化处理特征提取与选择模型训练与评估结果可视化7.2 实用建议与注意事项在实际项目中有几个关键点需要注意数据泄露问题确保预处理和特征提取只在训练数据上进行然后应用到测试数据类别不平衡SEED数据集的标签分布相对均衡但必要时可以使用过采样或加权损失计算效率EEG数据处理计算量大可以考虑使用GPU加速或分布式计算可复现性固定随机种子确保结果可复现我在实际项目中发现将原始数据转换为MNE的Raw对象格式可以方便地利用MNE-Python提供的各种分析工具。此外对于跨被试的情感识别域适应技术可以显著提升模型泛化能力。