<jupyter_start><jupyter_text>This notebook demonstrates the use of Reweighing pre-processing, Adversarial Debiasing in-processing and Reject Option Classification (ROC) post-processing algorithms for bias mitigation.- Load imports- Dataset    * Load Adult, COMPAS, or German dataset and set privileged and unprivileged groups    * Divide the dataset into training, validation, and testing partitions    * Show dataset properties- Pre-processing: Reweighing.    * Show difference in mean outcomes for original training data    * Assign weights with reweighing    * Show difference in mean outcomes for transformed training data- In-processing: Adversarial Debiasing.    * Train model without debiasing, predict, and show metrics    * Train model with debiasing, predict, and show metrics- Post-processing: Reject Option Classification (ROC).    * Show metrics for test set from Adversarial Debiasing without debiasing    * Fit ROC model    * Transform labels and show metrics<jupyter_code># Load all necessary packages
import sys
sys.path.append("../")
import numpy as np
import tensorflow as tf
from warnings import warn 

# Avoid deprecation warnings
tf.compat.v1.logging.set_verbosity(tf.compat.v1.logging.ERROR)


from aif360.datasets import BinaryLabelDataset
from aif360.datasets import AdultDataset, GermanDataset, CompasDataset
from aif360.metrics import ClassificationMetric, BinaryLabelDatasetMetric
from aif360.metrics.utils import compute_boolean_conditioning_vector
from aif360.algorithms.preprocessing.optim_preproc_helpers.data_preproc_functions\
        import load_preproc_data_adult, load_preproc_data_german, load_preproc_data_compas

from aif360.algorithms.preprocessing.reweighing import Reweighing
from aif360.algorithms.inprocessing.adversarial_debiasing import AdversarialDebiasing
from aif360.algorithms.postprocessing.reject_option_classification\
        import RejectOptionClassification

from common_utils import compute_metrics

from IPython.display import Markdown, display
from ipywidgets import interactive, FloatSlider<jupyter_output><empty_output><jupyter_text>Load dataset and specify options<jupyter_code>## import dataset
dataset_used = "german" # "adult", "german", "compas"
protected_attribute_used = 1 # 1, 2

if dataset_used == "adult":
#     dataset_orig = AdultDataset()
    if protected_attribute_used == 1:
        privileged_groups = [{'sex': 1}]
        unprivileged_groups = [{'sex': 0}]
        dataset_orig = load_preproc_data_adult(['sex'])
    else:
        privileged_groups = [{'race': 1}]
        unprivileged_groups = [{'race': 0}]
        dataset_orig = load_preproc_data_adult(['race'])
    
elif dataset_used == "german":
#     dataset_orig = GermanDataset()
    if protected_attribute_used == 1:
        privileged_groups = [{'sex': 1}]
        unprivileged_groups = [{'sex': 0}]
        dataset_orig = load_preproc_data_german(['sex'])
    else:
        privileged_groups = [{'age': 1}]
        unprivileged_groups = [{'age': 0}]
        dataset_orig = load_preproc_data_german(['age'])
    
elif dataset_used == "compas":
#     dataset_orig = CompasDataset()
    if protected_attribute_used == 1:
        privileged_groups = [{'sex': 0}]
        unprivileged_groups = [{'sex': 1}]
        dataset_orig = load_preproc_data_compas(['sex'])
    else:
        privileged_groups = [{'race': 1}]
        unprivileged_groups = [{'race': 0}]  
        dataset_orig = load_preproc_data_compas(['race'])<jupyter_output><empty_output><jupyter_text>Split into train, test and validation<jupyter_code># Get the dataset and split into train and test
dataset_orig_train, dataset_orig_vt = dataset_orig.split([0.7], shuffle=True)
dataset_orig_valid, dataset_orig_test = dataset_orig_vt.split([0.5], shuffle=True)<jupyter_output><empty_output><jupyter_text>Clean up training data and display properties of the data<jupyter_code># print out some labels, names, etc.
display(Markdown("#### Training Dataset shape"))
print(dataset_orig_train.features.shape)
display(Markdown("#### Favorable and unfavorable labels"))
print(dataset_orig_train.favorable_label, dataset_orig_train.unfavorable_label)
display(Markdown("#### Protected attribute names"))
print(dataset_orig_train.protected_attribute_names)
display(Markdown("#### Privileged and unprivileged protected attribute values"))
print(dataset_orig_train.privileged_protected_attributes, 
      dataset_orig_train.unprivileged_protected_attributes)
display(Markdown("#### Dataset feature names"))
print(dataset_orig_train.feature_names)<jupyter_output><empty_output><jupyter_text>Pre-processing: Reweighing  Metric for original training data<jupyter_code># 1. Crear un objeto de la clase BinaryLabelDatasetMetric cuyo constructor recibe por parámetros el dataset de entrenamiento, 
# el array de tuplas de grupos desprivilegiados y el array de tuplas de grupos privilegiados. 
# 2. Llamar a su método mean_difference() e imprimir el valor devuelto (un float)<jupyter_output><empty_output><jupyter_text>Reweighing<jupyter_code># 1. Crear un objeto de la clase Reweighing(grupos desprivilegiados, gurpos privilegiados)
# 2. Llamar a su método fit(dataset) con el dataset de entrenamiento
# 3. Llamar a su método transform(dataset) con el dataset de entrenamiento que devuelve el dataset transformado<jupyter_output><empty_output><jupyter_text>Metric for reweighted training data<jupyter_code># 1. Imprimir la media de diferencias del dataset transformado<jupyter_output><empty_output><jupyter_text>In-processing: Adversarial Debiasing  Without debiasing  Train without debiasing<jupyter_code># Learn parameters with debias set to False
# 1. Iniciar una sesión de tensorflow con tf.Session() 
# 2. Crear un objeto de la clase AdversarialDebiasing(grupo privilegiado, grupo desprivilegiado, 'plain_classifier', 
# booleano de si queremos que haya un adversario (en este caso False), la sesión de tensorflow)
# 1. Llamar a su método fit(dataset) con el dataset de entrenamiento<jupyter_output><empty_output><jupyter_text>Show metrics<jupyter_code># Apply the plain model to test data
# 1. Llamar a su método predict(dataset) que devuelve un dataset con las labels predichas para el dataset de entrenamiento, 
# validación y testeo. Guardar cada uno en 3 datasets distintos (entre sí y respecto a los dataset de entrada)!
# Metrics for the dataset from plain model (without debiasing)
# 1. Imprimir la media de diferencias del dataset de entrenamiento y el dataset de test
# Accuracy
# 1. Crear un objeto de la clase ClassificationMetric(dataset no predicho, dataset predicho, grupos desprivilegiados, 
# grupos privilegiados) con el dataset de test
# 2. Llamar a su método accuracy() e imprimir el valor devuelto (un float)


# Other metrics
# 1. Llamar a la función compute_metrics(dataset no predicho, dataset predicho, grupos desprivilegiados, grupos privilegiados)
# Compute scores for ROC
# 1. Llamar al método del objeto de la clase AdversarialDebiasing predict_proba(dataset no predicho) 
# con el dataset de validación y el de test
# 2. Transformar el valor devuelto en una columna con reshape y guardar los valores en el atributo scores de los 
# datasets predichos de validación y de test respectivamente<jupyter_output><empty_output><jupyter_text>With debiasing  Train with debiasing<jupyter_code># 1. Cerrar la sesión de tf con su método close()
# 2. Llamar a la función de tf reset_default_graph()
# 3. Abrir una nueva sesión de tensorflow
# Learn parameters with debias set to True
# 1. Volver a crear un objeto de la clase AdversarialDebiasing con debias=True
# 1. Entrenar el modelo sobre el dataset de entrenamiento<jupyter_output><empty_output><jupyter_text>Show metrics<jupyter_code># Apply the plain model to test data
# 1. Predecir el dataset de entrenamiento y de test
# Metrics for the dataset from plain model (without debiasing)
# 1. Mostrar la media de las diferencias del dataset de entrenamiento y de test
# Accuracy
# 1. Mostrar la precisión del dataset test


# Other metrics
# 1. Mostrar el resto de métricas del dataset test<jupyter_output><empty_output><jupyter_text>Post-processing: Reject Option Classification  Show metrics for Test Set<jupyter_code># Metrics for the test set
# Accuracy 
# 1. Mostrar la precisión del dataset test sin debias

# Other metrics
# 1. Mostrar el resto de métricas del dataset test sin debias<jupyter_output><empty_output><jupyter_text>Estimate optimal parameters for the ROC method<jupyter_code># Metric used (should be one of allowed_metrics)
metric_name = "Statistical parity difference"

# Upper and lower bound on the fairness metric used
metric_ub = 0.05
metric_lb = -0.05
        
#random seed for calibrated equal odds prediction
np.random.seed(1)

# Verify metric name
allowed_metrics = ["Statistical parity difference",
                   "Average odds difference",
                   "Equal opportunity difference"]
if metric_name not in allowed_metrics:
    raise ValueError("Metric name should be one of allowed metrics")
# 1. Crear un objeto de la clase RejectOptionClassification(grupos desprivilegiados, gurpos privilegiados, 
# límite inferior de prueba, limite superior de prueba, número de thresholds, número de márgenes, métrica a optimizar, 
# límite superior de la métrica, límite inferior de la métrica)
# 2. Llamar a su método fit(dataset no predicho, dataset predicho) con el dataset de validación. Devuelve el ROC entrenado
# 1. Imprimir el classification_threshold y el ROC_margin del ROC entrenado<jupyter_output><empty_output><jupyter_text>Show predictions from Test Set with ROC<jupyter_code># Metrics for the transformed test set
# 1. Predecir con predict(dataset predicho) las nuevas predicciones

# Accuracy 
# 1. Mostrar la precisión del dataset transformado test sin debias

# Other metrics
# 1. Mostrar el resto de métricas del dataset transformado test sin debias<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.07102387697288547, 'fraction_numerical': 0.009004451639012546, 'mean_word_length': 5.352827763496144, 'pattern_counts': {'":': 3, '<': 57, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '14', 'dir': 'jupyter-structured-clean-dedup', 'id': '247586', 'license': 'Apache-2.0', 'n_tokens_mistral': 3085, 'n_tokens_neox': 2948, 'n_words': 1013, 'path': 'examples/incom_pre_in_postproc.ipynb', 'repo_name': 'guillemarsan/AIF360', 'size': '9884'}