非官方中文翻译 本页译自 MNE-Python 官方文档: 查看英文原文 ↗。 文档版权归 MNE Developers 所有(BSD-3-Clause)。

伪迹检测概览#

本教程介绍伪迹检测的基础知识,并简要介绍 MNE-Python 提供的伪迹检测工具。

照例,我们首先导入所需的 Python 模块并加载一些示例数据:

# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.
import os

import numpy as np

import mne

sample_data_folder = mne.datasets.sample.data_path()
sample_data_raw_file = os.path.join(
    sample_data_folder, "MEG", "sample", "sample_audvis_raw.fif"
)
raw = mne.io.read_raw_fif(sample_data_raw_file)
raw.crop(0, 60).load_data()  # just use a fraction of data for speed here
Opening raw data file /home/circleci/mne_data/MNE-sample-data/MEG/sample/sample_audvis_raw.fif...
    Read a total of 3 projection items:
        PCA-v1 (1 x 102)  idle
        PCA-v2 (1 x 102)  idle
        PCA-v3 (1 x 102)  idle
    Range : 25800 ... 192599 =     42.956 ...   320.670 secs
Ready.
Reading 0 ... 36037  =      0.000 ...    60.000 secs...
General
Filename(s) sample_audvis_raw.fif
MNE object type Raw
Measurement date 2002-12-03 at 19:01:10 UTC
Participant Unknown
Experimenter MEG
Acquisition
Duration 00:01:01 (HH:MM:SS)
Sampling frequency 600.61 Hz
Time points 36,038
Channels
Magnetometers
Gradiometers and
EEG and
EOG
Stimulus
Head & sensor digitization 146 points
Filters
Highpass 0.10 Hz
Lowpass 172.18 Hz
Projections PCA-v1 (off)
PCA-v2 (off)
PCA-v3 (off)


什么是伪迹?#

伪迹是记录信号中并非来自感兴趣源(即大脑神经活动)的部分。因此,相对于感兴趣的信号,伪迹是一种干扰或噪声。这类干扰可能有许多来源,例如:

  • 环境伪迹
    围绕交流工频(通常为 50 或 60 Hz)的持续振荡 建筑物振动(如关门)引起的短暂信号跳变 来自附近电梯、手机、地磁场等的电磁场噪声
  • 设备伪迹
    刺激呈现带来的电磁干扰(例如 EEG 传感器拾取到未屏蔽耳机产生的场) 由头位指示(HPI)线圈所用特定频率引起的持续振荡 传感器故障导致的单个通道随机高幅波动(或反之,信号恒为零),例如表面电极与头皮接触不良
  • 生理性伪迹
    心脏电活动引起的周期性类 QRS 信号模式(尤其见于磁强计通道) 眼动引起的短促阶跃样偏转(尤其见于额区 EEG 通道) 眨眼引起的大幅瞬态偏转(尤其见于额区 EEG 通道) 吞咽时肌肉活动引起的多个通道短暂高频波动爆发

在某些情况下,来自大脑内部的信号也可能被视为伪迹。例如,如果研究者主要关注对刺激的感觉响应,但实验范式包含行为反应(如按键),那么与计划和执行按键相关的神经活动,相对于感兴趣的信号(即诱发感觉响应),就可以被视为伪迹。

注意

由于传感器设计不同(例如被动式与主动式 EEG 电极、轴向与平面梯度计等),相同来源的伪迹在不同 EEG 或 MEG 系统的记录中可能表现不同。

如何处理伪迹#

面对记录中的伪迹,通常有三种基本选择:

  1. 忽略伪迹,继续进行分析

  2. 剔除被污染的数据部分,分析剩余数据

  3. 修复伪迹,即抑制记录中的伪迹成分,同时(希望)保持感兴趣的信号不受影响

修复伪迹有许多不同的方法,MNE-Python 提供了多种伪迹修复工具,包括数字滤波、独立成分分析(ICA)、Maxwell 滤波 / 信号空间分离(SSS)以及信号空间投影(SSP)。后续的独立教程将分别演示这些伪迹修复技术。许多修复技术既可作用于连续(原始)数据,也可作用于已分段的 Epochs 数据(不过效果未必相同);有些技术可用于内存映射数据,另一些则要求将数据复制到内存中。当然,在选用任何策略之前,你必须先检测出伪迹,这正是下一节的主题。

伪迹检测#

MNE-Python 提供了一些用于自动检测特定伪迹(如心跳和眨眼)的工具,当然你也可以随时通过目视检查数据来识别并标注伪迹。

我们在入门教程中已经看到,示例数据包含 SSP 投影器(projectors),因此在查看伪迹之前,我们先把这些投影器保存到一个单独的变量中,然后用 del_proj() 方法将它们从 Raw 对象中移除,以便在原始状态下检查数据:

General
Filename(s) sample_audvis_raw.fif
MNE object type Raw
Measurement date 2002-12-03 at 19:01:10 UTC
Participant Unknown
Experimenter MEG
Acquisition
Duration 00:01:01 (HH:MM:SS)
Sampling frequency 600.61 Hz
Time points 36,038
Channels
Magnetometers
Gradiometers and
EEG and
EOG
Stimulus
Head & sensor digitization 146 points
Filters
Highpass 0.10 Hz
Lowpass 172.18 Hz


低频漂移#

低频漂移最容易通过目视检查发现,可使用基本的 plot() 方法;绘制较长的时间跨度并关闭逐通道的直流偏移校正会更有帮助。下面我们绘制 60 秒的数据并显示所有磁强计通道:

mag_channels = mne.pick_types(raw.info, meg="mag")
raw.plot(duration=60, order=mag_channels, n_channels=len(mag_channels), remove_dc=False)
Raw plot

使用较低截止频率的高通滤波即可轻松去除低频漂移(上面看到的漂移周期大约为 20 秒,因此本例中 0.1 Hz 的截止频率大概可以抑制大部分漂移)。

工频噪声#

工频伪迹在频谱图上最容易看出,因此我们用 compute_psd() 来演示。

fig = raw.compute_psd(tmax=np.inf, fmax=250).plot(
    average=True, amplitude=False, picks="data", exclude="bads"
)
# add some arrows at 60 Hz and its harmonics:
for ax in fig.axes[1:]:
    freqs = ax.lines[-1].get_xdata()
    psds = ax.lines[-1].get_ydata()
    for freq in (60, 120, 180, 240):
        idx = np.searchsorted(freqs, freq)
        ax.arrow(
            x=freqs[idx],
            y=psds[idx] + 18,
            dx=0,
            dy=-12,
            color="red",
            width=0.1,
            head_width=3,
            length_includes_head=True,
        )
EEG, Gradiometers, Magnetometers
Effective window size : 3.410 (s)
Plotting power spectral density (dB=True).

这里可以看到 60、120、180 和 240 Hz 处的窄带频率峰——即美国(示例数据采集地)的工频及其 2、3、4 次谐波。其他峰(约 25 至 30 Hz 处及其二次谐波)可能与心跳有关;如下一节所述,使用专门的心跳检测函数在时域中更容易观察到。

心电伪迹(ECG)#

MNE-Python 在 mne.preprocessing 子模块中提供了专用函数 find_ecg_events(),用于从专用 ECG 通道或磁强计(若没有 ECG 通道)中检测心电伪迹。此外,create_ecg_epochs() 函数会在内部调用 find_ecg_events(),并利用得到的事件数组提取以检测到的心电伪迹为中心的 Epochs。下面我们创建这些 Epochs,然后展示检测到的心电伪迹的图像,以及跨伪迹平均的 ERF。尽管 EEG 通道受心电伪迹影响较弱,我们仍会展示全部三种通道类型:

  • EEG (mean), µV
  • Gradiometers (mean), fT/cm
  • Magnetometers (mean), fT
Reconstructing ECG signal from Magnetometers
Setting up band-pass filter from 8 - 16 Hz

FIR filter parameters
---------------------
Designing a two-pass forward and reverse, zero-phase, non-causal bandpass filter:
- Windowed frequency-domain design (firwin2) method
- Hann window
- Lower passband edge: 8.00
- Lower transition bandwidth: 0.50 Hz (-12 dB cutoff frequency: 7.75 Hz)
- Upper passband edge: 16.00 Hz
- Upper transition bandwidth: 0.50 Hz (-12 dB cutoff frequency: 16.25 Hz)
- Filter length: 6007 samples (10.001 s)

Number of ECG events detected : 59 (average pulse 58.9981981638739 / min.)
Not setting metadata
59 matching events found
No baseline correction applied
Using data from preloaded Raw for 59 events and 601 original time points ...
0 bad epochs dropped
Not setting metadata
59 matching events found
No baseline correction applied
0 projection items activated
Not setting metadata
59 matching events found
No baseline correction applied
0 projection items activated
Not setting metadata
59 matching events found
No baseline correction applied
0 projection items activated
combining channels using "mean"
combining channels using "mean"
combining channels using "mean"

磁强计图像中的水平条纹反映了心电伪迹叠加在低频漂移之上(如前文所见);为避免这种情况,可以在调用 create_ecg_epochs() 时传入 baseline=(-0.5, -0.2)。你还可以通过 average() 方法对 ECG Epochs 求平均,再用 mne.Evoked.plot_topomap() 方法快速查看各传感器上与 ECG 相关的场模式:

avg_ecg_epochs = ecg_epochs.average().apply_baseline((-0.5, -0.2))
Applying baseline correction (mode: mean)

同样,我们可以可视化相对于 EOG 响应峰值的不同时刻所对应的场空间模式:

avg_ecg_epochs.plot_topomap(times=np.linspace(-0.05, 0.05, 11))
-0.050 s, -0.040 s, -0.030 s, -0.020 s, -0.010 s, 0.000 s, 0.010 s, 0.020 s, 0.030 s, 0.040 s, 0.050 s, fT

或者,我们可以用 plot() 得到 ERP/F 图,或用 plot_joint() 得到头皮场图与 ERP/F 的组合图。这里我们手动指定了绘制头皮场图的时间点;若不指定,则会根据信号峰值自动选择:

avg_ecg_epochs.plot_joint(times=[-0.25, -0.025, 0, 0.025, 0.25])
  • Gradiometers (203 channels), -0.250 s, -0.025 s, 0.000 s, 0.025 s, 0.250 s
  • Magnetometers (102 channels), -0.250 s, -0.025 s, 0.000 s, 0.025 s, 0.250 s
  • EEG (59 channels), -0.250 s, -0.025 s, 0.000 s, 0.025 s, 0.250 s
No projector specified for this dataset. Please consider the method self.add_proj.

眼电伪迹(EOG)#

与上述心电检测和分段方法类似,MNE-Python 也提供了检测和提取眼电伪迹的函数:find_eog_events() 和 create_eog_epochs()。这里我们同样使用更高层的便捷函数,一步自动查找伪迹并将其提取到 Epochs 对象中。与上面的心电伪迹不同,眼电伪迹通常在 EEG 通道中最明显,但我们仍会展示全部三种通道类型。这次我们也会使用 baseline 参数;注意眨眼次数远少于心跳,因此图像看起来会比较块状:

eog_epochs = mne.preprocessing.create_eog_epochs(raw, baseline=(-0.5, -0.2))
eog_epochs.plot_image(combine="mean")
eog_epochs.average().plot_joint()
  • EEG (mean), µV
  • Gradiometers (mean), fT/cm
  • Magnetometers (mean), fT
  • Gradiometers (203 channels), -0.012 s, 0.188 s, 0.426 s
  • Magnetometers (102 channels), -0.012 s, 0.216 s, 0.383 s
  • EEG (59 channels), -0.008 s, 0.256 s, 0.315 s
Using EOG channel: EOG 061
EOG channel index for this subject is: [375]
Filtering the data to remove DC offset to help distinguish blinks from saccades
Selecting channel EOG 061 for blink detection
Setting up band-pass filter from 1 - 10 Hz

FIR filter parameters
---------------------
Designing a two-pass forward and reverse, zero-phase, non-causal bandpass filter:
- Windowed frequency-domain design (firwin2) method
- Hann window
- Lower passband edge: 1.00
- Lower transition bandwidth: 0.50 Hz (-12 dB cutoff frequency: 0.75 Hz)
- Upper passband edge: 10.00 Hz
- Upper transition bandwidth: 0.50 Hz (-12 dB cutoff frequency: 10.25 Hz)
- Filter length: 6007 samples (10.001 s)

Now detecting blinks and generating corresponding events
Found 10 significant peaks
Number of EOG events detected: 10
Not setting metadata
10 matching events found
Applying baseline correction (mode: mean)
Using data from preloaded Raw for 10 events and 601 original time points ...
0 bad epochs dropped
Not setting metadata
10 matching events found
No baseline correction applied
0 projection items activated
Not setting metadata
10 matching events found
No baseline correction applied
0 projection items activated
Not setting metadata
10 matching events found
No baseline correction applied
0 projection items activated
combining channels using "mean"
combining channels using "mean"
combining channels using "mean"
No projector specified for this dataset. Please consider the method self.add_proj.

小结#

熟悉典型的伪迹形态和幅值,是评估后续伪迹修复效果的关键第一步。一个经验法则是:伪迹幅值应比感兴趣的信号大若干个数量级,并且这类事件应出现多次,这样才有可能找到能有效估计并修复伪迹的信号分解。

本节的其他几个教程演示了各种伪迹修复工具,并讨论了每种技术的优缺点,例如:

此外还有关于通用预处理步骤的教程,例如滤波与重采样,以及剔除坏通道或坏数据段。

脚本总运行时间:(0 分钟 8.753 秒)

示例库由 Sphinx-Gallery 生成