第 4 层 · 伪迹剔除层 · 第 17 步 / 共 25 步

步骤 17:剔眼电成分

识别眼电相关 ICA 成分

🕐 25 分钟🎯 难度:进阶🔗 核心 API:ica.find_bads_eog⬅️ 前置:步骤 16

1. 目标

利用 EOG 通道与 ICA 成分的相关性,自动识别眼电成分,并支持人工核对与修改。识别后成分进入 ica.exclude 候选,最终通过步骤 19 应用剔除。

2. 何时使用 / 何时跳过

  • 必须使用:若计划用 ICA 去除眼电
  • 可跳过:若步骤 14 的 SSP 已完全去除眼电

3. 前置条件

  • 已执行步骤 16:ICA 已拟合完成
  • 数据中存在 eog 类型通道
  • ica.fit() 拟合时包含 picks=['eeg'],但传入的 raw 包含 eog 通道(关键!)

4. 核心代码

Python
import mne

# ====== 方式 A:自动识别(推荐新手) ======
# MNE 会计算每个 IC 与 EOG 通道的相关性,自动挑出最高的
eog_idx, eog_scores = ica.find_bads_eog(
    raw,
    ch_name=None,          # None = 自动选择 EOG 类型通道
    threshold=3.0,         # z-score 阈值,越小越激进(默认 3.0)
    measure='zscore',      # 相关性度量
)

print(f"自动识别的眼电成分: {eog_idx}")
print(f"各成分相关性分数: {eog_scores}")

# ====== 方式 B:手动指定 EOG 通道 ======
eog_idx, eog_scores = ica.find_bads_eog(
    raw,
    ch_name=['HEOG', 'VEOG'],  # 可指定多个
    threshold=2.0,
)

# ====== 方式 C:水平 + 垂直眼电分别检测 ======
eog_idx_h, scores_h = ica.find_bads_eog(raw, ch_name='HEOG')
eog_idx_v, scores_v = ica.find_bads_eog(raw, ch_name='VEOG')
eog_idx = list(set(eog_idx_h) | set(eog_idx_v))

# ====== 人工核对(必做!) ======
# 1) 可视化自动识别结果
ica.plot_scores(eog_scores, exclude=eog_idx)

# 2) 检查每个候选成分的拓扑图(眼电成分应在额部)
ica.plot_components(
    picks=eog_idx,
    inst=raw,
)

# 3) 检查每个候选成分的时间序列
ica.plot_sources(
    inst=raw,
    picks=eog_idx,
    start=0,
    stop=30,
)
# 期望:能清楚看到眨眼节律或眼球运动

# ====== 手动调整 ======
# 添加遗漏的眼电成分
ica.exclude.extend(eog_idx)
# 或移除误识别的成分
# ica.exclude.remove(<misidentified_idx>)

5. 参数详解

参数 含义 推荐值
ch_name EOG 通道 None(自动选)/ 'HEOG' / ['HEOG', 'VEOG']
threshold 相关性 z-score 阈值 3.0(默认)/ 2.0(激进)
measure 相关性度量 'zscore'(默认)/'correlation'

6. 验证方法

Python
# 验证 1:候选成分数量合理
print(f"自动检出 EOG 成分数: {len(eog_idx)}")
assert 1 <= len(eog_idx) <= 5, "眼电成分数异常,建议人工复核"

# 验证 2:topomap 集中在额部
for idx in eog_idx:
    ica.plot_components(picks=[idx], inst=raw)
    # 期望:额部权重最大(特别是 Fp1/Fp2 附近)

# 验证 3:时间序列与 EOG 通道强相关
eog_ch = raw.get_channel_types(picks=['eog']).index('eog')
eog_data = raw.get_data(picks=['eog'])[0]
ic_timeseries = ica.get_sources(raw).get_data()[eog_idx[0]]
corr = np.corrcoef(eog_data, ic_timeseries)[0, 1]
print(f"IC{eog_idx[0]} vs EOG 相关系数: {corr:.2f}")
# 期望:|r| > 0.3

# 验证 4:保存 ICA + exclude 列表
ica.save('subject-01_ica.fif', overwrite=True)

7. 常见错误

错误 原因 解决方案
find_bads_eog 检出 0 个成分 EOG 通道未在 raw 中(标错类型) 回到步骤 03 修正
自动检出的成分不是眼电 数据本身眼电不明显 提高 threshold
检出过多(>5)成分 threshold 太低 提高 threshold 至 5.0+
自动检出 vs 人工判断不一致 个别成分边界模糊 永远要配合可视化人工核对
闭眼被试看不到眨眼成分 闭眼态眨眼微弱 接受现状或用眨眼相关分析
ch_name='auto' 报错 'auto' 不是合法值 改用 ch_name=None

8. 官方来源

资源类型 链接
find_bads_eog https://mne.tools/stable/generated/mne.preprocessing.ICA.html#mne.preprocessing.ICA.find_bads_eog
ICA 教程 https://mne.tools/stable/auto_tutorials/preprocessing/plot_40_artifact_correction_ica.html
成分图 https://mne.tools/stable/generated/mne.preprocessing.ICA.html#mne.preprocessing.ICA.plot_components

9. 学术引用

Vigário, R. N. (1997). Extraction of ocular artefacts from EEG using independent component analysis. Electroencephalography and Clinical Neurophysiology, 103(3), 395-404.