ICA after interpolation without rank adjustment
Symptom. Duplicated or degenerate components; ICA fails to converge.
1 claim on this page is unverified. TODO(confirm) marks a specific statement the author has not yet checked against a
primary source. Everything else on this page has been reviewed. Treat a marked claim as
provisional and go to the cited source rather than quoting the sentence.
Symptom
An ICA decomposition that looks wrong in a characteristic way: pairs of components with near-identical topographies and mirror-image time courses; components with speckled, physically implausible maps; components whose spectra are flat noise; a decomposition that changes completely when you re-run it with a different seed. Or, more bluntly, the fit does not converge, or converges after many more iterations than usual. Downstream, the classifier (or you) cannot label half the components, and removing any of them changes the data in ways that do not correspond to any artifact.
Cause
ICA is a change of basis. It can only find as many independent components as the data has independent dimensions — its rank. A recording’s rank is not its channel count if anything linear has been done to it:
- each interpolated channel is a weighted sum of the remaining good channels, so it adds a row without adding a dimension;
- an average reference makes the channels sum to zero at every time point, costing one more dimension;
- a reconstructed online-reference channel added back as zeros adds a row and no dimension;
- SSP projections remove exactly one dimension each.
A 64-channel recording with 3 interpolated channels and an average reference has 64 rows and rank 60. Nothing in the array’s shape records this, and the default number of components in most implementations is derived from the number of channels. Asking for 64 components from rank-60 data asks the estimator for four directions that do not exist; it obliges, by fitting numerical noise, and the four spurious directions are not neatly isolated — they degrade the whole decomposition.
Detect
- Compute the rank explicitly and compare it with the channel count (
mne.compute_rank(inst, rank='info'), or the arithmetic above done by hand). A gap you cannot account for is the finding. - Look at the singular values of the channel covariance: a sharp drop to near-zero after k values means the true rank is k.
- Inspect the decomposition for near-duplicate pairs (high absolute correlation between component time courses, or near-identical topographies of opposite sign).
- Re-run the fit with a different seed. A well-conditioned decomposition is broadly reproducible up to order and sign; a rank-deficient one is not.
- Check the pipeline log for every step that touched the channel set: interpolation, referencing, projections, and any channel dropped after the montage was set.
Fix
- Carry the rank through the pipeline as a number, updated at every linear step, and log it (L2.8). Start at the channel count and subtract: one per interpolated channel, one for an average reference, one per projector.
- Pass it explicitly:
ICA(n_components=rank, ...), or MNE’srankargument, rather than relying on a default derived from the channel count. - Prefer to detect bad channels, re-reference and interpolate before the ICA fit, in the canonical order of L2.8, so that there is one rank to track rather than a moving target.
- If rank is low enough that the decomposition is unstable — few channels, many interpolated, short recording — reduce the requested number of components deliberately and report it, rather than letting the estimator discover the deficiency for you.
- Record the seed, so that “the components changed” is a statement you can check rather than a suspicion.
Example

TODO(confirm): caption and numbers, once data/scripts/make_figures_p2.py has written /figures/pitfalls/pf-interpolation-rank.png and its sidecar — including the channel count, the number of interpolated channels, the resulting rank, and the ICA method and seed. The description above states what the mechanism requires the figure to show; the sidecar’s own alt and caption are the authority once it exists.