-
Notifications
You must be signed in to change notification settings - Fork 576
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ENH] Allow Decoder to work with surface objects #4205
base: main
Are you sure you want to change the base?
Conversation
👋 @ymzayek Thanks for creating a PR! Until this PR is ready for review, you can include the [WIP] tag in its title, or leave it as a github draft. Please make sure it is compliant with our contributing guidelines. In particular, be sure it checks the boxes listed below.
For new features:
For bug fixes:
We will review it as quick as possible, feel free to ping us with questions if needed. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4205 +/- ##
==========================================
+ Coverage 91.85% 92.01% +0.16%
==========================================
Files 144 145 +1
Lines 16419 16724 +305
Branches 3434 3548 +114
==========================================
+ Hits 15082 15389 +307
+ Misses 792 766 -26
- Partials 545 569 +24
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
@bthirion WDYT about handling FREM in the decoder? Is it applicable/used for surface analysis? This would require adapting |
Adapting ReNA (and Ward) to the surface is technically easy. We should definitely do that. |
Well yes and no. I think writing a new image check function that wraps check_niimg and handles surface image separately (we don't want to call |
Ye, but behind that, the algorithm will be a bit different, given that the connectivity structure is then defined by the mesh and no longer by the voxel grid. |
What would be the equivalent calculation of edges and weights for surface data? |
edges are the mesh edges: each triangle results into three edges. |
The comment from #4227 (review) is meant to be here
|
7bf7590
to
00980ea
Compare
mask : :class:`numpy.ndarray`, shape (nx, ny, nz) | ||
mask : :class:`numpy.ndarray` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there is nothing in this function that requires that shape
nilearn/regions/rena_clustering.py
Outdated
else: | ||
edges, weight = _make_edges_and_weights(X, mask_img) | ||
|
||
# TODO : deal with dict results if surface analysis |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now failure is here because edges and weights are returned in a dictionary with keys representing the surface image object mesh and data keys for the different hemispheres
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bthirion I'm a bit stuck here. Does it make more sense to let ReNA run on each hemisphere separately and then concatenate the results in X_train on the level of the call from the decoder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could great a unique graph that would stack the data from the two hemispheres. This graph would have 2 connected components. This would have the advantage to make the use on surface transparent for other functions.
TODO:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thx ! Thi is great
faces : ndarray | ||
The vertex indices corresponding the mesh triangles. | ||
|
||
mask : boolean |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how to make sense of mask in this function, given that the edge ordering is unclear at that point ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maks is on vertices, right ? Then it makes sense. But the dosctring has to be improved.
@@ -171,11 +291,20 @@ def _weighted_connectivity_graph(X, mask_img): | |||
""" | |||
n_features = X.shape[1] | |||
|
|||
edges, weight = _make_edges_and_weights(X, mask_img) | |||
if isinstance(mask_img, SurfaceImage): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not finish this section under the conditional for surface. It probably needs to be updated according to this comment #4205 (comment)
And then the whole pipeline needs to be validated
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There remain a few comments to address, but it looks good overall.
assert model.scoring == "roc_auc" | ||
|
||
model.score(X, y) | ||
accuracy_score(y, y_pred) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could additionally check that the accuracy score are reasonable (close to chance I guess) ?
assert model.scoring == "r2" | ||
|
||
model.score(X, y) | ||
r2_score(y, y_pred) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we could additionally check that the accuracy score are reasonable (close to chance I guess) ?
Changes proposed in this pull request:
TODO
Examples to adapt: