Coverage for nilearn/decomposition/_multi_pca.py: 30%
21 statements
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-20 10:58 +0200
« prev ^ index » next coverage.py v7.9.1, created at 2025-06-20 10:58 +0200
1"""PCA dimension reduction on multiple subjects.
3This is a good initialization method for ICA.
4"""
6import numpy as np
7from sklearn.utils.extmath import randomized_svd
9from nilearn._utils import fill_doc
11from ._base import _BaseDecomposition
14@fill_doc
15class _MultiPCA(_BaseDecomposition):
16 """Perform Multi Subject Principal Component Analysis.
18 Perform a PCA on each subject, stack the results, and reduce them
19 at group level. An optional Canonical Correlation Analysis can be
20 performed at group level. This is a good initialization method for ICA.
22 Parameters
23 ----------
24 n_components : int, default=20
25 Number of components to extract.
27 do_cca : boolean, default=True
28 Indicate if a Canonical Correlation Analysis must be run after the
29 PCA.
31 %(random_state)s
33 %(smoothing_fwhm)s
35 mask : Niimg-like object, :obj:`~nilearn.maskers.NiftiMasker` or \
36 :obj:`~nilearn.maskers.MultiNiftiMasker` or \
37 :obj:`~nilearn.surface.SurfaceImage` or \
38 :obj:`~nilearn.maskers.SurfaceMasker` object, optional
39 Mask to be used on data. If an instance of masker is passed,
40 then its mask will be used. If no mask is given, for Nifti images,
41 it will be computed automatically by a MultiNiftiMasker with default
42 parameters; for surface images, all the vertices will be used.
44 %(mask_strategy)s
45 Default='epi'.
46 .. note::
48 These strategies are only relevant for Nifti images and the parameter
49 is ignored for SurfaceImage objects.
51 mask_args : dict, optional
52 If mask is None, these are additional parameters passed to
53 :func:`nilearn.masking.compute_background_mask`,
54 or :func:`nilearn.masking.compute_epi_mask`
55 to fine-tune mask computation.
56 Please see the related documentation for details.
58 standardize : boolean, default=False
59 If standardize is True, the time-series are centered and normed:
60 their mean is put to 0 and their variance to 1 in the time dimension.
62 standardize_confounds : boolean, default=True
63 If standardize_confounds is True, the confounds are z-scored:
64 their mean is put to 0 and their variance to 1 in the time dimension.
66 detrend : boolean, default=False
67 If detrend is True, the time-series will be detrended before
68 components extraction.
70 %(target_affine)s
72 .. note::
73 This parameter is passed to :func:`nilearn.image.resample_img`.
75 %(target_shape)s
77 .. note::
78 This parameter is passed to :func:`nilearn.image.resample_img`.
80 %(low_pass)s
82 .. note::
83 This parameter is passed to :func:`nilearn.image.resample_img`.
85 %(high_pass)s
87 .. note::
88 This parameter is passed to :func:`nilearn.image.resample_img`.
90 %(t_r)s
92 .. note::
93 This parameter is passed to :func:`nilearn.image.resample_img`.
95 memory : instance of joblib.Memory or string, default=None
96 Used to cache the masking process.
97 By default, no caching is done.
98 If a string is given, it is the path to the caching directory.
99 If ``None`` is passed will default to ``Memory(location=None)``.
101 memory_level : integer, default=0
102 Rough estimator of the amount of memory used by caching. Higher value
103 means more memory for caching.
105 n_jobs : integer, default=1
106 The number of CPUs to use to do the computation. -1 means
107 'all CPUs', -2 'all CPUs but one', and so on.
109 %(verbose0)s
111 %(base_decomposition_attributes)s
113 %(multi_pca_attributes)s
115 """
117 def __init__(
118 self,
119 n_components=20,
120 mask=None,
121 smoothing_fwhm=None,
122 do_cca=True,
123 random_state=None,
124 standardize=False,
125 standardize_confounds=True,
126 detrend=False,
127 low_pass=None,
128 high_pass=None,
129 t_r=None,
130 target_affine=None,
131 target_shape=None,
132 mask_strategy="epi",
133 mask_args=None,
134 memory=None,
135 memory_level=0,
136 n_jobs=1,
137 verbose=0,
138 ):
139 super().__init__(
140 n_components=n_components,
141 random_state=random_state,
142 mask=mask,
143 smoothing_fwhm=smoothing_fwhm,
144 standardize=standardize,
145 standardize_confounds=standardize_confounds,
146 detrend=detrend,
147 low_pass=low_pass,
148 high_pass=high_pass,
149 t_r=t_r,
150 target_affine=target_affine,
151 target_shape=target_shape,
152 mask_strategy=mask_strategy,
153 mask_args=mask_args,
154 memory=memory,
155 memory_level=memory_level,
156 n_jobs=n_jobs,
157 verbose=verbose,
158 )
160 self.do_cca = do_cca
162 def _raw_fit(self, data):
163 """Process unmasked data directly."""
164 if self.do_cca:
165 S = np.sqrt(np.sum(data**2, axis=1))
166 S[S == 0] = 1
167 data /= S[:, np.newaxis]
168 components_, self.variance_, _ = self._cache(
169 randomized_svd, func_memory_level=2
170 )(
171 data.T,
172 n_components=self.n_components,
173 transpose=True,
174 random_state=self.random_state,
175 n_iter=3,
176 )
177 if self.do_cca:
178 data *= S[:, np.newaxis]
179 self.components_ = components_.T
180 if hasattr(self, "masker_"):
181 self.components_img_ = self.masker_.inverse_transform(
182 components_.T
183 )
184 return components_