.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/03_connectivity/plot_group_level_connectivity.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code or to run this example in your browser via Binder .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_03_connectivity_plot_group_level_connectivity.py: Classification of age groups using functional connectivity ========================================================== This example compares different kinds of :term:`functional connectivity` between regions of interest : correlation, partial correlation, and tangent space embedding. The resulting connectivity coefficients can be used to discriminate children from adults.In general, the tangent space embedding **outperforms** the standard correlations: see :footcite:t:`Dadi2019` for a careful study. .. include:: ../../../examples/masker_note.rst .. GENERATED FROM PYTHON SOURCE LINES 19-22 Load brain development :term:`fMRI` dataset and MSDL atlas ---------------------------------------------------------- We study only 30 subjects from the dataset, to save computation time. .. GENERATED FROM PYTHON SOURCE LINES 22-26 .. code-block:: Python from nilearn import datasets, plotting development_dataset = datasets.fetch_development_fmri(n_subjects=30) .. GENERATED FROM PYTHON SOURCE LINES 27-28 We use probabilistic regions of interest (ROIs) from the MSDL atlas. .. GENERATED FROM PYTHON SOURCE LINES 28-36 .. code-block:: Python msdl_data = datasets.fetch_atlas_msdl() msdl_coords = msdl_data.region_coords n_regions = len(msdl_coords) print( f"MSDL has {n_regions} ROIs, " f"part of the following networks:\n{msdl_data.networks}." ) .. rst-class:: sphx-glr-script-out .. code-block:: none MSDL has 39 ROIs, part of the following networks: ['Aud', 'Aud', 'Striate', 'DMN', 'DMN', 'DMN', 'DMN', 'Occ post', 'Motor', 'R V Att', 'R V Att', 'R V Att', 'R V Att', 'Basal', 'L V Att', 'L V Att', 'L V Att', 'D Att', 'D Att', 'Vis Sec', 'Vis Sec', 'Vis Sec', 'Salience', 'Salience', 'Salience', 'Temporal', 'Temporal', 'Language', 'Language', 'Language', 'Language', 'Language', 'Cereb', 'Dors PCC', 'Cing-Ins', 'Cing-Ins', 'Cing-Ins', 'Ant IPS', 'Ant IPS']. .. GENERATED FROM PYTHON SOURCE LINES 37-42 Region signals extraction ------------------------- To extract regions time series, we instantiate a :class:`nilearn.maskers.NiftiMapsMasker` object and pass the atlas the file name to it, as well as filtering band-width and detrending option. .. GENERATED FROM PYTHON SOURCE LINES 42-57 .. code-block:: Python from nilearn.maskers import NiftiMapsMasker masker = NiftiMapsMasker( msdl_data.maps, resampling_target="data", t_r=2, detrend=True, low_pass=0.1, high_pass=0.01, memory="nilearn_cache", memory_level=1, standardize="zscore_sample", standardize_confounds="zscore_sample", ).fit() .. GENERATED FROM PYTHON SOURCE LINES 58-59 Then we compute region signals and extract useful phenotypic information. .. GENERATED FROM PYTHON SOURCE LINES 59-75 .. code-block:: Python children = [] pooled_subjects = [] groups = [] # child or adult for func_file, confound_file, phenotypic in zip( development_dataset.func, development_dataset.confounds, development_dataset.phenotypic, ): time_series = masker.transform(func_file, confounds=confound_file) pooled_subjects.append(time_series) if phenotypic["Child_Adult"] == "child": children.append(time_series) groups.append(phenotypic["Child_Adult"]) print(f"Data has {len(children)} children.") .. rst-class:: sphx-glr-script-out .. code-block:: none Data has 24 children. .. GENERATED FROM PYTHON SOURCE LINES 76-81 ROI-to-ROI correlations of children ----------------------------------- The simpler and most commonly used kind of connectivity is correlation. It models the full (marginal) connectivity between pairwise ROIs. We can estimate it using :class:`nilearn.connectome.ConnectivityMeasure`. .. GENERATED FROM PYTHON SOURCE LINES 81-88 .. code-block:: Python from nilearn.connectome import ConnectivityMeasure correlation_measure = ConnectivityMeasure( kind="correlation", standardize="zscore_sample", ) .. GENERATED FROM PYTHON SOURCE LINES 89-91 From the list of ROIs time-series for children, the `correlation_measure` computes individual correlation matrices. .. GENERATED FROM PYTHON SOURCE LINES 91-99 .. code-block:: Python correlation_matrices = correlation_measure.fit_transform(children) # All individual coefficients are stacked in a unique 2D matrix. print( "Correlations of children are stacked " f"in an array of shape {correlation_matrices.shape}" ) .. rst-class:: sphx-glr-script-out .. code-block:: none Correlations of children are stacked in an array of shape (24, 39, 39) .. GENERATED FROM PYTHON SOURCE LINES 100-101 as well as the average correlation across all fitted subjects. .. GENERATED FROM PYTHON SOURCE LINES 101-106 .. code-block:: Python mean_correlation_matrix = correlation_measure.mean_ print(f"Mean correlation has shape {mean_correlation_matrix.shape}.") from matplotlib import pyplot as plt .. rst-class:: sphx-glr-script-out .. code-block:: none Mean correlation has shape (39, 39). .. GENERATED FROM PYTHON SOURCE LINES 107-108 We display the connectome matrices of the first 3 children .. GENERATED FROM PYTHON SOURCE LINES 108-117 .. code-block:: Python _, axes = plt.subplots(1, 3, figsize=(15, 5)) for i, (matrix, ax) in enumerate(zip(correlation_matrices, axes)): plotting.plot_matrix( matrix, tri="lower", colorbar=False, axes=ax, title=f"correlation, child {i}", ) .. image-sg:: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_001.png :alt: correlation, child 0, correlation, child 1, correlation, child 2 :srcset: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 118-119 The blocks structure that reflect functional networks are visible. .. GENERATED FROM PYTHON SOURCE LINES 121-122 Now we display as a connectome the mean correlation matrix over all children. .. GENERATED FROM PYTHON SOURCE LINES 122-128 .. code-block:: Python plotting.plot_connectome( mean_correlation_matrix, msdl_coords, title="mean correlation over all children", ) .. image-sg:: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_002.png :alt: plot group level connectivity :srcset: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_002.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 129-133 Studying partial correlations ----------------------------- We can also study **direct connections**, revealed by partial correlation coefficients. We just change the `ConnectivityMeasure` kind .. GENERATED FROM PYTHON SOURCE LINES 133-141 .. code-block:: Python partial_correlation_measure = ConnectivityMeasure( kind="partial correlation", standardize="zscore_sample", ) partial_correlation_matrices = partial_correlation_measure.fit_transform( children ) .. GENERATED FROM PYTHON SOURCE LINES 142-143 Most of direct connections are weaker than full connections. .. GENERATED FROM PYTHON SOURCE LINES 143-153 .. code-block:: Python _, axes = plt.subplots(1, 3, figsize=(15, 5)) for i, (matrix, ax) in enumerate(zip(partial_correlation_matrices, axes)): plotting.plot_matrix( matrix, tri="lower", colorbar=False, axes=ax, title=f"partial correlation, child {i}", ) .. image-sg:: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_003.png :alt: partial correlation, child 0, partial correlation, child 1, partial correlation, child 2 :srcset: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_003.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 154-160 .. code-block:: Python plotting.plot_connectome( partial_correlation_measure.mean_, msdl_coords, title="mean partial correlation over all children", ) .. image-sg:: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_004.png :alt: plot group level connectivity :srcset: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_004.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-script-out .. code-block:: none .. GENERATED FROM PYTHON SOURCE LINES 161-166 Extract subjects variabilities around a group connectivity ---------------------------------------------------------- We can use **both** correlations and partial correlations to capture reproducible connectivity patterns at the group-level. This is done by the tangent space embedding. .. GENERATED FROM PYTHON SOURCE LINES 166-171 .. code-block:: Python tangent_measure = ConnectivityMeasure( kind="tangent", standardize="zscore_sample", ) .. GENERATED FROM PYTHON SOURCE LINES 172-175 We fit our children group and get the group connectivity matrix stored as in `tangent_measure.mean_`, and individual deviation matrices of each subject from it. .. GENERATED FROM PYTHON SOURCE LINES 175-177 .. code-block:: Python tangent_matrices = tangent_measure.fit_transform(children) .. GENERATED FROM PYTHON SOURCE LINES 178-183 `tangent_matrices` model individual connectivities as **perturbations** of the group connectivity matrix `tangent_measure.mean_`. Keep in mind that these subjects-to-group variability matrices do not directly reflect individual brain connections. For instance negative coefficients can not be interpreted as anticorrelated regions. .. GENERATED FROM PYTHON SOURCE LINES 183-194 .. code-block:: Python _, axes = plt.subplots(1, 3, figsize=(15, 5)) for i, (matrix, ax) in enumerate(zip(tangent_matrices, axes)): plotting.plot_matrix( matrix, tri="lower", colorbar=False, axes=ax, title=f"tangent offset, child {i}", ) .. image-sg:: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_005.png :alt: tangent offset, child 0, tangent offset, child 1, tangent offset, child 2 :srcset: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_005.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 195-197 The average tangent matrix cannot be interpreted, as individual matrices represent deviations from the mean, which is set to 0. .. GENERATED FROM PYTHON SOURCE LINES 199-207 What kind of connectivity is most powerful for classification? -------------------------------------------------------------- We will use connectivity matrices as features to distinguish children from adults. We use cross-validation and measure classification accuracy to compare the different kinds of connectivity matrices. We use random splits of the subjects into training/testing sets. StratifiedShuffleSplit allows preserving the proportion of children in the test set. .. GENERATED FROM PYTHON SOURCE LINES 207-240 .. code-block:: Python import numpy as np from sklearn.metrics import accuracy_score from sklearn.model_selection import StratifiedShuffleSplit from sklearn.svm import LinearSVC kinds = ["correlation", "partial correlation", "tangent"] _, classes = np.unique(groups, return_inverse=True) cv = StratifiedShuffleSplit(n_splits=15, random_state=0, test_size=5) pooled_subjects = np.asarray(pooled_subjects) scores = {} for kind in kinds: scores[kind] = [] for train, test in cv.split(pooled_subjects, classes): # *ConnectivityMeasure* can output the estimated subjects coefficients # as a 1D arrays through the parameter *vectorize*. connectivity = ConnectivityMeasure( kind=kind, vectorize=True, standardize="zscore_sample", ) # build vectorized connectomes for subjects in the train set connectomes = connectivity.fit_transform(pooled_subjects[train]) # fit the classifier classifier = LinearSVC(dual=True).fit(connectomes, classes[train]) # make predictions for the left-out test subjects predictions = classifier.predict( connectivity.transform(pooled_subjects[test]) ) # store the accuracy for this cross-validation fold scores[kind].append(accuracy_score(classes[test], predictions)) .. GENERATED FROM PYTHON SOURCE LINES 241-242 display the results .. GENERATED FROM PYTHON SOURCE LINES 242-258 .. code-block:: Python mean_scores = [np.mean(scores[kind]) for kind in kinds] scores_std = [np.std(scores[kind]) for kind in kinds] plt.figure(figsize=(6, 4)) positions = np.arange(len(kinds)) * 0.1 + 0.1 plt.barh(positions, mean_scores, align="center", height=0.05, xerr=scores_std) yticks = [k.replace(" ", "\n") for k in kinds] plt.yticks(positions, yticks) plt.gca().grid(True) plt.gca().set_axisbelow(True) plt.gca().axvline(0.8, color="red", linestyle="--") plt.xlabel("Classification accuracy\n(red line = chance level)") plt.tight_layout() .. image-sg:: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_006.png :alt: plot group level connectivity :srcset: /auto_examples/03_connectivity/images/sphx_glr_plot_group_level_connectivity_006.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 259-265 This is a small example to showcase nilearn features. In practice such comparisons need to be performed on much larger cohorts and several datasets. :footcite:t:`Dadi2019` showed that across many cohorts and clinical questions, the tangent kind should be preferred. .. GENERATED FROM PYTHON SOURCE LINES 265-268 .. code-block:: Python plotting.show() .. GENERATED FROM PYTHON SOURCE LINES 269-273 References ---------- .. footbibliography:: .. rst-class:: sphx-glr-timing **Total running time of the script:** (2 minutes 14.782 seconds) **Estimated memory usage:** 1209 MB .. _sphx_glr_download_auto_examples_03_connectivity_plot_group_level_connectivity.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: binder-badge .. image:: images/binder_badge_logo.svg :target: https://mybinder.org/v2/gh/nilearn/nilearn/0.10.4?urlpath=lab/tree/notebooks/auto_examples/03_connectivity/plot_group_level_connectivity.ipynb :alt: Launch binder :width: 150 px .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_group_level_connectivity.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_group_level_connectivity.py ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_