第1章:EEG数据预处理实战(上)——滤波、重参考、坏道检测与插值

各位同学,欢迎来到实战环节。说实话,EEG数据预处理这事儿,我做了快十年,踩过的坑比走过的路还多。今天咱们就聊聊滤波、重参考、坏道检测与插值这四个核心步骤。别小看它们,预处理做不好,后面模型再花哨也是白搭。

1.1 滤波:带通与陷波

EEG信号里,真正有用的脑电频率范围一般在0.5-40Hz之间。但实际采集到的信号,混着工频干扰(50/60Hz)、肌电噪声(高频)、眼动伪迹(低频)等等。滤波就是要把这些“脏东西”去掉。

1.1.1 带通滤波

带通滤波,说白了就是只让某个频率范围的信号通过。比如我们做运动想象任务,通常关注8-30Hz的mu节律和beta节律。我个人习惯用0.5-40Hz的带通,既能保留主要脑电成分,又能滤掉直流漂移和高频肌电。

这里有个坑:滤波器的阶数别设太高。阶数高了,虽然过渡带陡峭,但会产生振铃效应,把信号搞变形。我一般用4阶或5阶的Butterworth滤波器,效果够用。

核心要点:带通滤波的截止频率要根据任务需求来定。做睡眠分析,可能需要0.3-30Hz;做高频gamma振荡研究,可以放宽到100Hz甚至更高。

# Python示例:使用MNE进行带通滤波
import mne

# 加载原始数据
raw = mne.io.read_raw_fif('subject01_raw.fif', preload=True)

# 0.5-40Hz带通滤波
raw.filter(0.5, 40, method='fir', fir_design='firwin')
print('滤波完成,频率范围:0.5-40Hz')

1.1.2 陷波滤波

陷波滤波专门对付工频干扰。国内是50Hz,国外有些地方是60Hz。你想想看,如果50Hz的干扰不滤掉,后面做频谱分析时,50Hz处会冒出一个假峰,误导性极强。

我曾经在一个项目中,发现某位受试者的数据在50Hz处能量异常高。一开始以为是脑电特征,后来一查,原来是实验室隔壁在用电焊机。嗯,陷波滤波救了我一命。

小技巧:如果工频干扰不严重,可以只做带通滤波(0.5-40Hz),因为50Hz已经被滤掉了。但多数情况下,我建议单独做一次陷波,更稳妥。

# 50Hz陷波滤波
raw.notch_filter(50, method='fir', fir_design='firwin')
print('50Hz陷波完成')

1.2 重参考

EEG信号是差分信号,记录的是两个电极之间的电位差。所以参考电极的选择,直接影响信号质量。常见的参考方式有:

  • 单极参考:以某个电极(如Cz、A1/A2)为参考。简单,但参考电极本身可能受干扰。
  • 双极参考:相邻电极相减。能抑制共模干扰,但会损失空间信息。
  • 平均参考:所有电极的平均值作为参考。我个人最常用,因为它能最小化参考电极的偏差。

为什么平均参考好?你想想看,如果某个电极恰好处于噪声源附近,单极参考就会把噪声引入所有通道。平均参考相当于“民主投票”,每个电极贡献一点,噪声被平均掉了。

注意:平均参考要求电极覆盖均匀。如果只有几个电极,平均参考的效果会变差。这时候我建议用单极参考,选一个远离脑区的电极(如乳突电极)。

# 设置平均参考
raw.set_eeg_reference('average', projection=False)
print('已设置为平均参考')

1.3 坏道检测

坏道,就是那些信号质量极差的通道。原因很多:电极接触不良、导线断裂、受试者出汗导致短路……坏道不处理,会污染后续的分析结果。

怎么检测坏道?我总结了几条经验:

  1. 目视检查:看波形是否异常平坦或剧烈抖动。这是最原始但最可靠的方法。
  2. 统计指标:计算每个通道的方差、峰峰值、信噪比。偏离均值3个标准差的,基本可以判定为坏道。
  3. 相关性分析:坏道与其他通道的相关性通常很低(<0.3)。

我曾经遇到过一个案例:某受试者的Fz通道波形看起来很正常,但方差比其他通道大10倍。后来发现是电极帽的Fz位置有个小裂缝,导致接触阻抗不稳定。嗯,这种“伪装”成好通道的坏道最坑人。

实战建议:坏道检测要结合自动算法和人工判断。我一般先用MNE的自动检测功能,再手动确认一遍。别完全相信算法,也别完全依赖肉眼。

# MNE自动检测坏道
raw.info['bads'] = []  # 清空原有坏道列表
raw.plot(block=True)   # 手动标记坏道

# 或者用自动检测
from mne.preprocessing import find_bad_channels
bads = find_bad_channels(raw, method='correlation', threshold=0.3)
print(f'检测到的坏道:{bads}')

1.4 坏道插值

坏道找到了,怎么办?直接删除?别急。删除坏道会损失空间信息,尤其是坏道较多时,插值是更好的选择。

插值的原理很简单:用周围好通道的信号,通过某种算法估算坏道的值。常用的方法有:

  • 球面样条插值:假设头皮是球面,用样条函数拟合。精度高,但计算慢。
  • 最近邻插值:用最近的几个好通道平均。简单粗暴,适合坏道较少的情况。
  • 加权平均插值:根据距离加权。我比较推荐,兼顾精度和速度。

这里要注意:插值不是万能的。如果坏道超过总通道数的20%,插值结果会严重失真。这时候我建议直接删除坏道,或者重新采集数据。

经验之谈:插值前一定要确认坏道是真的坏了,还是只是暂时性干扰。我曾经把眨眼伪迹误判为坏道,结果插值后把眨眼信号扩散到了周围通道,搞得数据没法用。

# 使用MNE进行坏道插值
raw.interpolate_bads(reset_bads=True)
print('坏道插值完成')

知识体系总览

下面这张图,是我自己整理的EEG预处理流程。你可以把它当作一个检查清单,每次处理数据时对照着来。

EEG预处理流程(第1章核心) 原始EEG数据 滤波(带通0.5-40Hz + 陷波50Hz) 重参考(推荐平均参考) 坏道检测(自动+人工确认) 坏道插值(球面样条/加权平均) 预处理完成

这张图里,我特意把滤波放在最前面。为什么?因为滤波能去除大部分噪声,让后续的坏道检测更准确。你想想看,如果工频干扰没滤掉,坏道检测算法可能会把50Hz的噪声误判为坏道。顺序很重要。

总结一下:滤波去噪 → 重参考统一基准 → 坏道检测找问题 → 插值修复。这四步走完,你的EEG数据就基本干净了。下一章咱们聊伪迹去除,那才是真正的硬骨头。


专注资料整理