ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

脑电数据分析利器:EEGLAB从预处理到ERP/频谱/时频分析实战指南

脑电数据分析利器:EEGLAB从预处理到ERP/频谱/时频分析实战指南 EEGLAB我从研究生阶段一直用到现在中间换过好几个数据处理工具最后还是老老实实回到它上面。这个工具箱确实不是最漂亮的那个上手也有点门槛但它把脑电数据分析从头到尾的环节都串起来了网上随时能搜到教程遇到报错基本都有前人踩过坑。这篇就按我自己实际使用的路线从头梳理一遍EEGLAB的完整用法从安装配置到预处理、批处理脚本再到时域频域时频三大分析方向最后附上常见问题的排查记录。如果你正在被脑电数据折磨或者刚装上EEGLAB不知道从哪下手这篇应该能给你省不少时间。1. 先用一句话说清楚EEGLAB是干什么的EEGLAB是一个运行在MATLAB环境下的开源工具箱专门用来处理脑电图和脑磁图数据。它能做的事情从数据导入开始一路覆盖到滤波去噪、去除眼动伪迹、坏导坏段剔除、ICA独立成分分析、ERP波形提取、频谱分析、时频分析最后连出图导结果都能一起搞定。简单说从原始脑电数据到论文里的图中间这套流程它基本全包了。为什么在众多工具里我始终绕不开它因为它的生态太成熟了。EEGLAB背后是Swartz计算神经科学中心从1997年发布到现在维护了二十多年学界用得极广配套插件超过几十个大部分先进的处理方法都会第一时间出EEGLAB插件版本。你在文献里看到某个新的去噪算法多半能在这里找到实现。对你来说这意味着什么意味着遇到问题能搜到大量解决方案意味着大部分审稿人认这套流程意味着你的数据处理可以复现、可以审计。适合谁用自然是想认真分析脑电数据的研究生、工程师和科研人员。EEGLAB适合从零开始系统学习的人也适合只需要调用某个模块做单步处理的老人。你不需要是MATLAB高手但至少要会基础的脚本编写。如果你连MATLAB都没打开过建议先花几天把MATLAB的基础语法熟悉一遍再来碰EEGLAB否则容易被劝退。我自己的使用场景比较典型做认知实验采集64导脑电数据分析事件相关电位和静息态频谱。EEGLAB在这些任务上表现足够稳定并且能记录每次处理的操作历史这个特性对科研复现特别重要。好下面进入正题。2. 安装和启动EEGLAB这部分别跳过坑都在这里2.1 版本选择和MATLAB环境准备EEGLAB对MATLAB版本有要求不是随便拿个旧版就能跑。官方文档里写的是支持最新版MATLAB以及上两个主要版本太老的MATLAB可能装不了新版EEGLAB。比如EEGLAB 2024版要求MATLAB R2019b以上如果你还在用R2016这种老古董建议先去装新版的MATLAB或者找匹配的旧版EEGLAB来用。EEGLAB也支持GNU Octave但对于科研用户我不太推荐部分插件和绘图功能在Octave下跑不通白费时间。安装EEGLAB本身的步骤非常简单去官网下载最新的EEGLAB压缩包文件名类似eeglab2024.1.zip。解压到某个固定目录注意路径里不要有中文和空格比如放在D:\toolbox\eeglab或者/home/xxx/toolbox/eeglab都行。我之前懒省事放了个带中文名的文件夹结果某次加载插件死活报错排查半天就是路径的问题。打开MATLAB设置路径把EEGLAB的根目录加进去然后保存路径。在命令行输入eeglab回车。如果在命令行看到一句话提示然后弹出一个EEGLAB主界面窗口安装就成功了。主界面顶部有菜单栏下面有几个按钮和一个画图区域这就是你接下来几个月天天要面对的地方。2.2 先把插件装齐再开始干活EEGLAB生态里有一批装机必备插件强烈建议装好再处理数据不然你会在某一步突然卡住ICLabel做ICA后自动给每个成分分类眼动、肌肉、心电、大脑信号等是去伪迹时的重要帮手。clean_rawdata提供清理坏导、坏段以及ASR伪迹校正功能预处理初始阶段很管用。DIPFIT对ICA成分做偶极子定位做源分析时会用到。ERPLAB专门做ERP分析事件相关电位的提取、测量都靠它和EEGLAB配套。firfilt用FIR滤波器做滤波比EEGLAB自带的IIR滤波更稳。安装插件的方式有两种。一种是菜单栏 File Manage EEGLAB extensions Data 搜索需要的插件 Install这种适合新手。另一种是我更推荐的方式直接用eegplugin_xxx带路径的插件文件夹加入MATLAB路径因为有些插件在扩展管理器里安装会因为网络问题失败。我代理不了网络的时候经常用git clone的方式把插件克隆到本地再加路径实测最可靠。安装后重启一次EEGLAB界面菜单里如果出现新的菜单项就说明插件加载成功了。3. 数据导入和预处理从原始文件到能分析的干净数据预处理是整个脑电分析里最脏最累的活也是最能拉开分析水平差距的阶段。EEGLAB把预处理的几个核心步骤做成了图形界面和脚本双支持我建议你图形界面用来探路脚本用来跑批量。这一节我把每一步的具体操作和原理都拆开讲。3.1 第一步把不同采集设备的数据拉进来不同脑电采集设备导出的文件格式千奇百怪EEGLAB支持的格式非常多BioSemi的.bdf、欧洲标准.edf、BrainVision的.vhdr/.eeg/.vmrk、Neuroscan的.cnt、EGI的.mff、以及最常见的.set格式。加载数据用菜单的File Import data Using EEGLAB functions and plugins选择对应格式就能导入。以BioSemi的.bdf文件为例我会用pop_biosig命令完成导入EEG pop_biosig(subj01.bdf); [ALLEEG EEG CURRENTSET] pop_newset(ALLEEG, 0, setname, raw);导入之后要做的第一件事是看数据长什么样。点主界面的Plot Channel data (scroll)用滚动窗口看原始信号。这一步非常关键它会告诉你数据里有多少噪声源、有没有某个通道彻底没信号、有没有超大漂移。我习惯在原始数据阶段就先把明显的死导记下来后面统一处理。3.2 电极定位没有坐标的脑电数据等于少了一只手导入数据后经常发现通道没有对应的电极位置信息也就是chanlocs为空。这种情况下很多功能用不了比如做头皮地形图、ICA成分定位。设置电极位置有几种办法如果采集设备本身导出了电极坐标直接Edit Channel locations里加载。如果没有用标准模板。EEGLAB自带了standard_1020.elc和standard_1005.elc等文件你只需要按实验导联数选择合适的模板再把通道名称和模板里的名称匹配好就行。电极定位之后画地形图时会自动输出漂亮的头皮分布图。我踩过一次坑有次图出来以后电极位置明显错位发现是把Cz和FCz搞混了。所以加载完一定要认真检查一下坐标直接用topoplot画个图看看电极排布是不是符合常规。3.3 滤波高通、低通和陷波怎么设才科学预处理中的滤波参数设置我是吃过不少亏的。一开始我随手就把高通设为1Hz结果发现慢电位成分全被滤没了后面想做CNV或者某些临床指标的时候完全没法用。后来才知道高通滤波的截止频率直接决定你能看多慢的神经活动。常规的滤波设置建议大致是这样如果后续只分析ERP的早期成分比如P1、N1、P3这些60-500ms范围内的成分高通设为0.1Hz问题不大。如果关注的是慢波、准备电位、失匹配负波这种慢成分高通建议放到0.01Hz甚至更低比如0.05Hz。代价是基线漂移会保留得多一点后面要配合去漂移手段处理。低通一般设到30Hz或40Hz除非你专门分析gamma频段或高频振荡那样需要把低通提高甚至不加。工频干扰50Hz或60Hz一般用陷波滤波器或者用之后要讲的cleanline插件做去工频处理。我不推荐在预处理早期直接陷波因为会损失信号建议先做ICA看能不能自动分离掉工频干扰。滤波器本身有两个主要选项需要在意IIR和FIR。EEGLAB新版的pop_eegfiltnew函数用的是一套优化过的滤波设计默认就挺好。如果是科研报告我建议用FIR滤波因为相位响应是线性的不会造成波形畸变。例如EEG pop_eegfiltnew(EEG, 0.1, 40);这样写就是带通0.1到40Hz。如果想单独做高通或低通把不需要的截止频率填[]就行。注意滤波的方向也很重要EEGLAB自带的是零相位滤波不会引入相位延迟但会在信号首尾产生边缘效应。长记录无所谓如果是短片段最好保证前后有足够余量。3.4 剔除坏导和坏段不能靠肉眼硬刚每一个脑电数据集里几乎都会有那么几个完全不能看的通道有的是因为接触不良有的是因为电极老化波形直接是一根直线或者疯狂摆动的尖峰。这种通道留着会严重影响后续的重参考和ICA必须处理。手动在滚动窗口里找坏导效率太低我用的方法是直接用clean_rawdata插件它有个基于统计的方法能识别异常通道虽然不能完全替代人工检查但能把大部分明显问题找出来EEG clean_rawdata(EEG, 5, off, 0.7, off, 20, off);这行命令的第二个参数5是坏导检测阈值数值越小越严格第四个参数0.7是坏段剔除所需的通道相关阈值第六个参数20是ASR的截断阈值。这个函数用起来要谨慎参数设得太激进会把好数据也删掉。我的建议是先跑一个中等阈值然后再人工复核一遍被标记的通道再在数据集上直接右键查看通道的功率谱和波形最终决定是否剔除。坏段则是指由于动作、电极松脱、设备故障等原因造成的一整段不可用信号。我一般会用pop_eegthresh做简单的幅度阈值检测也会配合pop_rejchan和pop_jointprob看每个通道的统计特性再加上肉眼扫一遍。EEGLAB的Tools Reject data epochs Reject extreme values可以设置阈值比如正负100微伏超过这个范围的epoch就会被标记。这里有个经验阈值设置不能一刀切。如果是儿童或者特殊人群的数据脑电幅度本来就大阈值要放宽如果采集质量很好可以收紧到正负80微伏。我会先跑一版用默认阈值看报告里拒绝比例再根据比例调整。通常一个被试剔除的坏段在0-10%是正常的如果超过20%说明采集过程存在系统性问题缓一缓再深入分析。3.5 重参考平均参考还是全脑平均别选错脑电记录是相对参考电极的测量结果所以你用什么参考直接影响到后续波形解释。EEGLAB里重参考的选项在Tools Re-reference。最常见的做法是用全脑平均参考average reference对64导及以上的数据效果比较好对32导或者更少通道的数据则推荐用双耳乳突参考。我做的实验通常是64导所以我处理时基本都用pop_reref(EEG, [])方括号表示全脑平均。这里牵扯到一个细节全脑平均参考的前提是所有电极均匀覆盖头皮如果某个区域电极缺失比如只有背部导联平均参考会带有偏差这种情况下还是用乳突参考更稳妥。实际操作中我会先把需要剔除的坏导标记出来重参考之后再插值回去这样能避免坏导拉偏参考值。顺序千万不要弄反。如果一个被试头顶有一块区域导联噪声太大直接平均参考会把噪声带到所有导联后续ICA都救不回来。我的流程是识别坏导 → 剔除坏导 → 重参考 → 插值坏导 → 滤波 → ICA。3.6 ICA去伪迹眼动、心跳、肌电分而治之预处理流程中最有技术含量的一步是ICA独立成分分析。它的核心思想是把多导脑电信号分解成多个统计独立的成分其中眼动、眨眼、心跳等非神经活动通常集中在少数几个成分上识别出来然后剔除剩下的成分重构回电极空间就能得到更干净的脑电信号。EEGLAB里做ICA的入口是Tools Decompose data by ICA。ICA算法的选择上runicaInfomax是经典选择处理速度适中适用面广如果你的数据质量非常差或眼动伪迹特别严重可以试试AMICA它更稳定但速度极慢fastica是快速实现适合预览。我处理时通常跑的是runica一次64导10分钟的数据大概需要几分钟到十几分钟取决于机器性能。代码是这样的EEG pop_runica(EEG, icatype, runica, extended, 1);跑完ICA后打开ICLabel组件分类面板。ICLabel会为每个独立成分给出标签概率比如“Brain”、“Eye”、“Muscle”、“Heart”、“Line Noise”等这个功能非常实用。我会把“Eye”概率大于0.8或者“Muscle”概率大于0.7的成分标记掉然后手动再看一眼这些成分的头皮地形图和时域波形确认它们确实是伪迹。有些成分ICLabel标注为Brain但拓扑图十分奇怪也得警惕。标记伪迹成分后用pop_subcomp剔除然后把剩余成分投影回电极空间EEG pop_subcomp(EEG, [1 3 5], 0);这里的[1 3 5]是我需要剔除的成分编号列表0表示保留剩余成分并重建信号。剔除ICA成分不是万能的如果一个成分既包含眼动又包含大脑活动剔除它会伤及真正的脑信号。所以每次剔完我都会对比一下剔除前后的ERP波形看是否出现明显畸变。如果波形变化过大我会把边界成分改为不剔除或者在守恒的条件下降低剔除个数。我特别想强调的一点是预处理流程的执行顺序决定了结果质量。有人习惯先滤波再做ICA其实只要不把重要频段滤掉问题不大但我个人更推荐先做高通0.1Hz和低通40Hz、剔除坏段、再ICA。至于陷波滤波我认为尽量留在ICA之后因为ICA能比较自然地分离出50Hz工频成分再用陷波处理空气中的残留干扰。这个顺序我调试了非常久是目前对我数据集最稳定的一套。4. 三大分析路径ERP、频谱和时频到底怎么跑预处理完成后数据已经处于可分析状态。接下来就是看你想回答什么问题决定走哪条分析路线。神经科学和认知研究里最常用的指标是事件相关电位ERP、功率谱密度PSD和事件相关频谱扰动ERSP。EEGLAB对这三个方向都提供了成熟的支持。4.1 ERP分析从连续数据切epoch到平均叠加ERP分析的第一步是把连续数据分段。在EEGLAB里就是提取事件锁定的epoch菜单操作是Tools Extract epochs函数是pop_epoch。需要提供事件标记比如S1代表刺激呈现、S2代表反应。我对某个视觉实验做分段代码大致是EEG pop_epoch(EEG, {S1}, [-0.2 0.8]); EEG pop_rmbase(EEG, [-200 0]);第一行是提取刺激前200毫秒到刺激后800毫秒的片段第二行是做基线校正用刺激前200毫秒到刺激开始前这一段算平均作为基线从整个epoch里减去。分好段后先做一次自动伪迹拒绝再逐段检查。Tools Reject data epochs Reject extreme values设置阈值建议配合肉眼检查。如果你前面ICA去伪迹做得到位这一步一般拒绝率很低。ERP平均就在ERPLAB Compute averaged ERP里做输出每个条件每个电极的平均波形。之后用plot把多个条件的波形叠加在一起再加个pop_erpparams设置显示参数就能在EEGLAB里直接画出论文级别的图。我在做ERP时一般关注的是P1、N1、P300这些经典成分所以在时间窗测量时我会分别设置时间窗比如P1在80-130msN1在150-220msP300在300-500ms然后读取该窗口内的峰值和平均振幅。这里的核心是要提前决定测量窗口不能等看到数据再调整否则会有只看显著结果的嫌疑。4.2 频谱分析静息态数据看得很清楚如果做静息态分析不需要分段到事件直接在连续数据上做频谱就可以。EEGLAB的Tools Power spectrum会调用pop_spectopo它能输出各个电极的功率谱并且可以把多个电极的谱线叠在一张图上对比。做频谱前要确定两件事第一频率范围我一般看1-40Hz第二平滑窗口这决定了频率分辨率和稳定性之间的平衡。用pop_spectopo(EEG, 1, [0 4200], freqrange, [1 40])可以把窗口设为1秒从而得到1Hz的频率分辨率。值得留意的是静息态数据很容易受肌肉伪迹影响很多被试闭眼时下颌紧张颞区电极就一路肌电。频谱图上一旦出现高频段整体抬高就要回预处理阶段把肌肉成分剔干净否则后面算出来的alpha、beta功率会严重失真。我在一个静息态项目里遇到过这种情况同一个被试两次采集的数据在频谱形态上完全不同后来检查才发现是肌电成分没有剔除干净。从那以后我做频谱分析之前都会专门检查一下ICLabel里的Muscle成分比例。4.3 时频分析同时看时间和频率的变化时频分析相比ERP和频谱能看到信号在不同时间点的频率组成变化特别适合分析事件诱发的振荡活动比如theta振荡增加、alpha去同步等。EEGLAB里用newtimef函数[ersp itc] newtimef(EEG.data(chan_idx, :, :), EEG.pnts, [-200 800], EEG.srate, cycles, 3);cycles参数决定了时间分辨率和频率分辨率之间的权衡数值越小时间分辨率越高但频率分辨率越差。默认的0和1分别对应自适应和固定窗口。对于认知实验我会从3到5开始调再根据结果动态调整。如果你关心的频率很低比如1Hz自适应窗口会让时间窗拉长此时需要注意边缘效应。时频图出来后EEGLAB会用pop_newtimef生成带显著性检验的图。显著性检验通常用置换检验方法来生成没有统计学基础的读者可以先不深入直接用默认参数结果但报告时需要说清楚参数。4.4 批处理脚本没有脚本数据量一大你就等着崩溃吧如果你的实验有20个或更多被试每个被试都通过图形界面点按钮操作效率太低而且容易出错。我的做法是写一个统一的预处理脚本一键跑完全部被试。以下是一个简化但完整的批量预处理脚本骨架直接按你的数据情况修改即可% 初始化EEGLAB [ALLEEG EEG CURRENTSET ALLCOM] eeglab; % 文件列表 files dir(sub*.set); for i 1:length(files) EEG pop_loadset(filename, files(i).name, filepath, files(i).folder); [ALLEEG, EEG, CURRENTSET] eeg_store(ALLEEG, EEG, 0); EEG eeg_checkset(EEG); % 1. 滤波 EEG pop_eegfiltnew(EEG, 0.1, 40); % 2. 剔除坏导这里是示例参数按实际情况调整 EEG clean_rawdata(EEG, 5, off, 0.7, off, 20, off); % 3. 重参考到平均 EEG pop_reref(EEG, []); % 4. 插值坏导如果clean_rawdata已经标记了坏导的话 EEG pop_interp(EEG, EEG.chanlocs); % 5. 分段 EEG pop_epoch(EEG, {S1}, [-0.2 0.8]); EEG pop_rmbase(EEG, [-200 0]); % 6. 剔除坏段 EEG pop_eegthresh(EEG, 1, 1:EEG.nbchan, -100, 100, -0.2, 0.8, 0, 0); % 7. ICA EEG pop_runica(EEG, icatype, runica, extended, 1); % 8. 保存ICA结果方便后面手动查看和剔除成分 EEG pop_saveset(EEG, filename, [files(i).name(1:end-4) _ica.set], filepath, processed/); end这个脚本跑完后你会得到每个被试经过ICA处理的数据集后续再根据ICLabel的分类结果统一剔除伪迹成分提取ERP或PSD。因为ICA结果不一定会自动定位到一致的成分编号有的项目会直接在脚本里按ICLabel概率阈值自动剔除比如把Eye概率大于0.8的成分全部去掉。但我个人建议还是留一步人工复核尤其处理的是临床数据时自动阈值容易误伤。批处理脚本的大忌是写得太死。我最初十分喜欢把整个流程全写在一起跑完结果某个被试在某个特殊参数上挂了程序中止前面的处理全部白做。后来我改成每处理一个步骤就保存一个中间文件比如_filt.set、_ica.set、_clean.set这样如果中途出错只需从上一步断点继续。多花一点硬盘空间换回的排查效率非常可观。5. 常见报错和问题排查遇到Bug别慌按这个表对照排查EEGLAB报错看起来神秘其实大部分原因就那么几个。我把自己这些年碰到的典型问题和排查顺序列成一个速查表你照着一步步来就行。现象常见原因排查思路启动时报找不到eeglab.mMATLAB路径没设置好检查pathtool确认EEGLAB根目录和子目录都加进去了保存路径后重开MATLAB导入数据后通道数为空电极文件格式不正确或者通道名不匹配Edit Channel locations里重新加载standard_1005.elc或相应模板核对通道标签滤波后波形整体漂移高通截止频率太低或边缘效应明显提高高通频率到0.1或0.5Hz或者确保分段前后留出足够余量ICA成分里有大量脑电特征消失、波形很奇怪数据里仍有坏导或大幅伪迹没清干净回到预处理先剔坏导坏段再做一次ICA检查重参考顺序ERP波形噪声巨大滤过低或过低通参数不合适、剩余epoch数太少检查低通是否设置过高检查每个条件下保留的trial数频谱图高频整体抬高肌电伪迹混入回ICA阶段检查Muscle成分剔除后重建信号再做频谱clean_rawdata报错无法继续数据里存在NaN或极端值用eeg_checkset(EEG)检查异常值先手动处理再跑DIPFIT定位结果很差电极坐标不准确、ICA成分质量差扣紧电极定位文件挑选ICLabel里Brain概率高的成分再定位除了表里的问题我还有一个安全建议永远在改动数据前备份原始文件。EEGLAB里的很多操作会直接修改当前数据集如果不小心按错原始数据又没备份那就只能重新导入了。我的习惯是每个被试保存三个版本原始导入版、预处理后版、最终分析版。硬盘多花几十GB省的是无数重复劳动。另一个容易被忽视的点是EEGLAB图形界面操作的所有命令都会记录在EEG.history里。这意味着你做完一版预处理后可以用EEG.history把整个操作过程复制出来整理成脚本用于批处理。这个功能对可重复研究特别友好我每次处理完数据都会输出一份处理历史存档。6. 我自己的几个使用心得EEGLAB用久了之后我总结出几条很个人但很实用的经验。第一永远不要让图形界面替你做决定。图形界面最大的价值是让你快速理解每一步在干什么但真正要批量处理数据时一定要转成脚本。写脚本的过程就是思考的过程也是保证处理一致性的过程。有一次我需要修改预处理参数图形界面重跑一遍花了三个小时改成脚本改一行参数后重跑十分钟全部搞定。第二ICA不是一劳永逸的。它只是把数据变换到成分空间不能自动替你判断哪些是伪迹。现在有ICLabel可以帮你做初步分类但最后一个“是否剔除该成分”的决定还是要你来下。我见过有些人把ICLabel标注为Eye概率0.6左右的成分也全剔了结果丢了真实的额叶脑电活动。建议把ICLabel当作辅助工具而不是绝对标准。第三做ERP分析时检查每个条件下试次数的分布非常重要。如果一个条件下的某电极可用trial数明显少于另一个条件波形稳定性就完全不同后续比较会充满误导性。我一般在一份数据里去完伪迹后把每个条件下的trial数统计出来看一遍少于30个trial的条件基本不做进一步分析或者直接考虑剔除该被试。如果你看到这里大概率已经准备打开MATLAB捣鼓一番了。最后再分享一个小技巧EEGLAB自带了一组示例数据在安装目录的sample_data文件夹里里面有完整的.set文件和说明文档。如果你刚开始学先别急着拿自己数据练手用示例数据集把导入、滤波、分段、ICA、画图这些流程完整走一遍比你对着教程看十遍都管用。等流程熟了再换成自己的数据心态会完全不一样。
返回列表