✦ Day 06 · Signal Separation

Independent Component
Analysis (ICA)

Solving the cocktail party problem — decompose mixed electrode signals into statistically independent sources, identify which ones are artifacts, and surgically remove them while preserving the neural signal.

🍸 Cocktail Party Problem 🧠 Unmixing Matrix W 👁 Eye Blink Removal ❤ ECG Removal 🐍 mne.preprocessing.ICA

Independent Component Analysis (ICA) is the workhorse of EEG artifact removal. It solves the cocktail party problem: given a room full of people talking simultaneously (mixed signals at each microphone/electrode), can we recover each individual speaker’s voice? ICA finds an unmixing matrix W that decomposes the mixed electrode signals into statistically independent sources — some brain, some artifact.


1

The Cocktail Party Problem
Mixing & Unmixing Matrices

Each EEG electrode records a weighted sum of all active sources in the brain (and body). Mathematically: X = A · S, where X is the electrode data, A is the (unknown) mixing matrix encoding how sources project to sensors, and S is the (unknown) source matrix containing the independent components.

ICA estimates the unmixing matrix W ≈ A−1 by maximizing the statistical independence of the recovered sources. The key assumption: brain sources and artifacts are generated by different physiological processes and are therefore statistically independent.

Cohen’s perspective (ANTS Ch. 27): ICA doesn’t “know” what an eye blink looks like. It simply finds directions in the data where sources are maximally non-Gaussian (since mixtures become more Gaussian by the Central Limit Theorem). The interpretation — “this is an eye blink” — is entirely your job.


2

Fitting ICA in MNE
Preprocessing Requirements

ICA is sensitive to the statistical properties of the input data. Two critical requirements:

1. High-pass filter at ≥1 Hz — low-frequency drifts dominate the variance and cause ICA to waste components on slow trends instead of artifacts.

2. Sufficient data length — rule of thumb: at least 20× the number of channels squared data points (e.g., for 64 channels: 64² × 20 = ~82,000 samples).

Python
from mne.preprocessing import ICA

# Create a copy filtered at 1 Hz for ICA fitting
raw_filt = raw.copy().filter(l_freq=1.0, h_freq=None)

# Fit ICA with n_components determined automatically
ica = ICA(n_components=0.99,  # explain 99% variance
          method='infomax',
          random_state=42,
          max_iter=800)

ica.fit(raw_filt)
print(ica)  # shows number of components found

Critical: Fit ICA on filtered data but apply the removal to the original (unfiltered or lightly filtered) data. This preserves your low-frequency neural signals.


3

Identifying Artifact Components
Spatial Maps, Time Courses & Automated Detection

After fitting, you need to decide which components are artifacts. Three complementary approaches:

Visual inspection: Plot the spatial topography (ica.plot_components()) and time course (ica.plot_sources()). Eye blinks have a characteristic frontal dipolar pattern; heartbeats show a strong left-lateralized pattern.

Correlation with EOG/ECG: Use ica.find_bads_eog() and ica.find_bads_ecg() to automatically find components correlated with reference channels.

ICLabel (Day 7): Use deep learning to automatically classify all components.

Python
# Visualize component topographies
ica.plot_components(picks=range(20))

# Auto-detect EOG-related components
eog_indices, eog_scores = ica.find_bads_eog(raw)
ica.exclude = eog_indices
print(f"EOG components: {eog_indices}")

# Apply ICA removal to the ORIGINAL raw data
raw_clean = ica.apply(raw.copy())

How many components to remove? Typically 1–3 for eye artifacts and 0–1 for heartbeat. If you find yourself removing >5 components, something may be wrong with your ICA decomposition (insufficient data, bad channels not removed, filter too low).