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

步骤 16:ICA 拟合

独立成分分析(ICA)拟合

🕐 35 分钟🎯 难度:进阶🔗 核心 API:mne.preprocessing.ICA⬅️ 前置:步骤 15

1. 目标

在干净的高通滤波数据上拟合 独立成分分析(ICA),把混合的脑电信号分解为若干独立成分。每个成分代表"一个独立源",可能是脑源、眼电、肌电、心电、噪声等。

2. 何时使用 / 何时跳过

  • 应当使用:任何 ≥ 32 导 EEG 实验
  • 可跳过:极小数据集(< 16 导);纯儿童/动物 EEG(噪声太大 ICA 失效)

3. 前置条件

  • 已执行步骤 15:SSP 投影已记录到 raw.info['projs'],但尚未施加(apply_proj() 留给 epochs)
  • 数据已带通、已平均参考

⚠️ ICA 拟合数据的两个关键前提: 1. 高通 ≥ 1 Hz(剔除低频漂移,否则 ICA 拆出"漂移成分"); 2. SSP 投影记录但未施加(施加后会损失维度)。

4. 核心代码

Python
import mne

# ====== 准备 ICA 输入数据 ======
# 临时副本,仅用于 ICA(避免污染原数据)
raw_for_ica = raw.copy().filter(
    l_freq=1.0,   # ICA 专用高通
    h_freq=None,  # 保留之前所有低通
    picks=['eeg', 'eog', 'ecg'],  # EOG/ECG 必须参与 ICA
)

# ====== 方式 A:FastICA(默认) ======
from mne.preprocessing import ICA

ica = ICA(
    n_components=0.95,    # 自动选择保留 95% 方差的成分数
    method='fastica',
    # fit_params 默认 None:MNE 内部已对数据做 PCA 白化,FastICA 自带 whitening
    # 仅在需要微调时显式传 fit_params(如 Picard 的 ortho)
    max_iter='auto',
    random_state=42,      # 固定随机种子以复现
)
ica.fit(raw_for_ica, picks=['eeg'])  # ICA 仅对 EEG 拟合

# ====== 方式 B:Infomax('extended' 是它的参数) ======
ica = ICA(
    n_components=0.95,
    method='infomax',
    fit_params=dict(extended=True),  # extended 仅 infomax 合法
    random_state=42,
)
ica.fit(raw_for_ica)

# ====== 方式 C:Picard(最快,推荐新项目) ======
ica = ICA(
    n_components=0.95,
    method='picard',
    fit_params=dict(ortho=False, whiten='unit-variance'),
    random_state=42,
)
ica.fit(raw_for_ica)

# ====== 验证 ======
print(f"拟合的成分数: {ica.n_components_}")
print(f"解释方差: {ica.pca_explained_variance_}")

5. 参数详解

ICA 构造函数

参数 含义 推荐值
n_components 保留成分数 0.95(保留 95% 方差,自动选数)/30(固定数)/None(=通道数)
method 算法 'fastica'(默认);'infomax'、'picard'
fit_params 算法专属参数 默认 None(MNE 内部已白化);Infomax:dict(extended=True);Picard:dict(ortho=False, whiten='unit-variance');FastICA:一般无需传
max_iter 最大迭代 'auto'(默认)
random_state 随机种子 固定为 42 等以确保可复现
noise_cov 噪声协方差 默认 None

fit 方法

参数 含义 推荐值
picks 拟合的通道 ['eeg'](推荐)
start / stop 数据时间窗 默认全部
reject 自动拒绝阈值 None 或 dict(eeg=500e-6)

6. 不同 ICA 方法对比

方法 速度 稳定性 适用
FastICA 快 中 一般研究(默认)
Infomax 慢 高 难数据(多伪迹)
Picard 最快 高 新项目推荐

7. 验证方法

Python
# 验证 1:拟合成功
print(f"成分数: {ica.n_components_}")
assert ica.n_components_ > 0

# 验证 2:可视化所有成分
ica.plot_components()
# 期望:能看到脑电成分、眼电成分(额部明显)、肌电成分等

# 验证 3:可视化成分时间序列
ica.plot_sources(raw_for_ica, start=0, stop=30)
# 期望:能看到眨眼、肢体运动等

# 验证 4:方差解释率
print(f"前 10 成分累积解释方差: {ica.pca_explained_variance_[:10].sum()*100:.1f}%")
# 期望:≥ 80%

# 验证 5:保存 ICA
ica.save('subject-01_ica.fif')

8. 常见错误

错误 原因 解决方案
n_components=0.95 报错 数据长度太短 改用固定数(如 30)或保证数据 ≥ 1 分钟 × 通道数
ICA 拆不出眼电成分 EOG 通道未参与拟合/未标 eog 步骤 03 重新设通道类型
拟合过程内存爆炸 数据太长 + 通道太多 用 start / stop 切片拟合
每次拟合结果不同 random_state 未固定 显式设置 random_state=42
RuntimeError: data is empty preload=False 确保 raw_for_ica.preload=True
拟合后没有脑电成分 高通过低(< 1 Hz) 提高 l_freq 至 1.0 Hz
TypeError: unexpected keyword argument 'extended' FastICA 不接受 extended 参数(仅 infomax 接受) FastICA 改用 dict(whiten='unit-variance')

9. 官方来源

资源类型 链接
ICA 类 https://mne.tools/stable/generated/mne.preprocessing.ICA.html
教程 https://mne.tools/stable/auto_tutorials/preprocessing/plot_40_artifact_correction_ica.html
方法对比 https://mne.tools/stable/auto_tutorials/preprocessing/40_artifact_correction_ica.html

10. 学术引用

Bell, A. J., & Sejnowski, T. J. (1995). An information-maximization approach to blind separation and blind deconvolution. Neural Computation, 7(6), 1129-1159.

Ablin, P., et al. (2018). Faster independent component analysis by preconditioning with Hessian approximations. IEEE Transactions on Signal Processing, 66(15), 4040-4049.(Picard)