Note
Go to the end to download the full example code. or to run this example in your browser via Binder
A introduction tutorial to fMRI decoding¶
Here is a simple tutorial on decoding with nilearn. It reproduces the Haxby et al.[1] study on a face vs cat discrimination task in a mask of the ventral stream.
This tutorial is meant as an introduction to the various steps of a decoding
analysis using Nilearn meta-estimator: Decoder
It is not a minimalistic example, as it strives to be didactic. It is not meant to be copied to analyze new data: many of the steps are unnecessary.
Retrieve and load the fMRI data from the Haxby study¶
First download the data¶
The fetch_haxby
function will download the
Haxby dataset if not present on the disk, in the nilearn data directory.
It can take a while to download about 310 Mo of data from the Internet.
from nilearn import datasets
# By default 2nd subject will be fetched
haxby_dataset = datasets.fetch_haxby()
# 'func' is a list of filenames: one for each subject
fmri_filename = haxby_dataset.func[0]
# print basic information on the dataset
print(f"First subject functional nifti images (4D) are at: {fmri_filename}")
[get_dataset_dir] Dataset found in /home/runner/nilearn_data/haxby2001
First subject functional nifti images (4D) are at: /home/runner/nilearn_data/haxby2001/subj2/bold.nii.gz
Visualizing the fMRI volume¶
One way to visualize a fMRI volume is
using plot_epi
.
We will visualize the previously fetched fMRI
data from Haxby dataset.
Because fMRI data are 4D
(they consist of many 3D EPI images),
we cannot plot them directly using plot_epi
(which accepts just 3D input).
Here we are using mean_img
to
extract a single 3D EPI image from the fMRI data.
from nilearn import plotting
from nilearn.image import mean_img
plotting.view_img(mean_img(fmri_filename, copy_header=True), threshold=None)
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/numpy/core/fromnumeric.py:758: UserWarning: Warning: 'partition' will ignore the 'mask' of the MaskedArray.
a.partition(kth, axis=axis, kind=kind, order=order)
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
Feature extraction: from fMRI volumes to a data matrix¶
These are some really lovely images, but for machine learning
we need matrices to work with the actual data. Fortunately, the
Decoder
object we will use later on can
automatically transform Nifti images into matrices.
All we have to do for now is define a mask filename.
A mask of the Ventral Temporal (VT) cortex coming from the Haxby study is available:
mask_filename = haxby_dataset.mask_vt[0]
# Let's visualize it, using the subject's anatomical image as a
# background
plotting.plot_roi(mask_filename, bg_img=haxby_dataset.anat[0], cmap="Paired")
<nilearn.plotting.displays._slicers.OrthoSlicer object at 0x7f469558b820>
Load the behavioral labels¶
Now that the brain images are converted to a data matrix, we can apply machine-learning to them, for instance to predict the task that the subject was doing. The behavioral labels are stored in a CSV file, separated by spaces.
We use pandas to load them in an array.
import pandas as pd
# Load behavioral information
behavioral = pd.read_csv(haxby_dataset.session_target[0], delimiter=" ")
print(behavioral)
labels chunks
0 rest 0
1 rest 0
2 rest 0
3 rest 0
4 rest 0
... ... ...
1447 rest 11
1448 rest 11
1449 rest 11
1450 rest 11
1451 rest 11
[1452 rows x 2 columns]
The task was a visual-recognition task, and the labels denote the experimental condition: the type of object that was presented to the subject. This is what we are going to try to predict.
conditions = behavioral["labels"]
print(conditions)
0 rest
1 rest
2 rest
3 rest
4 rest
...
1447 rest
1448 rest
1449 rest
1450 rest
1451 rest
Name: labels, Length: 1452, dtype: object
Restrict the analysis to cats and faces¶
As we can see from the targets above, the experiment contains many conditions. As a consequence, the data is quite big. Not all of this data has an interest to us for decoding, so we will keep only fMRI signals corresponding to faces or cats. We create a mask of the samples belonging to the condition; this mask is then applied to the fMRI data to restrict the classification to the face vs cat discrimination.
The input data will become much smaller (i.e. fMRI signal is shorter):
condition_mask = conditions.isin(["face", "cat"])
Because the data is in one single large 4D image, we need to use index_img to do the split easily.
from nilearn.image import index_img
fmri_niimgs = index_img(fmri_filename, condition_mask)
We apply the same mask to the targets
(216,)
Decoding with Support Vector Machine¶
As a decoder, we use a Support Vector Classifier with a linear kernel. We
first create it using by using Decoder
.
from nilearn.decoding import Decoder
decoder = Decoder(
estimator="svc", mask=mask_filename, standardize="zscore_sample"
)
The decoder object is an object that can be fit (or trained) on data with labels, and then predict labels on data without.
We first fit it on the data
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
We can then predict the labels from the data
prediction = decoder.predict(fmri_niimgs)
print(prediction)
['face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'cat'
'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'face' 'face' 'face'
'face' 'face' 'face' 'face' 'face' 'face' 'cat' 'cat' 'cat' 'cat' 'cat'
'cat' 'cat' 'cat' 'cat' 'face' 'face' 'face' 'face' 'face' 'face' 'face'
'face' 'face' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat'
'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'face' 'face' 'face'
'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face'
'face' 'face' 'face' 'face' 'face' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat'
'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat'
'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face'
'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'cat' 'cat' 'cat'
'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'face' 'face' 'face' 'face' 'face'
'face' 'face' 'face' 'face' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat'
'cat' 'cat' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face'
'face' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'face'
'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'cat' 'cat' 'cat'
'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat'
'cat' 'cat' 'cat' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face'
'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face' 'face'
'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat' 'cat']
Note that for this classification task both classes contain the same number of samples (the problem is balanced). Then, we can use accuracy to measure the performance of the decoder. This is done by defining accuracy as the scoring. Let’s measure the prediction accuracy:
print((prediction == conditions).sum() / float(len(conditions)))
1.0
This prediction accuracy score is meaningless. Why?
Measuring prediction scores using cross-validation¶
The proper way to measure error rates or prediction accuracy is via cross-validation: leaving out some data and testing on it.
Manually leaving out data¶
Let’s leave out the 30 last data points during training, and test the prediction on these 30 last points:
fmri_niimgs_train = index_img(fmri_niimgs, slice(0, -30))
fmri_niimgs_test = index_img(fmri_niimgs, slice(-30, None))
conditions_train = conditions[:-30]
conditions_test = conditions[-30:]
decoder = Decoder(
estimator="svc", mask=mask_filename, standardize="zscore_sample"
)
decoder.fit(fmri_niimgs_train, conditions_train)
prediction = decoder.predict(fmri_niimgs_test)
# The prediction accuracy is calculated on the test data: this is the accuracy
# of our model on examples it hasn't seen to examine how well the model perform
# in general.
predicton_accuracy = (prediction == conditions_test).sum() / float(
len(conditions_test)
)
print(f"Prediction Accuracy: {predicton_accuracy:.3f}")
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
Prediction Accuracy: 0.767
Implementing a KFold loop¶
We can manually split the data in train and test set repetitively in a KFold strategy by importing scikit-learn’s object:
from sklearn.model_selection import KFold
cv = KFold(n_splits=5)
for fold, (train, test) in enumerate(cv.split(conditions), start=1):
decoder = Decoder(
estimator="svc", mask=mask_filename, standardize="zscore_sample"
)
decoder.fit(index_img(fmri_niimgs, train), conditions[train])
prediction = decoder.predict(index_img(fmri_niimgs, test))
predicton_accuracy = (prediction == conditions[test]).sum() / float(
len(conditions[test])
)
print(
f"CV Fold {fold:01d} | "
f"Prediction Accuracy: {predicton_accuracy:.3f}"
)
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
CV Fold 1 | Prediction Accuracy: 0.886
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
CV Fold 2 | Prediction Accuracy: 0.767
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
CV Fold 3 | Prediction Accuracy: 0.767
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
CV Fold 4 | Prediction Accuracy: 0.698
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
CV Fold 5 | Prediction Accuracy: 0.744
Cross-validation with the decoder¶
The decoder also implements a cross-validation loop by default and returns an array of shape (cross-validation parameters, n_folds). We can use accuracy score to measure its performance by defining accuracy as the scoring parameter.
n_folds = 5
decoder = Decoder(
estimator="svc",
mask=mask_filename,
standardize="zscore_sample",
cv=n_folds,
scoring="accuracy",
)
decoder.fit(fmri_niimgs, conditions)
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
Cross-validation pipeline can also be implemented manually. More details can be found on scikit-learn website.
Then we can check the best performing parameters per fold.
print(decoder.cv_params_["face"])
{'C': [100.0, 100.0, 100.0, 100.0, 100.0]}
Note
We can speed things up to use all the CPUs of our computer with the n_jobs parameter.
The best way to do cross-validation is to respect the structure of the experiment, for instance by leaving out full runs of acquisition.
The number of the run is stored in the CSV file giving the behavioral data. We have to apply our run mask, to select only cats and faces.
run_label = behavioral["chunks"][condition_mask]
The fMRI data is acquired by runs, and the noise is autocorrelated in a given run. Hence, it is better to predict across runs when doing cross-validation. To leave a run out, pass the cross-validator object to the cv parameter of decoder.
from sklearn.model_selection import LeaveOneGroupOut
cv = LeaveOneGroupOut()
decoder = Decoder(
estimator="svc", mask=mask_filename, standardize="zscore_sample", cv=cv
)
decoder.fit(fmri_niimgs, conditions, groups=run_label)
print(decoder.cv_scores_)
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/image/resampling.py:489: UserWarning: The provided image has no sform in its header. Please check the provided file. Results may not be as expected.
warnings.warn(
{'cat': [1.0, 1.0, 1.0, 1.0, 0.9629629629629629, 0.8518518518518519, 0.9753086419753086, 0.40740740740740744, 0.9876543209876543, 1.0, 0.9259259259259259, 0.8765432098765432], 'face': [1.0, 1.0, 1.0, 1.0, 0.9629629629629629, 0.8518518518518519, 0.9753086419753086, 0.40740740740740744, 0.9876543209876543, 1.0, 0.9259259259259259, 0.8765432098765432]}
Inspecting the model weights¶
Finally, it may be useful to inspect and display the model weights.
Turning the weights into a nifti image¶
We retrieve the SVC discriminating weights
coef_ = decoder.coef_
print(coef_)
[[-3.89376503e-02 -1.87167159e-02 -3.23027372e-02 -2.88746885e-02
4.18697173e-02 1.10743637e-02 1.69998417e-02 -5.50953117e-02
-1.94204145e-02 -3.51228119e-02 1.08509462e-02 -1.28796969e-02
-1.54676672e-02 -3.78907805e-02 -3.69167738e-02 2.28087673e-02
6.56417331e-03 -7.65753475e-03 1.67106831e-02 -8.02132894e-03
5.29515587e-02 -8.17593402e-02 -6.36992350e-02 2.41325950e-02
4.59875420e-02 -2.22603530e-02 -1.77308957e-02 2.22197892e-02
-9.53207885e-03 5.76046433e-02 2.14299817e-02 -9.14227393e-02
4.03657831e-03 -2.89276469e-02 -3.89030475e-02 -3.35114191e-02
2.21401846e-03 8.73133048e-03 -3.37415917e-02 -2.41276424e-02
-6.81650455e-02 1.65404553e-02 2.70783390e-02 -6.56847467e-03
-1.21663231e-02 5.47673278e-02 8.13279211e-03 3.60955649e-02
-1.52764501e-02 7.02911817e-02 1.28095194e-03 2.08007056e-02
-4.09940773e-03 3.72428985e-02 -3.77393283e-02 -1.03858419e-02
-2.38238504e-02 -5.48880056e-02 4.43027341e-02 -1.47419308e-01
-2.34043355e-02 1.87113605e-02 6.65859799e-02 -9.07604448e-02
-1.22034216e-02 -2.95653307e-03 3.22092373e-02 -3.04054521e-02
6.15343595e-02 1.12250450e-02 1.93776914e-02 -1.30542323e-02
4.42976490e-02 -2.23066406e-02 6.88148379e-02 1.69390119e-02
1.78947582e-02 1.00276043e-02 2.99186326e-02 -2.52170187e-02
1.06154246e-02 -6.31962749e-03 2.21514465e-03 -2.23348442e-02
1.42561274e-02 -1.53124332e-02 -1.98227226e-02 -4.32638788e-02
-4.55125353e-02 3.41589122e-02 -2.79200232e-02 -2.80908851e-02
-3.70157389e-02 -5.71450886e-02 -6.98948831e-02 3.20183370e-03
-8.35464757e-03 -3.37627687e-02 3.04261111e-02 8.68460584e-03
6.19370708e-03 5.94177979e-02 9.07297396e-03 -1.48931818e-02
1.43559610e-02 -1.09026629e-02 2.67697668e-02 4.73787351e-02
-2.96430823e-02 3.09423311e-02 1.57929557e-02 -3.16722249e-02
-4.00105627e-02 -5.40261575e-02 2.82613450e-02 -1.12101141e-02
-5.45402113e-02 6.32177298e-02 -1.49997159e-02 2.47545570e-03
-4.56642642e-02 -1.83882638e-02 1.19957394e-02 -3.72171549e-02
-2.25528412e-03 4.58655644e-02 4.79168306e-02 2.51821598e-03
-4.31723743e-02 -5.35327942e-03 5.76994197e-02 7.40837509e-03
-3.20589645e-02 4.35705550e-03 1.68302919e-02 -2.92570189e-02
-2.24506204e-03 -8.30214964e-03 -1.00011838e-02 2.17137539e-02
-1.92615053e-03 -1.33222499e-02 -2.80301315e-02 -1.75293442e-02
-9.17812360e-03 -7.09955535e-03 -1.43031378e-02 5.06831444e-02
-1.84812372e-02 -4.71506103e-02 1.72569384e-02 -4.76642530e-02
-9.09068764e-04 4.00768718e-02 7.53994623e-02 7.25623514e-03
4.82605027e-02 4.50555733e-02 3.61202053e-02 -8.16485321e-03
1.95406187e-02 3.57883823e-02 4.89303443e-02 3.82974039e-02
6.23920014e-02 6.13674371e-02 -1.68750930e-02 1.66514477e-02
3.35521151e-02 -1.80212889e-02 4.46411568e-02 -3.53244881e-02
-3.67293469e-02 -4.62242073e-03 4.86827780e-02 3.39666350e-02
6.21718714e-03 1.73612540e-02 2.01698649e-02 2.17098536e-02
2.91413881e-02 2.37776267e-02 4.84698243e-02 -9.22617192e-03
-2.82637450e-02 -2.13781363e-02 1.80798244e-03 4.79686509e-02
-9.78880399e-03 1.11431053e-02 -1.65018313e-02 -2.89088584e-02
2.42851321e-02 -1.22348113e-02 -2.92870196e-02 -2.89846915e-02
-3.39532397e-02 -3.65261736e-03 2.65325239e-02 4.58043922e-02
-5.93380440e-02 -2.13630574e-02 -3.09407863e-02 5.50179511e-02
-3.38816696e-02 6.12599590e-03 1.41484489e-02 1.10215895e-02
5.33811841e-02 -2.12339530e-02 6.37425504e-03 -1.13075688e-02
-2.64226980e-02 -2.22400249e-02 -5.31920445e-02 -3.98653253e-02
-1.29727938e-01 -3.28092705e-02 -2.89711599e-02 -9.13464501e-03
-7.28719182e-03 -3.71052918e-02 -6.34904361e-02 2.04365179e-03
-8.26796393e-02 -6.71213542e-02 -2.29141415e-03 -2.33452201e-02
1.77915311e-02 -8.74667743e-02 -2.76481393e-03 -4.38275720e-02
-1.28050564e-02 2.78033421e-02 -4.32695697e-02 -3.22689490e-02
-2.28029414e-02 -2.57415566e-02 2.03623800e-02 -9.90243399e-03
-3.15033808e-02 -1.81419789e-02 -1.12326797e-03 -4.17432012e-02
-6.23481454e-02 2.54501549e-04 -6.73680590e-02 6.53965701e-02
1.06520217e-02 2.21984741e-02 -1.98728716e-02 -1.85520848e-02
4.05703343e-02 -3.02839449e-02 -8.10051793e-02 -7.42460223e-02
-4.93847852e-02 -1.01772381e-02 1.09406184e-02 -4.49253373e-02
2.92748232e-02 7.05293668e-03 5.07538464e-03 -4.84057061e-03
2.48761824e-03 3.00654600e-02 -2.63087550e-03 4.64685969e-03
7.90209473e-02 1.04859220e-02 1.68079903e-02 -4.36719586e-02
-1.08855306e-02 2.10243107e-02 -4.41965192e-02 3.16490826e-03
6.98670669e-02 8.61630644e-02 4.96235694e-02 6.03918927e-03
5.56494067e-02 -2.98918892e-02 4.13043417e-03 -3.21952587e-02
-3.14991164e-02 -5.31277259e-02 2.67256190e-02 3.14428457e-02
6.67096158e-03 -1.28703185e-02 2.20150857e-02 5.68525799e-02
2.25604037e-02 -2.04616720e-02 5.10343729e-03 2.85357305e-02
-1.81663815e-02 -8.48422935e-03 -3.18825114e-02 -1.18497747e-02
-4.10846642e-02 3.11774236e-02 9.63467694e-03 -8.25920522e-03
-3.12227964e-02 8.57647339e-03 -9.70185354e-03 1.32375913e-02
4.06447037e-02 8.23427807e-03 -3.27354357e-02 -4.33894223e-03
-1.75531625e-02 6.88848957e-03 3.45131992e-02 7.03299373e-02
2.16785467e-02 5.32218605e-03 8.17564998e-02 6.40061124e-02
-2.31142024e-03 -1.17557555e-02 1.75889259e-01 3.18128513e-02
-3.15885120e-02 3.34029118e-02 2.22779891e-02 1.00230572e-02
-4.74913579e-02 -2.12757807e-02 -3.98718130e-02 -6.04070105e-02
-4.65059959e-02 1.03006444e-02 -3.05710631e-04 1.80743623e-02
-1.75451147e-02 -8.72590342e-02 1.00662606e-01 4.46114451e-03
7.46870310e-02 -6.13411188e-02 2.81703136e-02 -1.40978964e-02
3.14638042e-02 -1.63834310e-02 3.66531969e-02 -5.15679040e-03
1.45093650e-02 6.35869204e-02 2.34598732e-02 8.81060743e-02
6.15345053e-02 -1.39361607e-02 2.07247028e-02 -3.15457797e-03
5.15426573e-02 -2.88766765e-02 1.60262775e-02 2.09702386e-02
-3.29172062e-02 -2.59459394e-02 -5.60400464e-02 -3.64627260e-02
1.12881345e-02 2.17268726e-02 -1.51638957e-02 -7.82885326e-03
2.42547725e-02 9.47013662e-02 -2.63031678e-02 1.17359244e-04
-5.24167353e-03 4.17987691e-02 8.85681788e-02 6.23631635e-03
1.86601105e-02 1.54629087e-02 3.50546907e-03 6.20626267e-03
-1.19791150e-02 1.59526543e-02 7.12127480e-03 -8.93192859e-02
-3.54325571e-03 1.23477389e-02 3.03928247e-02 -2.37295664e-02
-3.82793175e-02 -4.98744893e-02 4.66895340e-02 -1.23291617e-02
-1.10333071e-02 2.18105229e-02 2.18718991e-02 2.63538847e-02
1.05280149e-02 1.84617384e-02 8.36168561e-04 -6.65220555e-03
3.49397264e-02 1.49353567e-02 -1.11598707e-02 6.69088503e-03
-2.00058558e-02 -3.99014732e-02 3.01871509e-02 -1.09866611e-02
-4.11780282e-02 2.72052671e-02 1.16426000e-02 -1.55502085e-02
3.27701023e-02 3.95494477e-02 8.48721316e-03 2.19935028e-02
-9.88663311e-03 -3.61421043e-02 -4.77020808e-02 1.90075380e-02
-5.58286504e-02 -3.31741023e-02 -2.24912469e-02 -3.36174855e-02
-4.07353021e-02 1.08860414e-02 1.12810729e-02 7.63145091e-02
4.04799999e-03 3.07015302e-02 2.89177214e-02 4.71620127e-03
5.13383871e-02 -4.10364457e-02 1.23265242e-03 -2.50404293e-02
5.85904434e-02 -1.04965543e-01 -4.41705329e-02 1.18520840e-02
-5.83203291e-02 -4.82245030e-02 9.17642543e-03 1.03259493e-02
-5.09186187e-03 -3.23390784e-02 -3.19386747e-02 -1.53769216e-02
-5.21212191e-02 1.55620069e-02 2.93484399e-02 -1.92528920e-02
1.76693446e-02 2.67991696e-02 5.76553688e-02 -1.38164355e-02
2.60400161e-02 1.50399685e-02 1.27424867e-02 -2.29244208e-02
-1.06663965e-02 9.81939884e-03 -4.77511444e-02 1.64243203e-02]]
It’s a numpy array with only one coefficient per voxel:
print(coef_.shape)
(1, 464)
To get the Nifti image of these coefficients, we only need retrieve the coef_img_ in the decoder and select the class
coef_img = decoder.coef_img_["face"]
coef_img is now a NiftiImage. We can save the coefficients as a nii.gz file:
from pathlib import Path
output_dir = Path.cwd() / "results" / "plot_decoding_tutorial"
output_dir.mkdir(exist_ok=True, parents=True)
print(f"Output will be saved to: {output_dir}")
decoder.coef_img_["face"].to_filename(output_dir / "haxby_svc_weights.nii.gz")
Output will be saved to: /home/runner/work/nilearn/nilearn/examples/00_tutorials/results/plot_decoding_tutorial
Plotting the SVM weights¶
We can plot the weights, using the subject’s anatomical as a background
plotting.view_img(
decoder.coef_img_["face"],
bg_img=haxby_dataset.anat[0],
title="SVM weights",
dim=-1,
)
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/numpy/core/fromnumeric.py:758: UserWarning: Warning: 'partition' will ignore the 'mask' of the MaskedArray.
a.partition(kth, axis=axis, kind=kind, order=order)