Skip to content

FIX keep CrossSession results session-specific for custom CV folds - #1210

Merged
bruAristimunha merged 9 commits into
NeuroTechX:developfrom
lindicaphxag-tech:fix/cross-session-per-session-scoring
Oct 4, 2026
Merged

bruAristimunha merged 9 commits into
NeuroTechX:developfrom
lindicaphxag-tech:fix/cross-session-per-session-scoring

Conversation

@lindicaphxag-tech

@lindicaphxag-tech lindicaphxag-tech commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Summary

CrossSessionEvaluation supports arbitrary scikit-learn cv_class values, so a custom test fold can contain more than one recording session. The current scoring path still assumes each fold holds out exactly one session and labels the entire fold with groups[test][0].

That silently gives multi-session folds the provenance of whichever session appears first.

Context in the evaluation-safety series

This is a follow-up found while validating the custom-CV path around #1207. #1207 makes explicit top-level splitters usable; this PR closes the corresponding result-provenance invariant for CrossSessionEvaluation: once a custom fold may contain multiple sessions, result rows must still remain session-specific rather than inheriting the first group label.

Fix

Keep fitting once per CV fold, but score and store each held-out session separately.

  • the legacy evaluation path partitions each test fold by its actual session before scoring;
  • the flattened/parallel path enables the existing score_per_session machinery, which already implements the same grouping;
  • default Leave-One-Session-Out behavior is unchanged because each fold already contains one session.

Regression coverage

A focused test uses GroupKFold(n_splits=2) on a 4-session, 2-subject fake dataset. Each CV fold therefore holds out two sessions at once. It verifies that:

  • results contain one row per real held-out session;
  • all four session identities are preserved;
  • n_samples_test is session-specific;
  • flattened and legacy execution produce identical result keys, scores, and test sizes.

No splitter API or grouping semantics are changed.

Copy link
Copy Markdown
Contributor Author

Exact-head validation is green on 92609a3c: MOABB pre-commit passes and the focused multi-session custom-CV regression passes on the current branch. The regression verifies that parallel and legacy CrossSession paths emit the same per-session provenance/scores across a 4-session GroupKFold split instead of collapsing a multi-session test fold onto its first session. Evidence: https://github.com/lindicaphxag-tech/lindicaphxag-tech/actions/runs/37145135118. I’ll hold scope here for review.

Copy link
Copy Markdown
Contributor Author

Updated exact-head validation: on 150ada97754deff06ef246edcb726101ae69e5c0, current-head pre-commit and the multi-session custom-CV provenance regression both pass. This supersedes the earlier evidence SHA after the branch cleanup/squash. Evidence: https://github.com/lindicaphxag-tech/lindicaphxag-tech/actions/runs/37183338993. I’ll hold this head for review.

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Copy link
Copy Markdown
Contributor Author

@bruAristimunha this is the smallest independent piece of the evaluation-provenance series and is ready for review. It only fixes CrossSession custom-CV folds that hold out multiple sessions: one fit is retained, but scoring/result attribution stays session-specific, with legacy/parallel parity covered. It does not depend on #1207/#1211, so it can merge independently; I’ll keep this head frozen unless review finds an issue.

@bruAristimunha bruAristimunha left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @lindicaphxag-tech. The fix is well scoped to CrossSessionEvaluation; the default LeaveOneGroupOut path still produces one row per fold since every fold holds exactly one session (the np.unique(test_sessions) loop collapses to one iteration), and the GroupKFold(n_splits=2) regression checks that the flattened and legacy paths agree on keys, scores and n_samples_test. I've just approved the Actions run; I'll approve the PR once Test/Test-braindecode are green on 150ada9. One request: since the flattened path previously returned one aggregated row per fold and now one per held-out session, please mention it under API changes in whats_new.rst as well.

@bruAristimunha bruAristimunha left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CI is green on 150ada9 (Test matrix, Test-braindecode, Docs). Approving — please still add the whats_new API note about one row per held-out session for custom folds before merge if you get a chance, @lindicaphxag-tech. Thanks.

@bruAristimunha
bruAristimunha merged commit ae47249 into NeuroTechX:develop Oct 4, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants