code: def fairness_optimization_binary_classification(
      self, current_models, results_path
  ):
      df_models, algorithms = self.df_models_algorithms(current_models)
  
      generated_params = []
      counts = {model_type: 0 for model_type in algorithms}
  
      # get sensitive features for all samples
      sensitive_features_path = os.path.join(
          results_path, "sensitive_features.data"
      )
      sensitive_features = load_data(sensitive_features_path)
  
      # get target
      y_path = os.path.join(results_path, "y.data")
      target = np.array(load_data(y_path)["target"])
  
      # we operate here on full target data (for all samples)
      # we can't load preprocessed targets from other place
      # we need to perform preprocessing here
      if df_models.shape[0] > 0:
          target_preprocessing = (
              df_models["model"]
              .iloc[0]
              .params.get("preprocessing", {})
              .get("target_preprocessing", {})
          )
          if (
              PreprocessingCategorical.CONVERT_INTEGER
              in target_preprocessing
          ):
              cat_y = LabelEncoder(try_to_fit_numeric=True)
              cat_y.fit(target)
              target = cat_y.transform(target)
  
      sensitive_columns = list(sensitive_features.columns)
  
      for i in range(df_models.shape[0]):
          model_type = df_models["model_type"].iloc[i]
  
          if df_models["model_type"].iloc[i] in ["Baseline"]:
              # we dont optimize Baseline
              continue
  
          counts[model_type] += 1
          if counts[model_type] > 1:
              continue
  
          m = df_models["model"].iloc[i]
  
          if "ratio" in self._fairness_metric.lower():
              if m.get_worst_fairness() > self._fairness_threshold:
                  continue
          else:
              if m.get_worst_fairness() < self._fairness_threshold:
                  continue
  
          fo = m.get_fairness_optimization()
          fo_step = fo.get("step", 0)
  
          samples_weight = np.ones(sensitive_features.shape[0])
  
          fo = m.get_fairness_optimization()
          weights = fo.get("weights")
          for k, ws in weights.items():
              sensitive_values = k.split("@")
              ii = None
              for i, sv in enumerate(sensitive_values):
                  if ii is None:
                      ii = (
                          sensitive_features[sensitive_columns[i]] == sv
                      )
                  else:
                      ii &= (
                          sensitive_features[sensitive_columns[i]] == sv
                      )
  
              samples_weight[ii & (target == 0)] = max(ws[0], 0.01)
              samples_weight[ii & (target == 1)] = max(
                  ws[1], 0.01
              )  # weight cant be negative
  
          samples_weight = (
              samples_weight * target.shape[0] / np.sum(samples_weight)
          )
  
          sample_weight_path = os.path.join(
              results_path,
              m.get_type() + f"_fairness_sample_weight_{fo_step}.data",
          )
          dump_data(
              sample_weight_path,
              pd.DataFrame({"sample_weight": samples_weight}),
          )
  
          fo = m.get_fairness_optimization()
          fo["step"] = fo_step
  
          params = copy.deepcopy(m.params)
          params["fairness_optimization"] = fo
  
          params["validation_strategy"][
              "sample_weight_path"
          ] = sample_weight_path
          params["injected_sample_weight"] = True
          if "SampleWeigthing" not in params["name"]:
              params["name"] += "_SampleWeigthing"
          if fo_step > 0:
              if "Update" in params["name"]:
                  n = params["name"].split("_")
                  params["name"] = "_".join(n[:-2])
              params["name"] += f"_Update_{fo_step}"
  
          params["status"] = "initialized"
          params["final_loss"] = None
          params["train_time"] = None
          params["data_type"] = "fairness"
          if "model_architecture_json" in params["learner"]:
              del params["learner"]["model_architecture_json"]
          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
  
          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 9 for calling the MljarTuner obj's underlying member method code with example usage: obj.fairness_optimization_binary_classification(current_models, results_path) and returns: generated_params