MATLAB实战:手把手教你从SEED原始.mat文件到情绪分类数据集(附代码) MATLAB实战从SEED原始.mat文件构建情绪分类数据集的完整指南在脑电信号分析领域SEED数据集因其规范性和丰富的情绪标签而广受欢迎。但对于刚接触该数据集的研究者来说面对原始的.mat文件和复杂的嵌套结构往往会感到无从下手。本文将提供一个完整的MATLAB处理流程帮助您高效地从原始数据构建标准的情绪分类数据集。1. 准备工作与环境配置在开始处理数据之前我们需要确保MATLAB环境配置正确。推荐使用MATLAB R2018b或更高版本这些版本对.mat文件的处理更加稳定。首先检查您的MATLAB是否安装了必要的工具箱ver % 查看已安装的工具箱确保以下工具箱已安装Signal Processing ToolboxStatistics and Machine Learning Toolbox接下来设置工作路径projectPath 您的项目路径; addpath(genpath(projectPath)); % 添加项目路径和子文件夹2. 理解SEED数据集结构SEED数据集采用了一种特殊的嵌套结构理解这种结构是数据处理的关键。每个原始.mat文件如1_20131027.mat包含15个子结构对应15个电影片段的脑电信号。典型的文件结构如下1_20131027.mat ├── djc_eeg1 (结构体) │ ├── data (62×N double) % 62通道的脑电数据 │ ├── label (1×N double) % 时间点标签 │ └── ...其他元数据 ├── djc_eeg2 ├── ... └── djc_eeg15情绪标签映射关系来自China_information情绪类型对应片段编号标签值积极情绪1,6,9,10,141消极情绪3,4,7,12,15-1中性情绪2,5,8,11,1303. 数据加载与预处理3.1 安全加载.mat文件MATLAB的load函数在处理大型.mat文件时可能会遇到内存问题。我们采用更安全的方式加载数据function data safeLoadMat(filePath) try data load(filePath, -mat); catch ME warning(加载文件 %s 时出错: %s, filePath, ME.message); data []; end end3.2 提取指定时长的数据根据研究需求我们通常提取每个片段的前180秒3分钟数据function segment extractSegment(eegStruct, durationSec, sampleRate) % eegStruct: 输入的EEG结构体 % durationSec: 要提取的时长秒 % sampleRate: 采样率SEED数据集为200Hz samplesToExtract durationSec * sampleRate; if size(eegStruct.data, 2) samplesToExtract warning(数据长度不足 %d 秒实际长度 %.1f 秒,... durationSec, size(eegStruct.data,2)/sampleRate); samplesToExtract size(eegStruct.data, 2); end segment.data eegStruct.data(:, 1:samplesToExtract); segment.label eegStruct.label(1:samplesToExtract); end4. 按情绪类型分类与合并4.1 情绪分类函数创建一个函数根据片段编号自动判断情绪类型function emotionType getEmotionType(segmentNum) positiveSegments [1,6,9,10,14]; negativeSegments [3,4,7,12,15]; if ismember(segmentNum, positiveSegments) emotionType happy; elseif ismember(segmentNum, negativeSegments) emotionType sad; else emotionType neutral; end end4.2 主处理流程以下是完整的处理脚本将单个被试的数据按情绪分类function processSubjectData(filePath, outputDir) % 加载原始文件 rawData safeLoadMat(filePath); if isempty(rawData) error(无法加载文件: %s, filePath); end % 初始化情绪数据结构 emotionData struct(); emotionData.happy []; emotionData.sad []; emotionData.neutral []; % 获取所有片段名称 segmentNames fieldnames(rawData); segmentNames segmentNames(~strcmp(segmentNames, China_information)); % 处理每个片段 for i 1:length(segmentNames) segName segmentNames{i}; segNum str2double(segName(end-1:end)); % 提取片段编号 % 提取180秒数据 segment extractSegment(rawData.(segName), 180, 200); % 按情绪分类 emotionType getEmotionType(segNum); if isempty(emotionData.(emotionType)) emotionData.(emotionType) segment.data; else emotionData.(emotionType) [emotionData.(emotionType), segment.data]; end end % 保存结果 [~, subjectName] fileparts(filePath); save(fullfile(outputDir, [subjectName _emotion.mat]), emotionData); end5. 多被试数据整合与最终数据集生成5.1 批量处理多个被试function batchProcessSEED(dataDir, outputDir) % 确保输出目录存在 if ~exist(outputDir, dir) mkdir(outputDir); end % 获取所有.mat文件 matFiles dir(fullfile(dataDir, *.mat)); % 初始化最终数据集 finalDataset struct(); finalDataset.happy []; finalDataset.sad []; finalDataset.neutral []; % 处理每个文件 for i 1:length(matFiles) filePath fullfile(matFiles(i).folder, matFiles(i).name); fprintf(正在处理: %s\n, matFiles(i).name); % 处理单个被试 processSubjectData(filePath, outputDir); % 加载处理后的情绪数据并整合 [~, name] fileparts(matFiles(i).name); emotionFile fullfile(outputDir, [name _emotion.mat]); if exist(emotionFile, file) loaded load(emotionFile); finalDataset.happy [finalDataset.happy; loaded.emotionData.happy]; finalDataset.sad [finalDataset.sad; loaded.emotionData.sad]; finalDataset.neutral [finalDataset.neutral; loaded.emotionData.neutral]; end end % 保存最终数据集 save(fullfile(outputDir, SEED_Emotion_Dataset.mat), finalDataset); end5.2 数据质量检查在完成数据集构建后建议进行以下检查数据维度验证fprintf(Happy数据维度: %d×%d\n, size(finalDataset.happy,1), size(finalDataset.happy,2)); fprintf(Sad数据维度: %d×%d\n, size(finalDataset.sad,1), size(finalDataset.sad,2)); fprintf(Neutral数据维度: %d×%d\n, size(finalDataset.neutral,1), size(finalDataset.neutral,2));标签分布检查happyLabels sum(finalDataset.happy(:) 1); sadLabels sum(finalDataset.sad(:) -1); neutralLabels sum(finalDataset.neutral(:) 0); fprintf(标签分布 - 积极: %d, 消极: %d, 中性: %d\n, happyLabels, sadLabels, neutralLabels);6. 常见问题与解决方案6.1 内存不足问题处理大型.mat文件时可能遇到内存错误。解决方法使用matfile函数进行部分加载m matfile(largeFile.mat); partialData m.data(1:1000, :); % 只加载部分数据增加Java堆内存% 在MATLAB启动时添加参数 -nojvm -nosplash -nodesktop -maxHeapSize 4G6.2 数据对齐问题不同片段的采样点数可能略有差异建议统一截取最小长度minSamples min([size(happyData,2), size(sadData,2), size(neutralData,2)]); happyData happyData(:, 1:minSamples); sadData sadData(:, 1:minSamples); neutralData neutralData(:, 1:minSamples);6.3 文件路径问题跨平台使用时注意路径分隔符差异if ispc sep \; else sep /; end filePath [folderPath sep fileName];7. 进阶处理建议数据标准化% 对每个通道进行Z-score标准化 happyDataNorm zscore(happyData, 0, 2); sadDataNorm zscore(sadData, 0, 2); neutralDataNorm zscore(neutralData, 0, 2);时频分析预处理% 使用短时傅里叶变换提取时频特征 function [tfPower] computeTFR(eegData, fs) window hann(256); noverlap 128; nfft 512; [~,F,T,P] spectrogram(eegData, window, noverlap, nfft, fs); tfPower 10*log10(P); end跨被试数据平衡% 确保每个被试的数据贡献均衡 subjects {subj1, subj2, ..., subj15}; minContribution min(arrayfun((s) size(s.happy,2), allSubjectData)); balancedHappy cell2mat(arrayfun((s) s.happy(:,1:minContribution),... allSubjectData, UniformOutput, false));