class Fair_PR(): def __init__(self, sensitive, class_attr, eta): self.model = PrejudiceRemover(sensitive_attr=sensitive, class_attr=class_attr, eta=eta) def fit(self, data, labels, prot): ds = BinaryLabelDataset(df=data, label_names=labels, protected_attribute_names=prot) self.model.fit(ds) def predict_proba(self, data_test): y = self.model.predict(data_test) return y.scores
def prejudice_remover(dataset_orig_train, dataset_orig_valid, dataset_orig_test, privileged_groups, unprivileged_groups, sens_attr): #print(dataset_orig_train.features.shape) #print(dataset_orig_train.labels.shape ) dataset_original_train = copy.deepcopy(dataset_orig_train) dataset_original_valid = copy.deepcopy(dataset_orig_valid) dataset_original_test = copy.deepcopy(dataset_orig_test) # Learning a Prejudice Remover (PR) model on original data model = PrejudiceRemover(sensitive_attr=sens_attr, eta=25.0) pr_orig_scaler = StandardScaler() dataset_original_train.features = pr_orig_scaler.fit_transform( dataset_original_train.features) dataset_original_valid.features = pr_orig_scaler.fit_transform( dataset_original_valid.features) dataset_original_test.features = pr_orig_scaler.fit_transform( dataset_original_test.features) pr_orig = model.fit(dataset_original_train) # validating PR model thresh_arr = np.linspace(0.01, 0.50, 50) valid_pred, valid_metrics = test(dataset_original_valid, pr_orig, thresh_arr, privileged_groups, unprivileged_groups) pr_orig_best_ind = np.argmax(valid_metrics['bal_acc']) train_pred, metric_train = test(dataset_original_train, pr_orig, [thresh_arr[pr_orig_best_ind]], privileged_groups, unprivileged_groups) val_pred, metric_val = test(dataset_original_valid, pr_orig, [thresh_arr[pr_orig_best_ind]], privileged_groups, unprivileged_groups) test_pred, metric_test = test(dataset_original_test, pr_orig, [thresh_arr[pr_orig_best_ind]], privileged_groups, unprivileged_groups) dataset_transf_valid_pred = copy.deepcopy(dataset_orig_valid) dataset_transf_valid_pred.labels = val_pred.labels print(val_pred.labels.shape) #dataset_transf_valid_pred.scores = val_pred.scores dataset_transf_test_pred = copy.deepcopy(dataset_orig_test) dataset_transf_test_pred.labels = test_pred.labels #dataset_transf_test_pred.scores = test_pred.scores return dataset_transf_valid_pred, dataset_transf_test_pred
def prejudice(train, test, unprivileged_groups, privileged_groups): prejudice_model = PrejudiceRemover(eta=100, sensitive_attr='sex') prejudice_model.fit(train) # predict outcome using the test set pred_prejudice = prejudice_model.predict(test) # calculate accuracy accuracy = accuracy_score(y_true=test.labels, y_pred=pred_prejudice.labels) # calculate fairness metrics metric_test = BinaryLabelDatasetMetric( pred_prejudice, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric(test, pred_prejudice, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) equal_opportunity_difference = equal_opp_diff(test, pred_prejudice, 'sex', privileged=1, unprivileged=0, favourable=1, unfavourable=0) average_odds_difference = avg_odds_diff(test, pred_prejudice, 'sex', privileged=1, unprivileged=0, favourable=1, unfavourable=0) if acc_test.disparate_impact() == math.inf: disparate_impact = 5.0 else: disparate_impact = acc_test.disparate_impact() metrics = [ metric_test.mean_difference(), disparate_impact, equal_opportunity_difference, average_odds_difference, acc_test.theil_index() ] return pred_prejudice, accuracy, metrics
def prejudice_remover(structured_data_train, structured_data_test, priv_category, eta=25): """ Remove bias from dataset using Prejudice Remover Regularizer. Parameters: structured_data (aif360.datasets.standard_dataset.StandardDataset): Structured dataset. priv_category (string): Column with privileged class. eta (int): Regularization parameter Returns: data_transf_train_df (pandas dataframe): Pandas dataframe. data_transf_test_df (pandas dataframe): Pandas dataframe. """ debiased_model = PrejudiceRemover(sensitive_attr=priv_category, eta=eta) 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
def __init__(self, df, target_col, sensitive_att, fairness_penalty=1.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 fairness_penalty: float in [0,1], fairness penalty parameter. default is 1. The same parameter in aif360.algorithms.inprocessing.PrejudiceRemover. """ # TODO: fix the bug that cannot import lib of 'getoutput' cur_step = PrejudiceRemover(eta=fairness_penalty, sensitive_attr=sensitive_att, class_attr=target_col) super().__init__("@".join(["AIF_PrejudiceRemover", sensitive_att]), cur_step, df, target_col, sensitive_att=sensitive_att, fair_aware=True)
def run_trial(): # stores each run (4 algos without reweighing, 4 algos with reweighing) as a sublist # number of sublists = number of runs # each sublist has four elements # we ONLY predict on the testing data ########## WITHOUT REWEIGHING ############# stat_par = [] disp_imp = [] eq_opp_diff = [] avg_odds_diff = [] theil = [] acc = [] ########## WITH REWEIGHING ############# stat_par_reweigh = [] disp_imp_reweigh = [] eq_opp_diff_reweigh = [] avg_odds_diff_reweigh = [] theil_reweigh = [] acc_reweigh = [] ########################################### for i in range(10): ########################################### privileged_groups = [{'sex': 1}] unprivileged_groups = [{'sex': 0}] dataset_orig = load_preproc_data_adult() # train1, test1 are the original dataset train1, test1 = dataset_orig.split([0.7], shuffle=True) RW = Reweighing(unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) RW.fit(train1) # dataset_transf_train, test1 are for the reweighed dataset dataset_transf_train = RW.transform(train1) ########################################### # change weights to whole numbers for i in range(dataset_transf_train.instance_weights.size): dataset_transf_train.instance_weights[i] = (round( dataset_transf_train.instance_weights[i] / 0.1) * 0.1) * 10 weights = copy.deepcopy(dataset_transf_train.instance_weights) # change dataset_transf_train.features and dataset_transf_train.labels and dataset_transf_train.protected_attributes according to the weights of each instance sum_weights = 0 for i in range(dataset_transf_train.features.shape[0]): row = copy.deepcopy(dataset_transf_train.features[i]) row_label = copy.deepcopy(dataset_transf_train.labels[i]) row_protected_attributes = copy.deepcopy( dataset_transf_train.protected_attributes[i]) row_protected_attributes.resize(1, 2) row.resize(1, 18) row_label.resize(1, 1) weight = int(weights[i]) for j in range(weight - 1): dataset_transf_train.features = np.concatenate( (dataset_transf_train.features, row)) dataset_transf_train.labels = np.concatenate( (dataset_transf_train.labels, row_label)) dataset_transf_train.protected_attributes = np.concatenate( (dataset_transf_train.protected_attributes, row_protected_attributes)) # change the dataset_transf_train to a numpy array of ones to match number of rows in features dataset_transf_train.instance_weights = np.ones( dataset_transf_train.features.shape[0]) ################## without reweighing ########################## temp_stat_par = [] temp_disp_imp = [] temp_eq_opp_diff = [] temp_avg_odds_diff = [] temp_theil = [] temp_acc = [] ##################### adversarial debiasing ##################### sess = tf.Session() debiased_model = AdversarialDebiasing( privileged_groups=privileged_groups, unprivileged_groups=unprivileged_groups, scope_name='debiased_classifier', debias=True, sess=sess) debiased_model.fit(train1) dataset_debiasing_test = debiased_model.predict(test1) sess.close() tf.reset_default_graph() ##################### metrics ##################### metric_test = BinaryLabelDatasetMetric( dataset_debiasing_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric( test1, dataset_debiasing_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) temp_stat_par.append(metric_test.mean_difference()) temp_disp_imp.append(metric_test.disparate_impact()) temp_eq_opp_diff.append(metric_test.equal_opportunity_difference()) temp_avg_odds_diff.append(metric_test.average_odds_difference()) temp_theil.append(metric_test.theil_index()) temp_acc.append(acc_test.accuracy()) ##################### prejudice remover ##################### prejudice_model = PrejudiceRemover(eta=100, sensitive_attr='sex') prejudice_model.fit(train1) dataset_prejudice_test = prejudice_model.predict(test1) ##################### metrics ##################### metric_test = BinaryLabelDatasetMetric( dataset_prejudice_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric( test1, dataset_prejudice_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) temp_stat_par.append(metric_test.mean_difference()) temp_disp_imp.append(metric_test.disparate_impact()) temp_eq_opp_diff.append(metric_test.equal_opportunity_difference()) temp_avg_odds_diff.append(metric_test.average_odds_difference()) temp_theil.append(metric_test.theil_index()) temp_acc.append(acc_test.accuracy()) ##################### normal neural net ##################### sess = tf.Session() neural_model = AdversarialDebiasing( privileged_groups=privileged_groups, unprivileged_groups=unprivileged_groups, scope_name='debiased_classifier', debias=False, sess=sess) neural_model.fit(train1) dataset_neural_test = neural_model.predict(test1) sess.close() tf.reset_default_graph() ##################### metrics ##################### metric_test = BinaryLabelDatasetMetric( dataset_neural_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric( test1, dataset_neural_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) temp_stat_par.append(metric_test.mean_difference()) temp_disp_imp.append(metric_test.disparate_impact()) temp_eq_opp_diff.append(metric_test.equal_opportunity_difference()) temp_avg_odds_diff.append(metric_test.average_odds_difference()) temp_theil.append(metric_test.theil_index()) temp_acc.append(acc_test.accuracy()) ##################### ensemble ##################### pred_labels_test = [] for i in range(0, len(test1.features)): arr_test = mode([ dataset_debiasing_test[i], dataset_prejudice_test[i], dataset_neural_test[i] ]) pred_labels_test.append(arr_test[0][0]) dataset_ensemble_test = test1.copy() dataset_ensemble_test.labels = np.array(pred_labels_test) ##################### metrics ##################### metric_test = BinaryLabelDatasetMetric( dataset_ensemble_train, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric( test1, dataset_ensemble_train, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) temp_stat_par.append(metric_test.mean_difference()) temp_disp_imp.append(metric_test.disparate_impact()) temp_eq_opp_diff.append(metric_test.equal_opportunity_difference()) temp_avg_odds_diff.append(metric_test.average_odds_difference()) temp_theil.append(metric_test.theil_index()) temp_acc.append(acc_test.accuracy()) ######### DUMP SHIT ########### stat_par.append(temp_stat_par) disp_imp.append(temp_disp_imp) eq_opp_diff.append(temp_eq_opp_diff) avg_odds_diff.append(temp_avg_odds_diff) theil.append(temp_theil) acc.append(temp_acc) ################## with reweighing ########################## temp_stat_par = [] temp_disp_imp = [] temp_eq_opp_diff = [] temp_avg_odds_diff = [] temp_theil = [] temp_acc = [] ################## adversarial debiasing ################## sess = tf.Session() debiased_model_reweighing = AdversarialDebiasing( privileged_groups=privileged_groups, unprivileged_groups=unprivileged_groups, scope_name='debiased_classifier', debias=True, sess=sess) debiased_model_reweighing.fit(dataset_transf_train) dataset_debiasing_test_reweighing = debiased_model_reweighing.predict( test1) sess.close() tf.reset_default_graph() ##################### metrics ##################### metric_test = BinaryLabelDatasetMetric( dataset_debiasing_test_reweighing, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric( test1, dataset_debiasing_test_reweighing, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) temp_stat_par.append(metric_test.mean_difference()) temp_disp_imp.append(metric_test.disparate_impact()) temp_eq_opp_diff.append(metric_test.equal_opportunity_difference()) temp_avg_odds_diff.append(metric_test.average_odds_difference()) temp_theil.append(metric_test.theil_index()) temp_acc.append(acc_test.accuracy()) ##################### prejudice remover ##################### prejudice_model_reweighing = PrejudiceRemover(eta=100, sensitive_attr='sex') prejudice_model_reweighing.fit(dataset_transf_train) dataset_prejudice_test_reweighing = prejudice_model_reweighing.predict( test1) ##################### metrics ##################### metric_test = BinaryLabelDatasetMetric( dataset_prejudice_test_reweighing, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric( test1, dataset_prejudice_test_reweighing, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) temp_stat_par.append(metric_test.mean_difference()) temp_disp_imp.append(metric_test.disparate_impact()) temp_eq_opp_diff.append(metric_test.equal_opportunity_difference()) temp_avg_odds_diff.append(metric_test.average_odds_difference()) temp_theil.append(metric_test.theil_index()) temp_acc.append(acc_test.accuracy()) ##################### normal neural net ##################### sess = tf.Session() neural_model = AdversarialDebiasing( privileged_groups=privileged_groups, unprivileged_groups=unprivileged_groups, scope_name='debiased_classifier', debias=False, sess=sess) neural_model.fit(dataset_transf_train) dataset_neural_test = neural_model.predict(test1) sess.close() tf.reset_default_graph() ##################### metrics ##################### metric_test = BinaryLabelDatasetMetric( dataset_neural_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric( test1, dataset_neural_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) temp_stat_par.append(metric_test.mean_difference()) temp_disp_imp.append(metric_test.disparate_impact()) temp_eq_opp_diff.append(metric_test.equal_opportunity_difference()) temp_avg_odds_diff.append(metric_test.average_odds_difference()) temp_theil.append(metric_test.theil_index()) temp_acc.append(acc_test.accuracy()) ##################### ensemble ##################### pred_labels_test = [] for i in range(0, len(test1.features)): arr_test = mode([ dataset_debiasing_test[i], dataset_prejudice_test[i], dataset_neural_test[i] ]) pred_labels_test.append(arr_test[0][0]) dataset_ensemble_test = test1.copy() dataset_ensemble_test.labels = np.array(pred_labels_test) ##################### metrics ##################### metric_test = BinaryLabelDatasetMetric( dataset_ensemble_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) acc_test = ClassificationMetric( test1, dataset_ensemble_test, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) temp_stat_par.append(metric_test.mean_difference()) temp_disp_imp.append(metric_test.disparate_impact()) temp_eq_opp_diff.append(metric_test.equal_opportunity_difference()) temp_avg_odds_diff.append(metric_test.average_odds_difference()) temp_theil.append(metric_test.theil_index()) temp_acc.append(acc_test.accuracy()) ######### DUMP SHIT ########### stat_par_reweigh.append(temp_stat_par) disp_imp_reweigh.append(temp_disp_imp) eq_opp_diff_reweigh.append(temp_eq_opp_diff) avg_odds_diff_reweigh.append(temp_avg_odds_diff) theil_reweigh.append(temp_theil) acc_reweigh.append(temp_acc) without_reweighing = [ stat_par, disp_imp, eq_opp_diff, avg_odds_diff, theil, acc ] with_reweighing = [ stat_par_reweigh, disp_imp_reweigh, eq_opp_diff_reweigh, avg_odds_diff_reweigh, theil_reweigh, acc_reweigh ] for metric in range(len(without_reweighing)): name = "metric" + str(metric) sublist = without_reweighing[metric] with open(name, "wb") as csv_file: writer = csv.writer(csv_file) writer.writerows(sublist) for metric in range(len(with_reweighing)): name = "metric" + str(metric) + "reweigh" sublist = with_reweighing[metric] with open(name, "wb") as csv_file: writer = csv.writer(csv_file) writer.writerows(sublist)
dataset_orig_test.features) dataset_orig_valid.features = min_max_scaler.transform( dataset_orig_valid.features) #### PREJUDICE REMOVER ######################################################## pr_predictions_valid = pd.DataFrame() pr_predictions_test = pd.DataFrame() all_eta = [1, 5, 15, 30, 50, 70, 100, 150] for eta in all_eta: print("Eta: %.2f" % eta) colname = "eta_" + str(eta) debiased_model = PrejudiceRemover(eta=eta, sensitive_attr=protected, class_attr="TARGET") debiased_model.fit(dataset_orig_train) dataset_debiasing_valid = debiased_model.predict(dataset_orig_valid) dataset_debiasing_test = debiased_model.predict(dataset_orig_test) scores = dataset_debiasing_valid.scores pr_predictions_valid[colname] = sum(scores.tolist(), []) scores = dataset_debiasing_test.scores pr_predictions_test[colname] = sum(scores.tolist(), []) pr_predictions_valid.to_csv(output_path + 'taiwan_in_PRpredictions_valid' + '.csv', index=None,
def __init__(self, sensitive, class_attr, eta): self.model = PrejudiceRemover(sensitive_attr=sensitive, class_attr=class_attr, eta=eta)