Inspiration
A scholarship model that is 88% accurate funds 48.4% of applicants from Montréal and Québec City, but only 27.3% from Bas-Saint-Laurent, Côte-Nord and Gaspésie, even though their R scores differ by just 0.7 points. We wanted to know why, and to fix it properly.
What we learned
Accuracy can be the problem: the model is accurate because it copies a biased committee. Deleting the region column doesn't help either, because distance and postal code identify the region almost perfectly. The bias lives in the labels, not the columns. We also found a second, hidden bias: the committee rewarded family income, and remote families earn 25% less.
How we built it
We modelled the committee with an explicit remote-region term:
$$ \text{logit}\,P(\text{award}) = \beta_0 + \beta_R R + \beta_h h + \beta_I \log I + \beta_d d + \beta_{\text{rem}} \mathbb{1}[\text{remote}] $$
The penalty, $|\beta_{\text{rem}}| / \beta_R \approx 1.6$ R points, explains 83% of the gap. With identical grades, 190 of 1,628 remote applicants would be funded just by living in Montréal.
We then switched off the penalty, the income bonus and distance, keeping the committee's own weighting of merit:
$$ \text{merit} = R + 0.146\,h $$
The top 41% are funded. Grant rates went from 46.8% vs 27.8% to 40.9% vs 41.1%, the equal-opportunity gap from 0.30 to 0, and HxBuddy accuracy reached 94.68%. A monitoring module checks every batch and stops a redeployed biased model.
Challenges
The only label we had was the biased one, so standard fairness tools thought the old model was already fair. We built our own merit references, and treated the leaderboard as a lab: 24 controlled experiments, each changing one ingredient. They confirmed that income isn't merit, hours worked are, and the committee's own weight of 0.146 was the peak.
Built With
- claude
- data-analysis
- explainable-ai
- fairlearn
- fairness
- github
- html
- jupyter
- logistic-regression
- machine-learning
- matplotlib
- numpy
- pandas
- pytest
- python
- random-forest
- scikit-learn
- shap
Log in or sign up for Devpost to join the conversation.