CSP Explorer
A CSP filter and the matching pattern side by side, with the angle between them measured — and what a cross-validated accuracy actually belongs to.
2 claims on this page are 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.
Modes: patterns · pipeline — the widget below runs in patterns. Use Share state to put the exact view in the URL.
What it does
Common spatial patterns fitted to one subject’s left-versus-right hand motor imagery, with the two weight matrices shipped separately and drawn side by side. The widget exists to make one distinction visible: a CSP filter is not a topography and a CSP pattern is.
A filter is the weighting you apply to the sensors to extract a component. Its weights are shaped as much by what it must cancel as by what it keeps, so a large weight can mean “signal here” or “interference I am subtracting here”, and the map cannot tell you which. A pattern is how the component appears on the scalp, which is a forward quantity of the same kind as a column of a leadfield, and it is the map a physiological claim may rest on. Every map in the widget carries the word filter or pattern in its title with the matching caveat underneath, in every mode and in every view.
In pipeline mode the widget shows what an accuracy belongs to: the cross-validated score of a whole pipeline, fold by fold, with the chance interval for the number of trials actually tested — plus the same pipeline with the spatial filter fitted before cross-validation instead of inside it, which is pf-decoding-leakage in one control, and the same pipeline on every candidate subject, so that the selection behind the shipped subject is visible rather than hidden.
Controls
| Control | What it sets |
|---|---|
| Mode | patterns (the two maps and their comparison) or pipeline (accuracies) |
| Component | Which CSP component is drawn, in eigenvalue order |
| View | Filter, pattern, or both side by side |
| Shape only | Rescale both maps to the same range, so any remaining difference is shape rather than amplitude |
| Sign | Fix the arbitrary overall sign of a component, so two maps can be compared without a spurious polarity flip |
| Electrodes, labels | Draw the electrode positions and their names on the maps |
| Weight table | The per-sensor weights of both maps as a table |
Feature set (pipeline) | Which measured configuration to show: no spatial filter, or CSP with 2, 4, 6 or 8 components. These are alternatives, not switches to combine — an accuracy belongs to a whole pipeline, and the widget will not add the parts up |
Fit the filter on all trials (pipeline) | The leakage demonstration: the same data, the same folds, the same seed, with CSP fitted once on every epoch instead of inside each training fold |
Under the two maps, four measured comparisons of the same component’s two vectors: the angle between them (folded to 0–90°, because a component’s sign is arbitrary), their correlation across sensors, their rank agreement on absolute weight — the “which sensors matter?” question — and each map’s peak sensor with whether the two agree. Nothing there is asserted; all four are measured from the vectors as loaded.
Explore the pipeline mode
The page opens in patterns. The second mode is embedded here so it is reachable without a URL change:
What to look for
patterns
- Put the two maps side by side for one component and read the angle the widget prints between them. They are not the same vector and often not close to it.
- Read the peak sensors. When the filter and the pattern peak on the same site it is tempting to conclude the filter map “shows” the source — then check the rank agreement across all the other sensors, which is usually near zero. Agreement at one electrode is not agreement about a topography.
- A filter has to cancel whatever it is not extracting. Large weights far from the component — frontal, occipital — are usually cancellation of a big shared source, not evidence of activity there.
- Turn on shape only: rescaling both maps removes the amplitude difference and leaves only the shape difference. If the two were one map at two scales, they would now coincide. They do not.
- Step through the components in eigenvalue order. The extreme pair carries the class difference; the middle components have eigenvalues near 0.5, which means they separate the classes hardly at all — whatever their maps look like.
pipeline
- Compare the accuracy with and without the spatial filter. CSP is a preprocessing step, not a classifier: what it buys is a handful of informative features instead of one per sensor.
- Turn on fit the spatial filter on all the trials before cross-validating. The number goes up and nothing about the decoder improved: the held-out trials helped choose the filter, so they are no longer held out.
- Read the fold-by-fold scores, not only the mean. With a few dozen trials per class one fold moves the mean by several points; a single accuracy without its spread and its trial count is not a result anyone can check.
- Notice which combinations have a number and which say “not measured”. An accuracy belongs to a whole pipeline; the widget will not add the parts up.
- Chance is 50 % for a two-class problem, but “above 50 %” is not the same as “above chance” — that depends on how many trials were tested, and the widget says so wherever it cannot compute the interval.
Used in
- L5.7 Spatial filters for decoding (
patterns) - L7.1 Decoding and BCI (
pipeline)
Data provenance
ds-eegbci — EEG Motor Movement/Imagery Database (EEGMMIDB), PhysioNet v1.0.0, ODC-By 1.0, open access, dataset DOI 10.13026/C28G6P. Cite Schalk et al. (2004) and Goldberger et al. (2000) as the dataset asks.
The shipped asset is a derivative (filtered, epoched, windowed, decomposed) of subject S002, runs R04 + R08 + R12 — imagine opening and closing the left or the right fist — band-passed 8–30 Hz, window 0.5 to 2.5 s after the cue, 64 channels, 45 epochs (23 left, 22 right), six components, mne.decoding.CSP into linear discriminant analysis, stratified 5-fold cross-validation with a recorded seed, MNE 1.10.2. filters.bin holds the CSP filters and patterns.bin the patterns, each with its own sidecar stating which it is, its layout, and that only the patterns may be read as topographies; the widget contradicts the file loudly if a sidecar ever disagrees with that rule. The topographies are drawn with the shared spherical-spline interpolation matrix for the 64-channel montage, computed once in Python.
Two disclosures that belong on the page and not only in the lesson:
- The subject was selected by accuracy. The rule was stated in advance — the lowest-numbered subject whose mean cross-validated accuracy reaches 0.75 — and the file ships every candidate’s score so the selection is visible. Across the twelve candidates the accuracies run from 44.4 % to 95.6 % with a median of 55.6 %, and eight of the twelve fall inside the chance band for 45 epochs (35.4–64.6 %). The shipped subject’s score is not a typical result for this dataset, for this method, or for EEG motor imagery.
- The candidate set excluded subjects with documented event-timestamp defects (S038, S088, S089, S092, S100, S104), on data-quality grounds and before any accuracy was computed.
TODO(confirm): the std field the file ships is the population standard deviation while the widget’s own table shows the sample one; both are computed and the widget names which convention the file used, and with five folds they differ by about 12 %.
Open the code
site/src/components/widgets/w-csp-explorer/ — Widget.svelte, index.ts, meta.ts, the data and comparison layer, the topomap and colour modules, README.md, and a test suite that checks the sidecars’ own claims against the widget’s rule and verifies that the filters and the patterns really are different vectors. Repository link: TODO(confirm) (GitHub org/repo).