Total Perspective Vortex
A brain-computer interface that classifies EEG motor-imagery signals: a from-scratch CSP spatial filter feeds logistic regression, wired as a scikit-learn pipeline.
- 109 subjects
- 8–30 Hz band-pass
My partImplemented Common Spatial Patterns from scratch — trace-normalised per-class covariances, a generalised eigenvalue decomposition and log-variance features — as a scikit-learn transformer.
- ROLE
- Solo
- CONTEXT
- École 42 · AI projects
- STATUS
- Done
- RESULT
- The pipeline runs end to end; on the single logged run (subject 4) it reaches 0.53 cross-validated accuracy, near the two-class chance level. The from-scratch CSP and the scikit-learn integration are the work, not the score.
- LAST UPDATED
- 26 Sep 2026
Data
PhysioNet EEG Motor Movement/Imagery: 109 subjects, 64-channel EEG at 160 Hz; runs 3–14, left/right fist and both fists/both feet.
What I built
Solo
- Implemented Common Spatial Patterns from scratch — trace-normalised per-class covariances, a generalised eigenvalue decomposition and log-variance features — as a scikit-learn transformer.
- Built the pipeline: the custom CSP feeding logistic regression, with k-fold cross-validation and model save and load.
- Wrote the MNE preprocessing layer: EDF loading, an 8–30 Hz band-pass, event extraction and epoching.
- Built the command-line tool (train, predict, stream) and a batch loop over all 109 subjects.
Key choices
- CSP written from scratch, not the library one
- The subject requires a hand-implemented dimensionality reduction, so the covariances, the generalised eigenvalue problem and the projection matrix are computed directly; MNE's CSP is kept only as a reference to check against.
- A scikit-learn-compatible transformer
- The CSP subclasses BaseEstimator and TransformerMixin, so it composes with logistic regression in one pipeline and runs through cross-validation unchanged.
- An 8–30 Hz band and a sensorimotor focus
- Filtering is restricted to the mu and beta bands where motor-imagery activity lives, with epochs cut from −0.5 s to 4 s around each event.
Results
The pipeline runs end to end; on the single logged run (subject 4) it reaches 0.53 cross-validated accuracy, near the two-class chance level. The from-scratch CSP and the scikit-learn integration are the work, not the score.
Limits
- Stream mode is offline replay, not live acquisition: it loops over pre-computed epochs one at a time and prints the processing time.
- One global model per task type, overwritten on each training run; there are no per-subject saved models.
- The evaluation is optimistic: cross-validation is measured on a single run, with no held-out subject and no separate validation set.
- On the one logged run, classification stays near the two-class chance level — the from-scratch CSP and the scikit-learn integration are the substance, not the score.
Questions about this project? → Email me