Example #1
0
def test_adv_debias_old_reproduce():
    """Test that the old AdversarialDebiasing is reproducible."""
    sess = tf.Session()
    old_adv_deb = OldAdversarialDebiasing(unprivileged_groups=[{
        'sex': 0
    }],
                                          privileged_groups=[{
                                              'sex': 1
                                          }],
                                          scope_name='old_classifier',
                                          sess=sess,
                                          num_epochs=5,
                                          seed=123)
    old_preds = old_adv_deb.fit_predict(adult)
    sess.close()
    tf.reset_default_graph()
    sess = tf.Session()
    old_adv_deb2 = OldAdversarialDebiasing(unprivileged_groups=[{
        'sex': 0
    }],
                                           privileged_groups=[{
                                               'sex': 1
                                           }],
                                           scope_name='old_classifier',
                                           sess=sess,
                                           num_epochs=5,
                                           seed=123)
    old_preds2 = old_adv_deb2.fit_predict(adult)
    sess.close()

    assert np.allclose(old_preds.labels, old_preds2.labels)
Example #2
0
def _preprocess_data(
    data, protected_attribute_name, protected_attribute_index, label_name, required_fairness
):
    from pandas import DataFrame
    from aif360.datasets import BinaryLabelDataset

    dataset = BinaryLabelDataset(
        df=DataFrame(data),
        protected_attribute_names={protected_attribute_name},
        label_names={label_name},
        favorable_label=2,
        unfavorable_label=1,
    )
    train, test = dataset.split([0.8])

    from aif360.algorithms.inprocessing import AdversarialDebiasing

    sess = tf.compat.v1.Session()
    debiaser = AdversarialDebiasing(
        unprivileged_groups=({protected_attribute_name: 0},),
        privileged_groups=({protected_attribute_name: 1},),
        scope_name="debiaser",
        debias=True,
        sess=sess,
    )
    debiaser.fit(train)

    from sklearn.ensemble import RandomForestClassifier

    model = RandomForestClassifier(class_weight="balanced")

    X_tr = np.delete(train.features, protected_attribute_index, axis=1)
    y_tr = train.labels.ravel()
    model.fit(X_tr, y_tr)

    test_pred = test.copy(deepcopy=True)
    test_pred.scores = model.predict(np.delete(debiaser.predict(test).features, protected_attribute_index, axis=1))

    accuracy = np.sum(np.equal(test.scores, test_pred.scores))

    from aif360.metrics import ClassificationMetric
    disparate_impact = ClassificationMetric(
        test,
        test_pred,
        unprivileged_groups=({protected_attribute_name: 0},),
        privileged_groups=({protected_attribute_name: 1},),
    ).disparate_impact()

    print(f"Accuracy: {accuracy}")
    print(f"Disparate impact: {disparate_impact}")
    if disparate_impact > float(required_fairness):
        raise ValueError(
            f"Too unfair! Disparate impact was {disparate_impact} but must be less than {required_fairness}"
        )
Example #3
0
def nondebiased_classifier(train, test, privileged_groups,
                           unprivileged_groups):
    sess = tf.Session()
    NN_model = AdversarialDebiasing(privileged_groups,
                                    unprivileged_groups,
                                    scope_name='nondebiased_classifier',
                                    debias=False,
                                    sess=sess)
    NN_model.fit(train)

    # predict outcome using the test set
    pred_NNmodel = NN_model.predict(test)
    sess.close()
    tf.reset_default_graph()

    # calculate accuracy
    accuracy = accuracy_score(y_true=test.labels, y_pred=pred_NNmodel.labels)

    # calculate fairness metrics
    metric_test = BinaryLabelDatasetMetric(
        pred_NNmodel,
        unprivileged_groups=unprivileged_groups,
        privileged_groups=privileged_groups)
    acc_test = ClassificationMetric(test,
                                    pred_NNmodel,
                                    unprivileged_groups=unprivileged_groups,
                                    privileged_groups=privileged_groups)
    equal_opportunity_difference = equal_opp_diff(test,
                                                  pred_NNmodel,
                                                  'sex',
                                                  privileged=1,
                                                  unprivileged=0,
                                                  favourable=1,
                                                  unfavourable=0)
    average_odds_difference = avg_odds_diff(test,
                                            pred_NNmodel,
                                            'sex',
                                            privileged=1,
                                            unprivileged=0,
                                            favourable=1,
                                            unfavourable=0)

    metrics = [
        metric_test.mean_difference(),
        acc_test.disparate_impact(), equal_opportunity_difference,
        average_odds_difference,
        acc_test.theil_index()
    ]

    return pred_NNmodel, accuracy, metrics
Example #4
0
    def __init__(self, df, target_col, sensitive_att, seed=0):
        """
        :param df: pandas dataframe, stores the data to fit the fair classifier.
        :param target_col: str, the name of the target variable in above data.
        :param sensitive_att: str, the name of a sensitive attribute in above data. If none, call auto_detection to update. Value 0 represent protected.
        :param seed: integer, random seed.

        """

        import tensorflow as tf
        sess = tf.Session()
        cur_step = AdversarialDebiasing(unprivileged_groups=[{
            sensitive_att: 0
        }],
                                        privileged_groups=[{
                                            sensitive_att: 1
                                        }],
                                        scope_name='debiased_classifier',
                                        debias=True,
                                        sess=sess,
                                        seed=seed)
        super().__init__("@".join(["AIF_AdversarialDebiasing", sensitive_att]),
                         cur_step,
                         df,
                         target_col,
                         sensitive_att=sensitive_att,
                         fair_aware=True)
Example #5
0
def test_adv_debias_old():
    """Test that the predictions of the old and new AdversarialDebiasing match.
    """
    tf.reset_default_graph()
    sess = tf.Session()
    old_adv_deb = OldAdversarialDebiasing(unprivileged_groups=[{
        'sex': 0
    }],
                                          privileged_groups=[{
                                              'sex': 1
                                          }],
                                          scope_name='old_classifier',
                                          sess=sess,
                                          num_epochs=5,
                                          seed=123)
    old_preds = old_adv_deb.fit_predict(adult)
    sess.close()
    adv_deb = AdversarialDebiasing('sex', num_epochs=5, random_state=123)
    new_preds = adv_deb.fit(X, y).predict(X)
    adv_deb.sess_.close()
    assert np.allclose(old_preds.labels.flatten(), new_preds)
Example #6
0
def adversarial_debias(structured_data_train,
                       structured_data_test,
                       priv_category,
                       scope_name='debiased_classifier',
                       num_epochs=10):
    """
    Remove bias from dataset using Adversarial debiasing. Must use Tensorflow version 1.14.
    
    Parameters:
    structured_data (aif360.datasets.standard_dataset.StandardDataset): Structured dataset.
    priv_category (string): Column with privileged class.
    scope_name (string): Name of scope to debias. See documentation on adversarial debiasing for details.
    num_epochs (int): Epochs to train with.
    Returns:
    data_transf_train_df (pandas dataframe): Pandas dataframe of train set
    data_transf_df (pandas dataframe): Pandas dataframe of test set
    """

    sess = tf.Session()

    # Get privileged and unprivileged groups
    privileged_groups, unprivileged_groups = get_attributes(
        structured_data_train, selected_attr=[priv_category])
    debiased_model = AdversarialDebiasing(
        privileged_groups=privileged_groups,
        unprivileged_groups=unprivileged_groups,
        scope_name=scope_name,
        num_epochs=num_epochs,
        debias=True,
        sess=sess)

    debiased_model.fit(structured_data_train)

    # Remove bias
    data_train_pred = debiased_model.predict(structured_data_train)
    data_pred = debiased_model.predict(structured_data_test)

    # Convert to pandas dataframe
    data_transf_train_df = convert_to_pd_dataframe(data_train_pred)
    data_transf_test_df = convert_to_pd_dataframe(data_pred)

    return data_transf_train_df, data_transf_test_df