class_docstr: A wrapper for popular classification/regression strategies in     neuroimaging.
  
  The `BaseDecoder` object supports classification and regression methods.
  It implements a model selection scheme that averages the best models
  within a cross validation loop (a technique sometimes known as CV bagging).
  The resulting average model is the one used as a classifier or a regressor.
  This object also leverages the `NiftiMaskers` to provide a direct interface
  with the Nifti files on disk.
  
  Parameters
  ----------
  estimator: str, default='svc'
      The estimator to use. For classification, choose among:
      %(classifier_options)s
      For regression, choose among:
      %(regressor_options)s
  
  mask: filename, Nifti1Image, NiftiMasker, MultiNiftiMasker, or          SurfaceMasker, default=None
      Mask to be used on data. If an instance of masker is passed,
      then its mask and parameters will be used. If no mask is given, mask
      will be computed automatically from provided images by an inbuilt
      masker with default parameters. Refer to NiftiMasker, MultiNiftiMasker
      or SurfaceMasker to check for default parameters. For use with
      SurfaceImage data, a SurfaceMasker instance must be passed.
  
  cv: cross-validation generator or int, default=10
      A cross-validation generator.
      See: https://scikit-learn.org/stable/modules/cross_validation.html
  
  param_grid: dict of str to sequence, or sequence of such, default=None
      The parameter grid to explore, as a dictionary mapping estimator
      parameters to sequences of allowed values.
  
      None or an empty dict signifies default parameters.
  
      A sequence of dicts signifies a sequence of grids to search, and is
      useful to avoid exploring parameter combinations that make no sense
      or have no effect. See scikit-learn documentation for more information,
      for example: https://scikit-learn.org/stable/modules/grid_search.html
  
      For Dummy estimators, parameter grid defaults to empty dictionary.
  
  clustering_percentile: int, float, in the [0, 100], default=10
      Percentile of features to keep after clustering. If it is lower
      than 100, a ReNA clustering is performed as a first step of fit
      to agglomerate similar features together. ReNA is typically efficient
      for clustering_percentile equal to 10.
  
  screening_percentile: int, float,                           in the closed interval [0, 100],                           default=20
      The percentage of brain volume that will be kept with respect to a full
      MNI template. In particular, if it is lower than 100, a univariate
      feature selection based on the Anova F-value for the input data will be
      performed. A float according to a percentile of the highest
      scores.
  
  scoring: str, callable or None,
           default=None
      The scoring strategy to use. See the scikit-learn documentation at
      https://scikit-learn.org/stable/modules/model_evaluation.html#the-scoring-parameter-defining-model-evaluation-rules
      If callable, takes as arguments the fitted estimator, the
      test data (X_test) and the test target (y_test) if y is
      not None.
      e.g. scorer(estimator, X_test, y_test)
  
      For regression, valid entries are: 'r2', 'neg_mean_absolute_error', or
      'neg_mean_squared_error'. Defaults to 'r2'.
  
      For classification, valid entries are: 'accuracy', 'f1', 'precision',
      'recall' or 'roc_auc'. Defaults to 'roc_auc'.
  %(smoothing_fwhm)s
  %(standardize)s
  %(target_affine)s
  %(target_shape)s
  %(low_pass)s
  %(high_pass)s
  %(t_r)s
  %(mask_strategy)s
  
      .. note::
          This parameter will be ignored if a mask image is provided.
  
      .. note::
          Depending on this value, the mask will be computed from
          :func:`nilearn.masking.compute_background_mask`,
          :func:`nilearn.masking.compute_epi_mask`, or
          :func:`nilearn.masking.compute_brain_mask`.
  
      Default is 'background'.
  %(memory)s
  %(memory_level)s
  %(n_jobs)s
  %(verbose0)s
  
  See Also
  --------
  nilearn.decoding.Decoder: Classification strategies for Neuroimaging,
  nilearn.decoding.DecoderRegressor: Regression strategies for Neuroimaging,
  nilearn.decoding.FREMClassifier: State of the art classification pipeline
      for Neuroimaging
  nilearn.decoding.FREMRegressor: State of the art regression pipeline
      for Neuroimaging
  nilearn.decoding.SpaceNetClassifier: Graph-Net and TV-L1 priors/penalties
class_docstr_tok: ["A","wrapper","for","popular","classification\/regression","strategies","in","neuroimaging",".","The","`","BaseDecoder","`","object","supports","classification","and","regression","methods",".","It","implements","a","model","selection","scheme","that","averages","the","best","models","within","a","cross","validation","loop","(","a","technique","sometimes","known","as","CV","bagging",")",".","The","resulting","average","model","is","the","one","used","as","a","classifier","or","a","regressor",".","This","object","also","leverages","the","`","NiftiMaskers","`","to","provide","a","direct","interface","with","the","Nifti","files","on","disk",".","Parameters","--","--","--","--","--","estimator",":","str",",","default='svc'","The","estimator","to","use",".","For","classification",",","choose","among",":","%","(","classifier_options",")","s","For","regression",",","choose","among",":","%","(","regressor_options",")","s","mask",":","filename",",","Nifti1Image",",","NiftiMasker",",","MultiNiftiMasker",",","or","SurfaceMasker",",","default=None","Mask","to","be","used","on","data",".","If","an","instance","of","masker","is","passed",",","then","its","mask","and","parameters","will","be","used",".","If","no","mask","is","given",",","mask","will","be","computed","automatically","from","provided","images","by","an","inbuilt","masker","with","default","parameters",".","Refer","to","NiftiMasker",",","MultiNiftiMasker","or","SurfaceMasker","to","check","for","default","parameters",".","For","use","with","SurfaceImage","data",",","a","SurfaceMasker","instance","must","be","passed",".","cv",":","cross-validation","generator","or","int",",","default=10","A","cross-validation","generator",".","See",":","https",":","\/\/scikit-learn.org\/stable\/modules\/cross_validation.html","param_grid",":","dict","of","str","to","sequence",",","or","sequence","of","such",",","default=None","The","parameter","grid","to","explore",",","as","a","dictionary","mapping","estimator","parameters","to","sequences","of","allowed","values",".","None","or","an","empty","dict","signifies","default","parameters",".","A","sequence","of","dicts","signifies","a","sequence","of","grids","to","search",",","and","is","useful","to","avoid","exploring","parameter","combinations","that","make","no","sense","or","have","no","effect",".","See","scikit-learn","documentation","for","more","information",",","for","example",":","https",":","\/\/scikit-learn.org\/stable\/modules\/grid_search.html","For","Dummy","estimators",",","parameter","grid","defaults","to","empty","dictionary",".","clustering_percentile",":","int",",","float",",","in","the","[","0",",","100","]",",","default=10","Percentile","of","features","to","keep","after","clustering",".","If","it","is","lower","than","100",",","a","ReNA","clustering","is","performed","as","a","first","step","of","fit","to","agglomerate","similar","features","together",".","ReNA","is","typically","efficient","for","clustering_percentile","equal","to","10.","screening_percentile",":","int",",","float",",","in","the","closed","interval","[","0",",","100","]",",","default=20","The","percentage","of","brain","volume","that","will","be","kept","with","respect","to","a","full","MNI","template",".","In","particular",",","if","it","is","lower","than","100",",","a","univariate","feature","selection","based","on","the","Anova","F-value","for","the","input","data","will","be","performed",".","A","float","according","to","a","percentile","of","the","highest","scores",".","scoring",":","str",",","callable","or","None",",","default=None","The","scoring","strategy","to","use",".","See","the","scikit-learn","documentation","at","https",":","\/\/scikit-learn.org\/stable\/modules\/model_evaluation.html","#","the-scoring-parameter-defining-model-evaluation-rules","If","callable",",","takes","as","arguments","the","fitted","estimator",",","the","test","data","(","X_test",")","and","the","test","target","(","y_test",")","if","y","is","not","None",".","e.g",".","scorer","(","estimator",",","X_test",",","y_test",")","For","regression",",","valid","entries","are",":","'r2","'",",","'neg_mean_absolute_error","'",",","or","'neg_mean_squared_error","'",".","Defaults","to","'r2","'",".","For","classification",",","valid","entries","are",":","'accuracy","'",",","'f1","'",",","'precision","'",",","'recall","'","or","'roc_auc","'",".","Defaults","to","'roc_auc","'",".","%","(","smoothing_fwhm",")","s","%","(","standardize",")","s","%","(","target_affine",")","s","%","(","target_shape",")","s","%","(","low_pass",")","s","%","(","high_pass",")","s","%","(","t_r",")","s","%","(","mask_strategy",")","s","..","note",":",":","This","parameter","will","be","ignored","if","a","mask","image","is","provided",".","..","note",":",":","Depending","on","this","value",",","the","mask","will","be","computed","from",":","func",":","`","nilearn.masking.compute_background_mask","`",",",":","func",":","`","nilearn.masking.compute_epi_mask","`",",","or",":","func",":","`","nilearn.masking.compute_brain_mask","`",".","Default","is","'background","'",".","%","(","memory",")","s","%","(","memory_level",")","s","%","(","n_jobs",")","s","%","(","verbose0",")","s","See","Also","--","--","--","--","nilearn.decoding.Decoder",":","Classification","strategies","for","Neuroimaging",",","nilearn.decoding.DecoderRegressor",":","Regression","strategies","for","Neuroimaging",",","nilearn.decoding.FREMClassifier",":","State","of","the","art","classification","pipeline","for","Neuroimaging","nilearn.decoding.FREMRegressor",":","State","of","the","art","regression","pipeline","for","Neuroimaging","nilearn.decoding.SpaceNetClassifier",":","Graph-Net","and","TV-L1","priors\/penalties"]
docstr: Fit the decoder (learner).
  
  Parameters
  ----------
  X: list of Niimg-like or SurfaceImage objects
      See :ref:`extracting_data`.
      Data on which model is to be fitted. If this is a list,
      the affine is considered the same for all.
  
  y: numpy.ndarray of shape=(n_samples) or list of length n_samples
      The dependent variable (age, sex, IQ, yes/no, etc.).
      Target variable to predict. Must have exactly as many elements as
      3D images in niimg.
  
  groups: None
      Group labels for the samples used while splitting the dataset into
      train/test set. Default None.
  
      Note that this parameter must be specified in some scikit-learn
      cross-validation generators to calculate the number of splits, e.g.
      sklearn.model_selection.LeaveOneGroupOut or
      sklearn.model_selection.LeavePGroupsOut.
  
      For more details see
      https://scikit-learn.org/stable/modules/cross_validation.html#cross-validation-iterators-for-grouped-data
  
  Attributes
  ----------
  masker_ : instance of NiftiMasker, MultiNiftiMasker, or SurfaceMasker
      The masker used to mask the data.
  
  mask_img_ : Nifti1Image or SurfaceImage
      Mask computed by the masker object.
  
  classes_ : numpy.ndarray
      Classes to predict. For classification only.
  
  screening_percentile_ : float
      Screening percentile corrected according to volume of mask,
      relative to the volume of standard brain.
  
  coef_ : numpy.ndarray, shape=(n_classes, n_features)
      Contains the mean of the models weight vector across
      fold for each class. Returns None for Dummy estimators.
  
  coef_img_ : dict of Nifti1Image
      Dictionary containing `coef_` with class names as keys,
      and `coef_` transformed in Nifti1Images as values. In the case of
      a regression, it contains a single Nifti1Image at the key 'beta'.
      Ignored if Dummy estimators are provided.
  
  intercept_ : ndarray, shape (nclasses,)
      Intercept (a.k.a. bias) added to the decision function.
      Ignored if Dummy estimators are provided.
  
  cv_ : list of pairs of lists
      List of the (n_folds,) folds. For the corresponding fold,
      each pair is composed of two lists of indices,
      one for the train samples and one for the test samples.
  
  std_coef_ : numpy.ndarray, shape=(n_classes, n_features)
      Contains the standard deviation of the models weight vector across
      fold for each class. Note that folds are not independent, see
      https://scikit-learn.org/stable/modules/cross_validation.html#cross-validation-iterators-for-grouped-data
      Ignored if Dummy estimators are provided.
  
  std_coef_img_ : dict of Nifti1Image
      Dictionary containing `std_coef_` with class names as keys,
      and `coef_` transformed in Nifti1Image as values. In the case of
      a regression, it contains a single Nifti1Image at the key 'beta'.
      Ignored if Dummy estimators are provided.
  
  cv_params_ : dict of lists
      Best point in the parameter grid for each tested fold
      in the inner cross validation loop. The grid is empty
      when Dummy estimators are provided. Note: if the estimator used its
      built-in cross-validation, this will include an additional key for
      the single best value estimated by the built-in cross-validation
      ('best_C' for LogisticRegressionCV and 'best_alpha' for
      RidgeCV/RidgeClassifierCV/LassoCV), in addition to the input list
      of values.
  
  scorer_ : function
      Scorer function used on the held out data to choose the best
      parameters for the model.
  
  cv_scores_ : dict, (classes, n_folds)
      Scores (misclassification) for each parameter, and on each fold
  
  n_outputs_ : int
      Number of outputs (column-wise)
  
  dummy_output_: ndarray, shape=(n_classes, 2)
      or shape=(1, 1) for regression
      Contains dummy estimator attributes after class predictions
      using strategies of DummyClassifier (class_prior)
      and DummyRegressor (constant) from scikit-learn.
      This attribute is necessary for estimating class predictions
      after fit.
      Returns None if non-dummy estimators are provided.
code: def fit(self, X, y, groups=None):
      """Fit the decoder (learner).
  
      Parameters
      ----------
      X: list of Niimg-like or SurfaceImage objects
          See :ref:`extracting_data`.
          Data on which model is to be fitted. If this is a list,
          the affine is considered the same for all.
  
      y: numpy.ndarray of shape=(n_samples) or list of length n_samples
          The dependent variable (age, sex, IQ, yes/no, etc.).
          Target variable to predict. Must have exactly as many elements as
          3D images in niimg.
  
      groups: None
          Group labels for the samples used while splitting the dataset into
          train/test set. Default None.
  
          Note that this parameter must be specified in some scikit-learn
          cross-validation generators to calculate the number of splits, e.g.
          sklearn.model_selection.LeaveOneGroupOut or
          sklearn.model_selection.LeavePGroupsOut.
  
          For more details see
          https://scikit-learn.org/stable/modules/cross_validation.html#cross-validation-iterators-for-grouped-data
  
      Attributes
      ----------
      masker_ : instance of NiftiMasker, MultiNiftiMasker, or SurfaceMasker
          The masker used to mask the data.
  
      mask_img_ : Nifti1Image or SurfaceImage
          Mask computed by the masker object.
  
      classes_ : numpy.ndarray
          Classes to predict. For classification only.
  
      screening_percentile_ : float
          Screening percentile corrected according to volume of mask,
          relative to the volume of standard brain.
  
      coef_ : numpy.ndarray, shape=(n_classes, n_features)
          Contains the mean of the models weight vector across
          fold for each class. Returns None for Dummy estimators.
  
      coef_img_ : dict of Nifti1Image
          Dictionary containing `coef_` with class names as keys,
          and `coef_` transformed in Nifti1Images as values. In the case of
          a regression, it contains a single Nifti1Image at the key 'beta'.
          Ignored if Dummy estimators are provided.
  
      intercept_ : ndarray, shape (nclasses,)
          Intercept (a.k.a. bias) added to the decision function.
          Ignored if Dummy estimators are provided.
  
      cv_ : list of pairs of lists
          List of the (n_folds,) folds. For the corresponding fold,
          each pair is composed of two lists of indices,
          one for the train samples and one for the test samples.
  
      std_coef_ : numpy.ndarray, shape=(n_classes, n_features)
          Contains the standard deviation of the models weight vector across
          fold for each class. Note that folds are not independent, see
          https://scikit-learn.org/stable/modules/cross_validation.html#cross-validation-iterators-for-grouped-data
          Ignored if Dummy estimators are provided.
  
      std_coef_img_ : dict of Nifti1Image
          Dictionary containing `std_coef_` with class names as keys,
          and `coef_` transformed in Nifti1Image as values. In the case of
          a regression, it contains a single Nifti1Image at the key 'beta'.
          Ignored if Dummy estimators are provided.
  
      cv_params_ : dict of lists
          Best point in the parameter grid for each tested fold
          in the inner cross validation loop. The grid is empty
          when Dummy estimators are provided. Note: if the estimator used its
          built-in cross-validation, this will include an additional key for
          the single best value estimated by the built-in cross-validation
          ('best_C' for LogisticRegressionCV and 'best_alpha' for
          RidgeCV/RidgeClassifierCV/LassoCV), in addition to the input list
          of values.
  
      scorer_ : function
          Scorer function used on the held out data to choose the best
          parameters for the model.
  
      cv_scores_ : dict, (classes, n_folds)
          Scores (misclassification) for each parameter, and on each fold
  
      n_outputs_ : int
          Number of outputs (column-wise)
  
      dummy_output_: ndarray, shape=(n_classes, 2)
          or shape=(1, 1) for regression
          Contains dummy estimator attributes after class predictions
          using strategies of DummyClassifier (class_prior)
          and DummyRegressor (constant) from scikit-learn.
          This attribute is necessary for estimating class predictions
          after fit.
          Returns None if non-dummy estimators are provided.
      """
      self.estimator = _check_estimator(self.estimator)
      self.memory_ = _check_memory(self.memory, self.verbose)
  
      X = self._apply_mask(X)
      X, y = check_X_y(X, y, dtype=np.float64, multi_output=True)
  
      self.n_outputs_ = 1 if y.ndim == 1 else y.shape[1]
  
      self._set_scorer()
  
      # Setup cross-validation object. Default is StratifiedKFold when groups
      # is None. If groups is specified but self.cv is not set to custom CV
      # splitter, default is LeaveOneGroupOut. If self.cv is manually set to
      # a CV splitter object do check_cv regardless of groups parameter.
      cv = self.cv
      if (isinstance(cv, int) or cv is None) and groups is not None:
          warnings.warn(
              "groups parameter is specified but "
              "cv parameter is not set to custom CV splitter. "
              "Using default object LeaveOneGroupOut()."
          )
          cv_object = LeaveOneGroupOut()
      else:
          cv_object = check_cv(
              cv, y=y, classifier=self.is_classification
          )
  
      self.cv_ = list(cv_object.split(X, y, groups=groups))
  
      # Define the number problems to solve. In case of classification this
      # number corresponds to the number of binary problems to solve
      y = (
          self._binarize_y(y)
          if self.is_classification
          else y[:, np.newaxis]
      )
  
      if self.is_classification and self.n_classes_ > 2:
          n_problems = self.n_classes_
      else:
          n_problems = 1
  
      # Check if the size of the mask image and the number of features allow
      # to perform feature screening.
      selector = check_feature_screening(
          self.screening_percentile,
          self.mask_img_,
          self.is_classification,
      )
      # Return a suitable screening percentile according to the mask image
      if hasattr(selector, "percentile"):
          self.screening_percentile_ = selector.percentile
      elif self.screening_percentile is None:
          self.screening_percentile_ = 100.0
      else:
          self.screening_percentile_ = self.screening_percentile
  
      n_final_features = int(
          X.shape[1]
          * self.screening_percentile_
          * self.clustering_percentile
          / 10000
      )
      if n_final_features < 50:
          warnings.warn(
              "After clustering and screening, the decoding model will "
              f"be trained only on {n_final_features} features. "
              + "Consider raising clustering_percentile or "
              + "screening_percentile parameters.",
              UserWarning,
          )
  
      parallel = Parallel(n_jobs=self.n_jobs, verbose=2 * self.verbose)
  
      parallel_fit_outputs = parallel(
          delayed(self._cache(_parallel_fit))(
              estimator=self.estimator,
              X=X,
              y=y[:, c],
              train=train,
              test=test,
              param_grid=self.param_grid,
              is_classification=self.is_classification,
              selector=selector,
              scorer=self.scorer_,
              mask_img=self.mask_img_,
              class_index=c,
              clustering_percentile=self.clustering_percentile,
          )
          for c, (train, test) in itertools.product(
              range(n_problems), self.cv_
          )
      )
  
      coefs, intercepts = self._fetch_parallel_fit_outputs(
          parallel_fit_outputs, y, n_problems
      )
  
      # Build the final model (the aggregated one)
      if not isinstance(
          self.estimator, (DummyClassifier, DummyRegressor)
      ):
          self.coef_ = np.vstack(
              [
                  np.mean(coefs[class_index], axis=0)
                  for class_index in self.classes_
              ]
          )
          self.std_coef_ = np.vstack(
              [
                  np.std(coefs[class_index], axis=0)
                  for class_index in self.classes_
              ]
          )
          self.intercept_ = np.hstack(
              [
                  np.mean(intercepts[class_index], axis=0)
                  for class_index in self.classes_
              ]
          )
  
          self.coef_img_, self.std_coef_img_ = self._output_image(
              self.classes_, self.coef_, self.std_coef_
          )
  
          if self.is_classification and (self.n_classes_ == 2):
              self.coef_ = self.coef_[0, :][np.newaxis, :]
              self.intercept_ = self.intercept_[0]
      else:
          # For Dummy estimators
          self.coef_ = None
          self.dummy_output_ = np.vstack(
              [
                  np.mean(self.dummy_output_[class_index], axis=0)
                  for class_index in self.classes_
              ]
          )
          if self.is_classification and (self.n_classes_ == 2):
              self.dummy_output_ = self.dummy_output_[0, :][
                  np.newaxis, :
              ]
  
imports: import itertools
  import warnings
  from typing import Iterable
  import numpy
  from joblib import Parallel, delayed
  from sklearn import clone
  from sklearn.base import BaseEstimator, MultiOutputMixin
  from sklearn.dummy import DummyClassifier, DummyRegressor
  from sklearn.linear_model import LassoCV, LogisticRegressionCV, RidgeClassifierCV, RidgeCV
  from sklearn.metrics import check_scoring, get_scorer
  from sklearn.model_selection import LeaveOneGroupOut, ParameterGrid, ShuffleSplit, StratifiedShuffleSplit, check_cv
  from sklearn.preprocessing import LabelBinarizer
  from sklearn.svm import SVR, LinearSVC, l1_min_c
  from sklearn.utils.extmath import safe_sparse_dot
  from sklearn.utils.validation import check_is_fitted, check_X_y
  from nilearn._utils import CacheMixin, fill_doc
  from nilearn._utils.cache_mixin import _check_memory
  from nilearn._utils.masker_validation import check_embedded_masker
  from nilearn._utils.param_validation import check_feature_screening
  from nilearn.experimental.surface import SurfaceMasker
  from nilearn.regions.rena_clustering import ReNA
label_desc: Use image node_id 2 for calling the _BaseDecoder obj's underlying member method code with example usage: obj.fit(X, y, groups) without return types