def explain(self, request: Dict) -> Dict: inputs = request["instances"] predictions = np.array(request["outputs"]) dataframe_predicted = pd.DataFrame(inputs, columns=self.feature_names) dataframe_predicted[self.label_names[0]] = predictions dataset_predicted = BinaryLabelDataset( favorable_label=self.favorable_label, unfavorable_label=self.unfavorable_label, df=dataframe_predicted, label_names=self.label_names, protected_attribute_names=['age']) metrics = BinaryLabelDatasetMetric( dataset_predicted, unprivileged_groups=self.unprivileged_groups, privileged_groups=self.privileged_groups) return { "predictions": predictions.tolist(), "metrics": { "base_rate": metrics.base_rate(), "consistency": metrics.consistency().tolist(), "disparate_impact": metrics.disparate_impact(), "num_instances": metrics.num_instances(), "num_negatives": metrics.num_negatives(), "num_positives": metrics.num_positives(), "statistical_parity_difference": metrics.statistical_parity_difference(), } }
def checkClassifierFairnessAndReweighData(frame, dpoints, mname, x_columns, verbose=True, pre=True): ''' Measure fairness according to the metric using the value of A and the classification outcome. Results get added to a dictionary used to pass them to a function to generate graphs of the results. If we have not performed intervention, perform intervention and return post intervention data.''' xay_columns = copy.deepcopy(x_columns) xay_columns.extend(["A", "Y"]) ycols = copy.deepcopy(frame["Y"]) tempframe = copy.deepcopy(frame) tempframe.drop(["Y"], axis=1, inplace=True) aifdf = BinaryLabelDataset(favorable_label=1.0, unfavorable_label=0.0, df=tempframe, label_names=['Ya'], protected_attribute_names=['A']) privileged_groups = [{'A': 1}] unprivileged_groups = [{'A': 0}] RW = Reweighing(unprivileged_groups=[{ 'A': 0 }], privileged_groups=[{ 'A': 1 }]) metric_aifdf_train = BinaryLabelDatasetMetric( aifdf, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) if pre: if verbose: print("\n\tINTERVENTION: {}\n".format(type(RW).__name__)) print("\t######### PRE {} ###########".format(type(RW).__name__)) print( "\tDifference in mean outcomes between unprivileged and privileged groups = {}\n" .format(metric_aifdf_train.mean_difference())) dpoints[mname]['PRE'][type( RW).__name__]['FAIR'] = metric_aifdf_train.mean_difference() print("PRE CLASSIFICATION MATRIX") print("----------------") print(" |Y'=0 | Y'=1 |") print("----------------") print("A=0| {0} | {1} |".format( metric_aifdf_train.num_negatives(False), metric_aifdf_train.num_positives(False))) print("A=1| {0} | {1} |".format( metric_aifdf_train.num_negatives(True), metric_aifdf_train.num_positives(True))) print("----------------") dataset_transf_train = RW.fit_transform(aifdf) fairdf = dataset_transf_train.convert_to_dataframe()[0] fairdf.drop(['Ya'], axis=1, inplace=True) ycols.reset_index(drop=True, inplace=True) fairdf.reset_index(drop=True, inplace=True) fairdf.insert(0, "Y", ycols) fairdf[xay_columns] = fairdf[xay_columns].astype(int) fairdf.insert(loc=len(fairdf.columns), column="weights", value=dataset_transf_train.instance_weights) return fairdf else: if verbose: print( "\tDifference in mean outcomes between unprivileged and privileged groups = {}\n" .format(metric_aifdf_train.mean_difference())) dpoints[mname]['POST'][type( RW).__name__]['FAIR'] = metric_aifdf_train.mean_difference() print("POST CLASSIFICATION MATRIX") print("----------------") print(" |Y'=0 | Y'=1 |") print("----------------") print("A=0| {0} | {1} |".format( metric_aifdf_train.num_negatives(False), metric_aifdf_train.num_positives(False))) print("A=1| {0} | {1} |".format( metric_aifdf_train.num_negatives(True), metric_aifdf_train.num_positives(True))) print("----------------") return frame