code: def regression(
      target,
      predictions,
      sensitive_features,
      fairness_metric,
      fairness_threshold,
      privileged_groups=[],
      underprivileged_groups=[],
      previous_fairness_optimization=None,
  ):
      metric_name = fairness_metric.split("@")[1].upper()
  
      if "ratio" in fairness_metric.lower():
          fairness_metric_name = f"Group Loss Ratio @ {metric_name}"
      else:
          fairness_metric_name = (
              f"Group Loss Difference @ {metric_name}"
          )
  
      fairness_metrics = {}
  
      regression_metrics = {
          "SAMPLES": lambda t, p, sw=None: t.shape[0],
          "MAE": mean_absolute_error,
          "MSE": mean_squared_error,
          "RMSE": lambda t, p, sample_weight=None: np.sqrt(
              mean_squared_error(t, p, sample_weight=sample_weight)
          ),
          "R2": r2_score,
          "MAPE": mean_absolute_percentage_error,
          "SPEARMAN": spearman,
          "PEARSON": pearson,
      }
      overall = {}
      for k, v in regression_metrics.items():
          overall[k] = v(target, predictions)
  
      for col in sensitive_features.columns:
          col_name = col[10:]  # skip 'senstive_'
  
          values = sensitive_features[col].unique()
          all_metrics = [overall]
  
          for value in values:
              metrics = {}
              for k, v in regression_metrics.items():
                  metrics[k] = v(
                      target[sensitive_features[col] == value],
                      predictions[sensitive_features[col] == value],
                  )
              all_metrics += [metrics]
  
          mdf = pd.DataFrame(
              all_metrics, index=["Overall"] + list(values)
          )
  
          privileged_value, underprivileged_value = None, None
          for pg in privileged_groups:
              if col_name in pg:
                  privileged_value = pg.get(col_name)
          for upg in underprivileged_groups:
              if col_name in upg:
                  underprivileged_value = upg.get(col_name)
  
          if privileged_value is None:
              if metric_name in ["R2", "SPEARMAN", "PEARSON"]:
                  # the higher the better
                  privileged_value = mdf.index[
                      mdf[metric_name][1:].argmax() + 1
                  ]  # without overall metrics
              else:
                  # the lower the better
                  privileged_value = mdf.index[
                      mdf[metric_name][1:].argmin() + 1
                  ]  # without overall metrics
  
          if underprivileged_value is None:
              if metric_name in ["R2", "SPEARMAN", "PEARSON"]:
                  # the higher the better
                  underprivileged_value = mdf.index[
                      mdf[metric_name][1:].argmin() + 1
                  ]  # without overall metrics
              else:
                  # the lower the better
                  underprivileged_value = mdf.index[
                      mdf[metric_name][1:].argmax() + 1
                  ]  # without overall metrics
  
          metric_min = mdf[metric_name].loc[privileged_value]
          metric_max = mdf[metric_name].loc[underprivileged_value]
  
          ratio = np.round(metric_min / metric_max, 4)
          diff = np.round(metric_max - metric_min, 4)
  
          # ratio = np.round(mdf[metric_name][1:].min()/mdf[metric_name][1:].max(), 4)
          # diff = np.round(mdf[metric_name][1:].max()-mdf[metric_name][1:].min(), 4)
  
          is_fair = False
          if "ratio" in fairness_metric.lower():
              fairness_metric_value = ratio
              if ratio > fairness_threshold:
                  is_fair = True
          else:
              fairness_metric_value = diff
              if diff < fairness_threshold:
                  is_fair = True
  
          fairness_metrics[col_name] = {
              "metrics": mdf,
              "figures": FairnessPlots.regression(
                  fairness_metric, col_name, mdf, fairness_metric_name
              ),
              "privileged_value": privileged_value,
              "underprivileged_value": underprivileged_value,
              "ratio": ratio,
              "diff": diff,
              "metric_name": metric_name,
              "fairness_metric_name": fairness_metric_name,
              "fairness_metric_value": fairness_metric_value,
              "is_fair": is_fair,
              "fairness_threshold": fairness_threshold,
          }
  
      fairness_metrics[
          "fairness_optimization"
      ] = FairnessOptimization.regression(
          target,
          predictions,
          sensitive_features,
          fairness_metric,
          fairness_threshold,
          privileged_groups,
          underprivileged_groups,
          previous_fairness_optimization,
          performance_metric=regression_metrics[metric_name],
          performance_metric_name=metric_name,
      )
  
      return fairness_metrics
  
file_path: mljar-supervised/supervised/fairness/metrics.py
imports: import os
  import numpy
  import pandas
  from matplotlib import pyplot
  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.fairness.optimization import FairnessOptimization
  from supervised.fairness.plots import FairnessPlots
  from supervised.fairness.utils import accuracy, false_negative_rate, false_positive_rate, selection_rate, true_negative_rate, true_positive_rate
  from supervised.utils.metric import pearson, spearman
label_desc: Use image node_id 2 for calling the FairnessMetrics obj's underlying member method code with example usage: obj.regression(target, predictions, sensitive_features, fairness_metric, fairness_threshold, privileged_groups, underprivileged_groups, previous_fairness_optimization) and returns: fairness_metrics