docstr: Get the recommended number of features by doing forward passes when max_features is set.
docstr_tok: ["Get","the","recommended","number","of","features","by","doing","forward","passes","when","max_features","is","set","."]
code: def _recommend_number_features(self, solver, max_time=None):
      """
      Get the recommended number of features by doing forward passes when max_features is set.
      """
      max_time = max_time if max_time else self.max_time
      if max_time < 0:
          max_time = (
              60  # allow 1 minute extra if we already spent max_time
          )
      MAX_FORWARD_PASS = 200
      MAX_FULL_BATCHES = (
          3  # the forward passes can take longer than the fitting
      )
      # if we allow a full epoch of data to be included. By only doing 3 full batches at most
      # we get enough accuracy without increasing the time too much. This
      # constant may not be optimal
      accum_steps = solver.accum_steps
      step_size = max(self.max_features / MAX_FORWARD_PASS, 1)
      # pylint: disable=E1130
      feature_order = np.argsort(-self.scores_)  # note the negative
      t = time.time()
  
      dataloader_iterator = iter(solver.ds_train)
      full_scores = []
      # keep_going = True
      with torch.no_grad():
          # might want to only consider a batch valid if there are at least
          # two classes
          for _ in range(accum_steps * MAX_FULL_BATCHES):
              scores = []
              try:
                  xsub, ysub = next(dataloader_iterator)
              except StopIteration:
                  # done with epoch, don't do more than one epoch
                  break
              except Exception as e:
                  print(e)
                  break
              if max_time and time.time() - t > max_time:
                  if self.verbose:
                      print(
                          "Stoppinn forward passes because they reached max_time: ",
                          max_time,
                      )
                  if not full_scores:
                      # no forward passes worked, return half of max_features
                      return self.max_features // 2
                  break
              if solver.multiclass:
                  for target_class in range(solver.n_classes):
                      ysub_binary = solver.transform_y_into_binary(
                          ysub, target_class
                      )
                      scaling_value = solver._get_scaling_value(
                          ysub, target_class
                      )
                      if not solver._skip_y_forward(ysub_binary):
                          scores = self._generate_scores(
                              solver,
                              xsub,
                              ysub_binary,
                              step_size,
                              feature_order,
                          )
                          # one row will represent one class that is present in the data
                          # all classes are weighted equally
                          full_scores.append(
                              [
                                  score * scaling_value
                                  for score in scores
                              ]
                          )
              else:
                  if not solver._skip_y_forward(ysub):
                      scores = self._generate_scores(
                          solver, xsub, ysub, step_size, feature_order
                      )
                      full_scores.append(scores)
      best_index = FeatureGradientSelector._find_best_index_elbow(
          full_scores
      )
      if self.verbose:
          print("Forward passes took: ", time.time() - t)
      # account for step size and off by one (n_features is 1 indexed, not 0
      # )
      return int(
          np.ceil(np.arange(1, self.max_features + 1, step_size))[
              best_index
          ]
      )
  
imports: import time
  import numpy
  import pandas
  from sklearn.base import BaseEstimator
  from sklearn.feature_selection import SelectorMixin
  from sklearn.utils.validation import check_is_fitted
  import torch
  from nni.feature_engineering.feature_selector import FeatureSelector
  from .None import constants
  from .fginitialize import PrepareData
  from .fgtrain import _train
label_desc: Use image node_id 22 for calling the FeatureGradientSelector obj's underlying member method code with example usage: obj._recommend_number_features(solver, max_time) and returns: int, unknown