mne-python icon indicating copy to clipboard operation
mne-python copied to clipboard

ENH: decoding module 2025

Open Genuster opened this issue 4 months ago • 1 comments

I'll summarise here my work for GSoC 2025 and describe a few ideas I had throughout for future improvements.

My main goal (following Mike X Cohen's paper) was to implement an sklearn transformer for generalized eigendecomposition (GED) that would generalize algorithms like CSP, xDAWN, etc. The transformer was implemented in #13259 supporting restriction/whitening for rank-deficient covariances (see the implementation details entry).

GED-based algorithms are spatial filters and essentially separate sources. The SpatialFilter container for their (and LinearModel) visualisation was implemented in #13332 and currently supports scree plot and topomaps for filters and patterns (see, for example, xDAWN example).

  • [ ] It would be useful to have a tutorial showing how to implement custom covariance estimation / eigenvalue sorting functions for _GEDTransformer and investigate the resulting sources with SpatialFilter
    • [ ] After that _GEDTransformer could be made public
  • [ ] _GEDTransformer could have inverse_transform similarly to how CSP does, but generalize it to the "multi" decomposition as in the XdawnTransformer case
  • [ ] Following ICA visualisation of spatially filtered time-series, it would be nice to have similar function for other spatial filters, but will require adding a new branch for SpatialFilter (or unifying it with ICA) in mne.viz._figure.BrowserBase
  • [ ] SpatialFilter is intended for visualisation of multiple spatial filters fixed over time, but there are cases such as EMS, LinearModel on vectorized data, SlidingEstimator wrapping LinearModel (and potentially GeneralizingEstimator) where each time point of an epoch can have different pattern. These can be conveniently visualised using EvokedArray and could be implemented either as a second use case for SpatialFilter or in an another container inheriting from EvokedArray, for example
  • [ ] mne.preprocessing.Xdawn works with Epochs and so can't directly inherit from _GEDTransformer, but perhaps _GEDTransformer's logic in fit and transform could be modularised and then reused in Xdawn.
  • [ ] SlidingEstimator and GeneralizingEstimator currently apply wrapped classifier per time-point. This can be generalized to sliding windows, where search lights will pass the windows to the downstream pipeline to cover cases like: SlidingEstimator(make_pipeline(Vectorizer(), SVC())) or, using pyRiemann transformers, SlidingEstimator(make_pipeline(XdawnTransformer(), Covariances(), TangentSpace(), SVC())) for ERP decoding.

The second part of the GSoC was to make the decoding classes more compliant with new sklearn (1.6+) estimator checks and data validation. LinearModel has been made a meta-estimator and reworked in #13361, while sklearn compliance for other classes was corrected in #13393.

Genuster avatar Aug 23 '25 11:08 Genuster

Thanks for the summary and the great work @Genuster !

larsoner avatar Aug 24 '25 14:08 larsoner