Note
Go to the end to download the full example code. or to run this example in your browser via Binder
Decoding with FREM: face vs house vs chair object recognition¶
This example uses fast ensembling of regularized models (FREM) to decode a face vs house vs chair discrimination task from Haxby et al.[1] study. FREM uses an implicit spatial regularization through fast clustering and aggregates a high number of estimators trained on various splits of the training set, thus returning a very robust decoder at a lower computational cost than other spatially regularized methods.
To have more details, see: FREM: fast ensembling of regularized models for robust decoding.
Load the Haxby dataset¶
from nilearn.datasets import fetch_haxby
data_files = fetch_haxby()
# Load behavioral data
import pandas as pd
behavioral = pd.read_csv(data_files.session_target[0], sep=" ")
# Restrict to face, house, and chair conditions
conditions = behavioral["labels"]
condition_mask = conditions.isin(["face", "house", "chair"])
# Split data into train and test samples, using the chunks
condition_mask_train = (condition_mask) & (behavioral["chunks"] <= 6)
condition_mask_test = (condition_mask) & (behavioral["chunks"] > 6)
# Apply this sample mask to X (fMRI data) and y (behavioral labels)
# 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
func_filenames = data_files.func[0]
X_train = index_img(func_filenames, condition_mask_train)
X_test = index_img(func_filenames, condition_mask_test)
y_train = conditions[condition_mask_train].to_numpy()
y_test = conditions[condition_mask_test].to_numpy()
# Compute the mean EPI to be used for the background of the plotting
from nilearn.image import mean_img
background_img = mean_img(func_filenames, copy_header=True)
[get_dataset_dir] Dataset found in /home/runner/nilearn_data/haxby2001
Fit FREM¶
from nilearn.decoding import FREMClassifier
decoder = FREMClassifier(cv=10, standardize="zscore_sample", n_jobs=2)
# Fit model on train data and predict on test data
decoder.fit(X_train, y_train)
y_pred = decoder.predict(X_test)
accuracy = (y_pred == y_test).mean() * 100.0
print(f"FREM classification accuracy : {accuracy:g}%")
/home/runner/work/nilearn/nilearn/.tox/doc/lib/python3.9/site-packages/nilearn/decoding/decoder.py:758: UserWarning:
Brain mask is bigger than the standard human brain. This object is probably not tuned to be used on such data.
FREM classification accuracy : 57.7778%
Plot confusion matrix¶
import numpy as np
from sklearn.metrics import confusion_matrix
from nilearn import plotting
# Calculate the confusion matrix
matrix = confusion_matrix(
y_test,
y_pred,
normalize="true",
)
# Plot the confusion matrix
im = plotting.plot_matrix(
matrix,
labels=sorted(np.unique(y_test)),
vmin=0,
cmap="hot_r",
)
# Add x/y-axis labels
ax = im.axes
ax.set_ylabel("True label")
ax.set_xlabel("Predicted label")
plotting.show()
Visualization of FREM weights¶
plotting.plot_stat_map(
decoder.coef_img_["face"],
background_img,
title=f"FREM: accuracy {accuracy:g}%, 'face coefs'",
cut_coords=(-50, -4),
display_mode="yz",
)
plotting.show()
FREM ensembling procedure yields an important improvement of decoding accuracy on this simple example compared to fitting only one model per fold and the clustering mechanism keeps its computational cost reasonable even on heavier examples. Here we ensembled several instances of l2-SVC, but FREMClassifier also works with ridge or logistic. FREMRegressor object is also available to solve regression problems.
References¶
Total running time of the script: (2 minutes 42.183 seconds)
Estimated memory usage: 1095 MB