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 checkClassifierFairnessAndLFR(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}] FairRep = LFR(unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups, verbose=0, seed=0) metric_aifdf_train = BinaryLabelDatasetMetric( aifdf, unprivileged_groups=unprivileged_groups, privileged_groups=privileged_groups) if pre: if verbose: print("\n\tINTERVENTION: {}\n".format(type(FairRep).__name__)) print("\t######### PRE {} ###########".format( type(FairRep).__name__)) print( "\tmean consistency between unprivileged and privileged groups = {}" .format(metric_aifdf_train.consistency())) print( "\tdisparate impact between unprivileged and privileged groups = {}\n" .format(metric_aifdf_train.disparate_impact())) dpoints[mname]['PRE'][type(FairRep).__name__][ 'FAIRCONSIS'] = metric_aifdf_train.consistency() dpoints[mname]['PRE'][type(FairRep).__name__][ 'FAIRDI'] = metric_aifdf_train.disparate_impact() 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 = FairRep.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] fairdf[xay_columns] = fairdf[xay_columns].astype(int) return fairdf else: if verbose: print( "\tMean consistency between unprivileged and privileged groups = {}\n" .format(metric_aifdf_train.consistency())) print( "\tdisparate impact between unprivileged and privileged groups = {}" .format(metric_aifdf_train.disparate_impact())) dpoints[mname]['POST'][type(FairRep).__name__][ 'FAIRCONSIS'] = metric_aifdf_train.consistency() dpoints[mname]['POST'][type(FairRep).__name__][ 'FAIRDI'] = metric_aifdf_train.disparate_impact() 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