docs: def fit(self, X, y=None):
          """Learn a model averaged proportion matrix for X.
          Parameters
          ----------
          X : ndarray, shape (n_samples, n_features)
              Data from which to compute the proportion matrix.
          """
          # default to QuicGraphicalLasso
          estimator = self.estimator or QuicGraphicalLasso()
  
          if self.penalization != "subsampling" and not hasattr(
              estimator, self.penalty_name
          ):
              raise ValueError(
                  (
                      "Must specify valid penalty for "
                      "estimator: {}.".format(self.penalty_name)
                  )
              )
  
          self.proportion_ = None
          self.support_ = None
          self.lam_ = None
          self.lam_scale_ = None
          self.estimators_ = []
          self.lams_ = []
          self.subsets_ = []
  
          X = check_array(X, ensure_min_features=2, estimator=self)
          X = as_float_array(X, copy=False, force_all_finite=False)
  
          n_samples_, n_features_ = X.shape
          _, self.lam_scale_ = _init_coefs(X, method=self.init_method)
  
          fit_fun = partial(
              _fit,
              penalization=self.penalization,
              lam=self.lam,
              lam_perturb=self.lam_perturb,
              lam_scale_=self.lam_scale_,
              estimator=estimator,
              penalty_name=self.penalty_name,
              subsample=self.subsample,
              bootstrap=self.bootstrap,
          )
          indexed_param_grid = [(nn,) for nn in range(self.n_trials)]
  
          if self.sc is None:
              results = _cpu_map(
                  partial(fit_fun, X=X, prng=self.prng),
                  indexed_param_grid,
                  n_jobs=self.n_jobs,
              )
          else:
              X_bc = self.sc.broadcast(X)
              results = _spark_map(fit_fun, indexed_param_grid, self.sc, self.seed, X_bc)
              X_bc.unpersist()
  
          self.estimators_ = [e for r, (l, s, e) in results]
          self.subsets_ = [s for r, (l, s, e) in results]
          self.lams_ = [l for r, (l, s, e) in results]
  
          # reduce
          self.lam_ = 0.0
          self.proportion_ = np.zeros((n_features_, n_features_))
          for new_estimator in self.estimators_:
              # update proportions
              if isinstance(new_estimator.precision_, list):
                  for prec in new_estimator.precision_:
                      self.proportion_[np.nonzero(prec)] += 1.
  
              elif isinstance(new_estimator.precision_, np.ndarray):
                  self.proportion_[np.nonzero(new_estimator.precision_)] += 1.
  
              else:
                  raise ValueError("Estimator returned invalid precision_.")
  
              # currently, dont estimate self.lam_ if penalty_name is different
              if self.penalty_name == "lam":
                  self.lam_ += np.mean(new_estimator.lam_.flat)
  
          # estimate support locations
          threshold = self.support_thresh * self.n_trials
          self.support_ = np.zeros(self.proportion_.shape)
          self.support_[self.proportion_ > threshold] = 1.0
  
          self.lam_ /= self.n_trials
          if self.normalize:
              self.proportion_ /= self.n_trials
  
          return self