code: def get_features_selection_params(
      self, current_models, results_path, total_time_limit
  ):
      fname = os.path.join(results_path, "drop_features.json")
      if not os.path.exists(fname):
          return None
  
      drop_features = json.load(open(fname, "r"))
      print("Drop features", drop_features)
  
      # in case of droping only one feature (random_feature)
      # skip this step
      if len(drop_features) <= 1:
          return None
  
      model_selection_time_limit = (
          None if total_time_limit is None else 0.1 * total_time_limit
      )
      df_models, algorithms = self.df_models_algorithms(
          current_models, time_limit=model_selection_time_limit
      )
  
      generated_params = []
      for m_type in algorithms:
          # try to do features selection only for below algorithms
          if m_type not in [
              "Xgboost",
              "LightGBM",
              "CatBoost",
              "Neural Network",
              "Random Forest",
              "Extra Trees",
          ]:
              continue
          models = df_models[df_models.model_type == m_type]["model"]
  
          for i in range(min(1, len(models))):
              m = models.iloc[i]
  
              params = copy.deepcopy(m.params)
              params["preprocessing"]["drop_features"] = drop_features
              params["name"] += "_SelectedFeatures"
              params["status"] = "initialized"
              params["final_loss"] = None
              params["train_time"] = None
              params["data_type"] = (
                  params.get("data_type", "") + "_features_selection"
              )
              if self._optuna_time_budget is not None:
                  params[
                      "optuna_time_budget"
                  ] = self._optuna_time_budget
                  params[
                      "optuna_init_params"
                  ] = self._optuna_init_params
                  params["optuna_verbose"] = self._optuna_verbose
  
              if "model_architecture_json" in params["learner"]:
                  del params["learner"]["model_architecture_json"]
              unique_params_key = MljarTuner.get_params_key(params)
              if unique_params_key not in self._unique_params_keys:
                  generated_params += [params]
      return generated_params
  
imports: import copy
  import json
  import logging
  import os
  import numpy
  import pandas
  from sklearn.preprocessing import OneHotEncoder
  from supervised.algorithms.catboost import catboost_eval_metric
  from supervised.algorithms.lightgbm import lightgbm_eval_metric
  from supervised.algorithms.registry import BINARY_CLASSIFICATION, MULTICLASS_CLASSIFICATION, REGRESSION, AlgorithmsRegistry
  from supervised.algorithms.xgboost import xgboost_eval_metric
  from supervised.preprocessing.label_encoder import LabelEncoder
  from supervised.preprocessing.preprocessing_categorical import PreprocessingCategorical
  from supervised.tuner.hill_climbing import HillClimbing
  from supervised.tuner.preprocessing_tuner import PreprocessingTuner
  from supervised.tuner.random_parameters import RandomParameters
  from supervised.utils.config import LOG_LEVEL
  from supervised.utils.utils import dump_data, load_data
label_desc: Use image node_id 30 for calling the MljarTuner obj's underlying member method code with example usage: obj.get_features_selection_params(current_models, results_path, total_time_limit) and returns: generated_params, None, None