Group Sparse inverse covariance for multi-subject connectome

This example shows how to estimate a connectome on a group of subjects using the group sparse inverse covariance estimate.

This example is a toy example as running it on more subjects will require a longer run time.

dataset

This example uses the MSDL atlas to extract data from the development fMRI dataset.

import numpy as np

from nilearn.plotting import plot_matrix


def plot_matrices(cov, prec, title, labels):
    """Plot covariance and precision matrices, for a given processing."""
    prec = prec.copy()  # avoid side effects

    # Put zeros on the diagonal, for graph clarity.
    size = prec.shape[0]
    prec[list(range(size)), list(range(size))] = 0
    span = max(abs(prec.min()), abs(prec.max()))

    # Display covariance matrix
    plot_matrix(
        cov,
        vmin=-1,
        vmax=1,
        title=f"{title} / covariance",
        labels=labels,
    )
    # Display precision matrix
    plot_matrix(
        prec,
        vmin=-span,
        vmax=span,
        title=f"{title} / precision",
        labels=labels,
    )

Fetching datasets

from nilearn.datasets import fetch_development_fmri

n_subjects = 4  # subjects to consider for group-sparse covariance (max: 40)

rest_dataset = fetch_development_fmri(n_subjects=n_subjects)

# print basic information on the dataset
print(
    f"First subject functional nifti image (4D) is at: {rest_dataset.func[0]}"
)
[fetch_development_fmri] Dataset directory found: /home/runner/work/nilearn/nilearn/nilearn_data/development_fmri
First subject functional nifti image (4D) is at: /home/runner/work/nilearn/nilearn/nilearn_data/development_fmri/sub-pixar123_task-pixar_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz

Extracting region signals

from nilearn.datasets import fetch_atlas_msdl
from nilearn.maskers import MultiNiftiMapsMasker

atlas = fetch_atlas_msdl()

print(atlas.description.content)

atlas_img = atlas.maps
labels = atlas.labels
[fetch_atlas_msdl] Dataset directory found: /home/runner/work/nilearn/nilearn/nilearn_data/msdl_atlas
{'labels': {'type': list[str], 'desc': 'List of the names of the regions. There are 39 labels such that ``data.labels[i]`` corresponds to map ``i``.'}, 'maps': {'type': <class 'str'>, 'desc': 'Full path to nifti file containing the :term:`Probabilistic atlas` image (shape is equal to ``(40, 48, 35, 39)``).'}, 'networks': {'type': list[str], 'desc': 'List containing the names of the networks. There are 39 network names such that ``data.networks[i]`` is the network name of region ``i``.'}, 'region_coords': {'type': list[list[float]], 'desc': 'Length-3 :obj:`tuple` ``data.region_coords[i]`` contains the coordinates ``(x, y, z)`` of region ``i`` in :term:`MNI` space.'}, 'atlas_type': {'type': <class 'str'>, 'desc': '\n        Type of atlas.\n        See :term:`Probabilistic atlas` and :term:`Deterministic atlas`.'}, 'template': {'type': <class 'str'>, 'desc': 'The standardized space of analysis in which the data is provided.'}}
masker = MultiNiftiMapsMasker(
    atlas_img,
    resampling_target="maps",
    detrend=True,
    high_variance_confounds=True,
    low_pass=None,
    high_pass=0.01,
    t_r=rest_dataset.t_r,
    standardize="zscore_sample",
    standardize_confounds=True,
    memory="nilearn_cache",
    memory_level=1,
    verbose=1,
)

func_filenames = rest_dataset.func
confound_filenames = rest_dataset.confounds

subject_time_series = masker.fit_transform(
    func_filenames, confounds=confound_filenames
)
[MultiNiftiMapsMasker.fit_transform] Loading data from [
 sub-pixar123_task-...,
         ...
 sub-pixar003_task-...,
]
[MultiNiftiMapsMasker.fit_transform] Loading regions from .../msdl_rois.nii
[MultiNiftiMapsMasker.fit_transform] Finished fit
________________________________________________________________________________
[Memory] Calling nilearn.image.image.high_variance_confounds...
high_variance_confounds('/home/runner/work/nilearn/nilearn/nilearn_data/development_fmri/sub-pixar123_task-pixar_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz')
__________________________________________high_variance_confounds - 0.5s, 0.0min
________________________________________________________________________________
[Memory] Calling nilearn.image.image.high_variance_confounds...
high_variance_confounds('/home/runner/work/nilearn/nilearn/nilearn_data/development_fmri/sub-pixar001_task-pixar_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz')
__________________________________________high_variance_confounds - 0.4s, 0.0min
________________________________________________________________________________
[Memory] Calling nilearn.image.image.high_variance_confounds...
high_variance_confounds('/home/runner/work/nilearn/nilearn/nilearn_data/development_fmri/sub-pixar002_task-pixar_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz')
__________________________________________high_variance_confounds - 0.5s, 0.0min
________________________________________________________________________________
[Memory] Calling nilearn.image.image.high_variance_confounds...
high_variance_confounds('/home/runner/work/nilearn/nilearn/nilearn_data/development_fmri/sub-pixar003_task-pixar_space-MNI152NLin2009cAsym_desc-preproc_bold.nii.gz')
__________________________________________high_variance_confounds - 0.4s, 0.0min
________________________________________________________________________________
[Memory] Calling nilearn.maskers.nifti_maps_masker.NiftiMapsMasker.transform_single_imgs...
transform_single_imgs(imgs=<nibabel.nifti1.Nifti1Image object at 0x72031a2d3110>, confounds=array([[-0.000233, ..., -0.048779],
       ...,
       [-0.026896, ...,  0.155444]]), sample_mask=None)
/home/runner/work/nilearn/nilearn/examples/03_connectivity/plot_multi_subject_connectome.py:97: UserWarning:

Resampling images at transform time...
To avoid this warning, make sure to resample the images you want to transform to the shape of the maps or set resampling_target to 'data'.

________________________________________________________________________________
[Memory] Calling nilearn.maskers.base_masker.filter_and_extract...
filter_and_extract(<nibabel.nifti1.Nifti1Image object at 0x72031a2d3110>, <nilearn.maskers.nifti_maps_masker._ExtractionFunctor object at 0x72031a2d2810>, { 'allow_overlap': True,
  'clean_args': None,
  'clean_kwargs': {},
  'cmap': 'CMRmap_r',
  'detrend': True,
  'dtype': None,
  'high_pass': 0.01,
  'high_variance_confounds': True,
  'low_pass': None,
  'maps_img': '/home/runner/work/nilearn/nilearn/nilearn_data/msdl_atlas/MSDL_rois/msdl_rois.nii',
  'mask_img': None,
  'reports': True,
  'smoothing_fwhm': None,
  'standardize': 'zscore_sample',
  'standardize_confounds': True,
  't_r': 2,
  'target_affine': array([[   4.,    0.,    0.,  -78.],
       [   0.,    4.,    0., -111.],
       [   0.,    0.,    4.,  -51.],
       [   0.,    0.,    0.,    1.]]),
  'target_shape': (40, 48, 35)}, confounds=array([[-0.000233, ..., -0.048779],
       ...,
       [-0.026896, ...,  0.155444]]), sample_mask=None, memory=Memory(location=nilearn_cache/joblib), memory_level=1, verbose=1, sklearn_output_config=None)
[MultiNiftiMapsMasker.fit_transform] Loading data from <nibabel.nifti1.Nifti1Image object at 0x72031a2d3110>
[MultiNiftiMapsMasker.fit_transform] Resampling images
[MultiNiftiMapsMasker.fit_transform] Extracting region signals
[MultiNiftiMapsMasker.fit_transform] Cleaning extracted signals
_______________________________________________filter_and_extract - 4.2s, 0.1min
____________________________________________transform_single_imgs - 4.3s, 0.1min
________________________________________________________________________________
[Memory] Calling nilearn.maskers.nifti_maps_masker.NiftiMapsMasker.transform_single_imgs...
transform_single_imgs(imgs=<nibabel.nifti1.Nifti1Image object at 0x72031a2d37d0>, confounds=array([[ 0.013422, ..., -0.057023],
       ...,
       [ 0.087146, ...,  0.102714]]), sample_mask=None)
/home/runner/work/nilearn/nilearn/examples/03_connectivity/plot_multi_subject_connectome.py:97: UserWarning:

Resampling images at transform time...
To avoid this warning, make sure to resample the images you want to transform to the shape of the maps or set resampling_target to 'data'.

________________________________________________________________________________
[Memory] Calling nilearn.maskers.base_masker.filter_and_extract...
filter_and_extract(<nibabel.nifti1.Nifti1Image object at 0x72031a2d37d0>, <nilearn.maskers.nifti_maps_masker._ExtractionFunctor object at 0x720320908b90>, { 'allow_overlap': True,
  'clean_args': None,
  'clean_kwargs': {},
  'cmap': 'CMRmap_r',
  'detrend': True,
  'dtype': None,
  'high_pass': 0.01,
  'high_variance_confounds': True,
  'low_pass': None,
  'maps_img': '/home/runner/work/nilearn/nilearn/nilearn_data/msdl_atlas/MSDL_rois/msdl_rois.nii',
  'mask_img': None,
  'reports': True,
  'smoothing_fwhm': None,
  'standardize': 'zscore_sample',
  'standardize_confounds': True,
  't_r': 2,
  'target_affine': array([[   4.,    0.,    0.,  -78.],
       [   0.,    4.,    0., -111.],
       [   0.,    0.,    4.,  -51.],
       [   0.,    0.,    0.,    1.]]),
  'target_shape': (40, 48, 35)}, confounds=array([[ 0.013422, ..., -0.057023],
       ...,
       [ 0.087146, ...,  0.102714]]), sample_mask=None, memory=Memory(location=nilearn_cache/joblib), memory_level=1, verbose=1, sklearn_output_config=None)
[MultiNiftiMapsMasker.fit_transform] Loading data from <nibabel.nifti1.Nifti1Image object at 0x72031a2d37d0>
[MultiNiftiMapsMasker.fit_transform] Resampling images
[MultiNiftiMapsMasker.fit_transform] Extracting region signals
[MultiNiftiMapsMasker.fit_transform] Cleaning extracted signals
_______________________________________________filter_and_extract - 4.2s, 0.1min
____________________________________________transform_single_imgs - 4.3s, 0.1min
________________________________________________________________________________
[Memory] Calling nilearn.maskers.nifti_maps_masker.NiftiMapsMasker.transform_single_imgs...
transform_single_imgs(imgs=<nibabel.nifti1.Nifti1Image object at 0x72031a2d3710>, confounds=array([[ 0.      , ..., -0.087084],
       ...,
       [ 0.00349 , ..., -0.02587 ]]), sample_mask=None)
/home/runner/work/nilearn/nilearn/examples/03_connectivity/plot_multi_subject_connectome.py:97: UserWarning:

Resampling images at transform time...
To avoid this warning, make sure to resample the images you want to transform to the shape of the maps or set resampling_target to 'data'.

________________________________________________________________________________
[Memory] Calling nilearn.maskers.base_masker.filter_and_extract...
filter_and_extract(<nibabel.nifti1.Nifti1Image object at 0x72031a2d3710>, <nilearn.maskers.nifti_maps_masker._ExtractionFunctor object at 0x7203581c5050>, { 'allow_overlap': True,
  'clean_args': None,
  'clean_kwargs': {},
  'cmap': 'CMRmap_r',
  'detrend': True,
  'dtype': None,
  'high_pass': 0.01,
  'high_variance_confounds': True,
  'low_pass': None,
  'maps_img': '/home/runner/work/nilearn/nilearn/nilearn_data/msdl_atlas/MSDL_rois/msdl_rois.nii',
  'mask_img': None,
  'reports': True,
  'smoothing_fwhm': None,
  'standardize': 'zscore_sample',
  'standardize_confounds': True,
  't_r': 2,
  'target_affine': array([[   4.,    0.,    0.,  -78.],
       [   0.,    4.,    0., -111.],
       [   0.,    0.,    4.,  -51.],
       [   0.,    0.,    0.,    1.]]),
  'target_shape': (40, 48, 35)}, confounds=array([[ 0.      , ..., -0.087084],
       ...,
       [ 0.00349 , ..., -0.02587 ]]), sample_mask=None, memory=Memory(location=nilearn_cache/joblib), memory_level=1, verbose=1, sklearn_output_config=None)
[MultiNiftiMapsMasker.fit_transform] Loading data from <nibabel.nifti1.Nifti1Image object at 0x72031a2d3710>
[MultiNiftiMapsMasker.fit_transform] Resampling images
[MultiNiftiMapsMasker.fit_transform] Extracting region signals
[MultiNiftiMapsMasker.fit_transform] Cleaning extracted signals
_______________________________________________filter_and_extract - 4.3s, 0.1min
____________________________________________transform_single_imgs - 4.4s, 0.1min
________________________________________________________________________________
[Memory] Calling nilearn.maskers.nifti_maps_masker.NiftiMapsMasker.transform_single_imgs...
transform_single_imgs(imgs=<nibabel.nifti1.Nifti1Image object at 0x7203719e40d0>, confounds=array([[ 6.680960e-06, ..., -6.231628e-02],
       ...,
       [ 2.379980e-02, ..., -2.286822e-02]]), sample_mask=None)
/home/runner/work/nilearn/nilearn/examples/03_connectivity/plot_multi_subject_connectome.py:97: UserWarning:

Resampling images at transform time...
To avoid this warning, make sure to resample the images you want to transform to the shape of the maps or set resampling_target to 'data'.

________________________________________________________________________________
[Memory] Calling nilearn.maskers.base_masker.filter_and_extract...
filter_and_extract(<nibabel.nifti1.Nifti1Image object at 0x7203719e40d0>, <nilearn.maskers.nifti_maps_masker._ExtractionFunctor object at 0x7203703f7490>, { 'allow_overlap': True,
  'clean_args': None,
  'clean_kwargs': {},
  'cmap': 'CMRmap_r',
  'detrend': True,
  'dtype': None,
  'high_pass': 0.01,
  'high_variance_confounds': True,
  'low_pass': None,
  'maps_img': '/home/runner/work/nilearn/nilearn/nilearn_data/msdl_atlas/MSDL_rois/msdl_rois.nii',
  'mask_img': None,
  'reports': True,
  'smoothing_fwhm': None,
  'standardize': 'zscore_sample',
  'standardize_confounds': True,
  't_r': 2,
  'target_affine': array([[   4.,    0.,    0.,  -78.],
       [   0.,    4.,    0., -111.],
       [   0.,    0.,    4.,  -51.],
       [   0.,    0.,    0.,    1.]]),
  'target_shape': (40, 48, 35)}, confounds=array([[ 6.680960e-06, ..., -6.231628e-02],
       ...,
       [ 2.379980e-02, ..., -2.286822e-02]]), sample_mask=None, memory=Memory(location=nilearn_cache/joblib), memory_level=1, verbose=1, sklearn_output_config=None)
[MultiNiftiMapsMasker.fit_transform] Loading data from <nibabel.nifti1.Nifti1Image object at 0x7203719e40d0>
[MultiNiftiMapsMasker.fit_transform] Resampling images
[MultiNiftiMapsMasker.fit_transform] Extracting region signals
[MultiNiftiMapsMasker.fit_transform] Cleaning extracted signals
_______________________________________________filter_and_extract - 4.2s, 0.1min
____________________________________________transform_single_imgs - 4.3s, 0.1min

Computing group-sparse precision matrices

from nilearn.connectome import GroupSparseCovarianceCV

gsc = GroupSparseCovarianceCV(verbose=1)
gsc.fit(subject_time_series)
[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:    7.2s finished
[GroupSparseCovarianceCV.fit] [GroupSparseCovarianceCV] Done refinement  0 out of 4
[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:   12.2s finished
[GroupSparseCovarianceCV.fit] [GroupSparseCovarianceCV] Done refinement  1 out of 4
[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:   14.2s finished
[GroupSparseCovarianceCV.fit] [GroupSparseCovarianceCV] Done refinement  2 out of 4
[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:   11.4s finished
[GroupSparseCovarianceCV.fit] [GroupSparseCovarianceCV] Done refinement  3 out of 4
[GroupSparseCovarianceCV.fit] Final optimization
GroupSparseCovarianceCV(verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.


from sklearn.covariance import GraphicalLassoCV

gl = GraphicalLassoCV(verbose=True)
gl.fit(np.concatenate(subject_time_series))
[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:    0.4s finished
[GraphicalLassoCV] Done refinement  1 out of 4:   0s
[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:    0.5s finished
[GraphicalLassoCV] Done refinement  2 out of 4:   0s
[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:    0.6s finished
[GraphicalLassoCV] Done refinement  3 out of 4:   1s
[Parallel(n_jobs=1)]: Done   5 out of   5 | elapsed:    0.5s finished
[GraphicalLassoCV] Done refinement  4 out of 4:   2s
GraphicalLassoCV(verbose=True)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.


Displaying results

from nilearn.plotting import (
    find_probabilistic_atlas_cut_coords,
    plot_connectome,
    show,
)

atlas_region_coords = find_probabilistic_atlas_cut_coords(atlas_img)

plot_connectome(
    gl.covariance_,
    atlas_region_coords,
    edge_threshold="90%",
    title="Covariance",
    display_mode="lzr",
)
plot multi subject connectome
<nilearn.plotting.displays._projectors.LZRProjector object at 0x72036fae4950>
plot_connectome(
    -gl.precision_,
    atlas_region_coords,
    edge_threshold="90%",
    title="Sparse inverse covariance (GraphicalLasso)",
    display_mode="lzr",
    edge_vmax=0.5,
    edge_vmin=-0.5,
)
plot_connectome(
    -gsc.precisions_[..., 0],
    atlas_region_coords,
    edge_threshold="90%",
    title="GroupSparseCovariance",
    display_mode="lzr",
    edge_vmax=0.5,
    edge_vmin=-0.5,
)

show()
  • plot multi subject connectome
  • plot multi subject connectome
plot_matrices(gl.covariance_, gl.precision_, "GraphicalLasso", labels)
plot_matrices(
    gsc.covariances_[..., 0],
    gsc.precisions_[..., 0],
    "GroupSparseCovariance",
    labels,
)

show()
  • GraphicalLasso / covariance
  • GraphicalLasso / precision
  • GroupSparseCovariance / covariance
  • GroupSparseCovariance / precision

Total running time of the script: (1 minutes 16.881 seconds)

Estimated memory usage: 1434 MB

Gallery generated by Sphinx-Gallery