code: def binary_classification(
      target,
      predictions,
      sample_weight=None,
      sensitive_features=None,
      fairness_metric=None,
      fairness_threshold=None,
      privileged_groups=[],
      underprivileged_groups=[],
      previous_fairness_optimization=None,
  ):
      negative_label, positive_label = "0", "1"
      mapping = None
      try:
          pred_col = predictions.columns[0]
          if "_0_for_" in pred_col and "_1_for_" in pred_col:
              t = pred_col.split("_0_for_")[1]
              t = t.split("_1_for_")
              negative_label, positive_label = t[0], t[1]
              mapping = {0: negative_label, 1: positive_label}
      except Exception as e:
          pass
  
      predictions = np.array(predictions).flatten()
      sorted_predictions = np.sort(predictions)
  
      STEPS = 100  # can go lower for speed increase ???
      details = {
          "threshold": [],
          "f1": [],
          "accuracy": [],
          "precision": [],
          "recall": [],
          "mcc": [],
      }
      samples_per_step = max(1, np.floor(predictions.shape[0] / STEPS))
  
      for i in range(STEPS):
          idx = int(i * samples_per_step)
          if idx + 1 >= predictions.shape[0]:
              break
          if i == 0:
              th = 0.9 * np.min(sorted_predictions)
          else:
              th = float(
                  0.5
                  * (
                      sorted_predictions[idx]
                      + sorted_predictions[idx + 1]
                  )
              )
  
          if np.sum(predictions > th) < 1:
              break
          response = (predictions > th).astype(int)
  
          details["threshold"] += [th]
          details["f1"] += [
              f1_score(target, response, sample_weight=sample_weight)
          ]
          details["accuracy"] += [
              accuracy_score(
                  target, response, sample_weight=sample_weight
              )
          ]
          details["precision"] += [
              precision_score(
                  target, response, sample_weight=sample_weight
              )
          ]
          details["recall"] += [
              recall_score(
                  target, response, sample_weight=sample_weight
              )
          ]
          if i == 0:
              details["mcc"] += [0.0]
          else:
              details["mcc"] += [
                  matthews_corrcoef(
                      target, response, sample_weight=sample_weight
                  )
              ]
  
      # max metrics
      max_metrics = {
          "logloss": {
              "score": logloss(
                  target, predictions, sample_weight=sample_weight
              ),
              "threshold": None,
          },  # there is no threshold for LogLoss
          "auc": {
              "score": roc_auc_score(
                  target, predictions, sample_weight=sample_weight
              ),
              "threshold": None,
          },  # there is no threshold for AUC
          "f1": {
              "score": np.max(details["f1"]),
              "threshold": details["threshold"][
                  np.argmax(details["f1"])
              ],
          },
          "accuracy": {
              "score": np.max(details["accuracy"]),
              "threshold": details["threshold"][
                  np.argmax(details["accuracy"])
              ],
          },
          "precision": {
              "score": np.max(details["precision"]),
              "threshold": details["threshold"][
                  np.argmax(details["precision"])
              ],
          },
          "recall": {
              "score": np.max(details["recall"]),
              "threshold": details["threshold"][
                  np.argmax(details["recall"])
              ],
          },
          "mcc": {
              "score": np.max(details["mcc"]),
              "threshold": details["threshold"][
                  np.argmax(details["mcc"])
              ],
          },
      }
  
      threshold = float(max_metrics["accuracy"]["threshold"])
  
      # updating resopnse variable for accuracy metric
      response = (predictions > threshold).astype(int)
  
      # accuracy threshold metrics
      accuracy_threshold_metrics = {
          "logloss": {
              "score": logloss(
                  target, predictions, sample_weight=sample_weight
              ),
              "threshold": None,
          },  # there is no threshold for LogLoss
          "auc": {
              "score": roc_auc_score(
                  target, predictions, sample_weight=sample_weight
              ),
              "threshold": None,
          },  # there is no threshold for AUC
          "f1": {
              "score": f1_score(
                  target, response, sample_weight=sample_weight
              ),
              "threshold": threshold,
          },
          "accuracy": {
              "score": accuracy_score(
                  target, response, sample_weight=sample_weight
              ),
              "threshold": threshold,
          },
          "precision": {
              "score": precision_score(
                  target, response, sample_weight=sample_weight
              ),
              "threshold": threshold,
          },
          "recall": {
              "score": recall_score(
                  target, response, sample_weight=sample_weight
              ),
              "threshold": threshold,
          },
          "mcc": {
              "score": matthews_corrcoef(
                  target, response, sample_weight=sample_weight
              ),
              "threshold": threshold,
          },
      }
  
      # if sample_weight is not None:
      #    new_max_metrics = {}
      #    for k, v in max_metrics.items():
      #        new_max_metrics["weighted_" + k] = v
      #    max_metrics = new_max_metrics
  
      # confusion matrix
  
      conf_matrix = confusion_matrix(
          target, predictions > threshold, sample_weight=sample_weight
      )
  
      conf_matrix = pd.DataFrame(
          conf_matrix,
          columns=[
              f"Predicted as {negative_label}",
              f"Predicted as {positive_label}",
          ],
          index=[
              f"Labeled as {negative_label}",
              f"Labeled as {positive_label}",
          ],
      )
  
      predicted_labels = pd.Series(
          (predictions.ravel() > threshold).astype(int)
      )
      predicted_labels_01 = predicted_labels.copy()
      predicted_probas = pd.DataFrame(
          {
              "proba_0": 1 - predictions.ravel(),
              "proba_1": predictions.ravel(),
          }
      )
  
      if mapping is not None:
          labeled_target = target["target"].map(mapping)
          predicted_labels = predicted_labels.map(mapping)
      else:
          labeled_target = target
  
      metrics = {
          "metric_details": pd.DataFrame(details),
          "max_metrics": pd.DataFrame(max_metrics),
          "accuracy_threshold_metrics": pd.DataFrame(
              accuracy_threshold_metrics
          ),
          "confusion_matrix": conf_matrix,
          "threshold": threshold,
          "additional_plots": AdditionalPlots.plots_binary(
              labeled_target, predicted_labels, predicted_probas
          ),
      }
  
      if sensitive_features is not None:
          metrics[
              "fairness_metrics"
          ] = FairnessMetrics.binary_classification(
              target,
              predicted_labels_01,
              sensitive_features,
              fairness_metric,
              fairness_threshold,
              privileged_groups,
              underprivileged_groups,
              previous_fairness_optimization,
          )
  
      return metrics
  
imports: import copy
  import json
  import logging
  import os
  import time
  import uuid
  import warnings
  import numpy
  import pandas
  from sklearn.metrics import accuracy_score, classification_report, confusion_matrix, f1_score, matthews_corrcoef, mean_absolute_error, mean_absolute_percentage_error, mean_squared_error, precision_score, r2_score, recall_score, roc_auc_score
  from supervised.algorithms.registry import BINARY_CLASSIFICATION, MULTICLASS_CLASSIFICATION, REGRESSION
  from supervised.utils.metric import logloss
  from supervised.utils.config import LOG_LEVEL
  from tabulate import tabulate
  from supervised.fairness.metrics import FairnessMetrics
  from supervised.fairness.report import FairnessReport
  from supervised.fairness.utils import accuracy, false_negative_rate, false_positive_rate, selection_rate, true_negative_rate, true_positive_rate
  from supervised.utils.additional_plots import AdditionalPlots
  from supervised.utils.common import construct_learner_name, get_fold_repeat_cnt
  from supervised.utils.learning_curves import LearningCurves
  from supervised.utils.jsonencoder import MLJSONEncoder
label_desc: Use image node_id 1 for calling the AdditionalMetrics obj's underlying member method code with example usage: obj.binary_classification(target, predictions, sample_weight, sensitive_features, fairness_metric, fairness_threshold, privileged_groups, underprivileged_groups, previous_fairness_optimization) and returns: metrics