New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ENH relaxed fairness constraint fulfillment via postprocessing (currently only supports strict fulfillment) #1246
Comments
Thank you for elaborating so well on the options! I'll have a bunch of observations in random order. I'm just numbering them so that it's easier to respond.
11.Assertions in the code should probably become if-blocks with raising exceptions since they wouldn't be super useful for users if they encounter them.
while RelaxedEqualOdds has
Predictor/estimator are basically the same here, except that we allow passing in an untrained estimator that ThresholdOptimizer will then train. The prefit arg indicates whether it is prefit, although we do checks for that as well. I suppose it makes sense to do the same for the relaxed version. Your constraint is currently always "equalized_odds", so it makes sense that it's not mentioned at this point. We would probably want to keep the same constraints arg in the API, though.
We can certainly start by just supporting accuracy_score for now and make other objectives a future item. I believe max_roc_ticks and grid_size are equivalent. We don't expose the seed on the TO constructor, but rather on the predict method since that's where the randomness comes in. Ours is called random_state for consistency with sklearn I believe.
Our predict_method arg indicates which method to call on the (trained) estimator to get scores. This solves the messy mapping one has to do otherwise. I believe you're familiar with this, and I've seen it in one of your notebooks, too:
I could have sworn we support costs for FP and FNs, but upon checking the code it seems like that's only in our reductions methods. @miro have we considered this for postprocessing? This seems to be the only gap I can identify here. There seems to be an (fairly old) issue asking for just this, too: #473 Summary:@fairlearn/fairlearn-maintainers: @MiroDudik @riedgar-ms @AndreFCruz and I discussed this yesterday on the community call. We all agreed that it makes sense to add. @hildeweerts suggested the same via email. I will be on point as the responsible maintainer to respond (just to make sure this doesn't catch dust 😄 ), but obviously every perspective is valuable and encouraged. |
Thanks for the thorough feedback Roman! All points sound very reasonable. A few specific questions:
Can we implement the Strict and Relaxed logic in different classes and add them to the MRO of the ThresholdOptimizer object dynamically in the constructor (at runtime)? Or is there a better solution? @MiroDudik mentioned some possible MixIn based solution (?)
.15. I can use this fairlearn mapping for objective functions, but it will reduce functionality. Instead of allowing for any FP and FN cost, only allows for 1-to-1 costs (accuracy) or costs normalized by size (balanced accuracy). |
Re 1: Re 3:
Re 15: |
Re 3: I am actually in favor of implementing Re 15: I definitely think that we should allow for different costs. This is something that we discussed previously: For API, we should go with option (2) in the above issue, so using |
Hi fairlearn maintainers,
We’ve implemented a relaxation for the common postprocessing (threshold optimization) fairness method, that essentially enables optimizing for some loss (e.g., accuracy) with a maximum difference between groups’ TPRs or FPRs.
The implementation is self-contained and available at https://github.com/andrefcruz/error-parity
There are also several example notebooks in the “examples” folder.
What would be a road map to have this included into fairlearn?
I guess the main options would be:
ThresholdOptimizer
class;tolerance: float = None
, and whenever that argument is passed the relaxed implementation would be used?RelaxedThresholdOptimizer
class;ThresholdOptimizer
(as the relaxation implies solving a linear program).Other thoughts/questions:
tolerance=None
(the default)?ThresholdOptimizer
class or a separateRelaxedThresholdOptimizer
? Or can we just throwNotImplementedError
whenever a specific unimplemented combination of kwargs is requested?Thanks and all the best,
André
Is your feature request related to a problem? Please describe.
Currently it is only possible to achieve exact equality between group-specific TPR or FPR (or both). Having a relaxed constraint fulfillment can enable direct head-to-head comparison between different fair ML methods at the same level of fairness. Additionally, relaxed constraint fulfillment also enables us to map the whole fairness-accuracy Pareto front for a single given classifier.
Describe the solution you'd like
The solution for relaxed equalized odds has been implemented at https://github.com/AndreFCruz/error-parity/blob/main/error_parity/cvxpy_utils.py#L159
It describes the problem as an LP, and relies on
cvxpy
to solve it. Then, up to three realized ROC points are used to triangulate to target ROC point (which can be in the interior of the ROC curve, and hence require randomization of predictions).The text was updated successfully, but these errors were encountered: