You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<p>(The disparate-impact ratio here is 17.10 / 21.62 = 0.79, below the 0.80 four-fifths threshold.)</p>
215
216
<p>The model was not told to discriminate. It learned to - by treating age as a proxy for gender, because women in the dataset more often had career gaps. Age was correlated with gender, so including it smuggled the gender signal back in even without an explicit gender rule.</p>
216
-
<p>After dropping gender and age (the protected attribute and its proxy):</p>
<p><strong>97.3% reduction.</strong> The gap wasn't in the underlying merit of candidates - it was in which features the model was permitted to see.</p>
217
+
<p>After dropping gender and age (the protected attribute and its proxy), the gap closes to <strong>0.12 percentage points</strong> - a <strong>97.3% reduction</strong>. The gap wasn't in the underlying merit of candidates - it was in which features the model was permitted to see.</p>
Copy file name to clipboardExpand all lines: explainers/demographic-parity.md
+6-12Lines changed: 6 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -50,21 +50,15 @@ A model trained with gender and age as features assigned hire recommendations at
50
50
51
51
| Group | Hire Rate |
52
52
|---|---|
53
-
| Male applicants |~71% |
54
-
| Female applicants |~50% |
55
-
|**Fairness Gap**|**~20.9 percentage points**|
53
+
| Male applicants |21.62% |
54
+
| Female applicants |17.10% |
55
+
|**Fairness Gap**|**4.51 percentage points**|
56
56
57
-
The model was not told to discriminate. It learned to - by treating age as a proxy for gender, because women in the dataset more often had career gaps. Age was correlated with gender, so including it smuggled the gender signal back in even without an explicit gender rule.
58
-
59
-
After dropping gender and age (the protected attribute and its proxy):
57
+
(The disparate-impact ratio here is 17.10 / 21.62 = 0.79, below the 0.80 four-fifths threshold.)
The model was not told to discriminate. It learned to - by treating age as a proxy for gender, because women in the dataset more often had career gaps. Age was correlated with gender, so including it smuggled the gender signal back in even without an explicit gender rule.
66
60
67
-
**97.3% reduction.** The gap wasn't in the underlying merit of candidates - it was in which features the model was permitted to see.
61
+
After dropping gender and age (the protected attribute and its proxy), the gap closes to **0.12 percentage points** - a **97.3% reduction**. The gap wasn't in the underlying merit of candidates - it was in which features the model was permitted to see.
<p><code>Gender</code> is a direct input. <code>Age</code> is both an input and a proxy for gender (women in the dataset more often have career gaps, so age encodes gender signal twice over - once directly, once through correlation). The model was <em>designed</em> to see these attributes. The 20.9pp hire rate gap is the disparate impact.</p>
224
+
<p><code>Gender</code> is a direct input. <code>Age</code> is both an input and a proxy for gender (women in the dataset more often have career gaps, so age encodes gender signal twice over - once directly, once through correlation). The model was <em>designed</em> to see these attributes. The 4.51pp hire rate gap (21.62% vs 17.10%) is the disparate impact.</p>
225
225
<h4id="the-fix-what-removing-disparate-treatment-looks-like">The Fix - What Removing Disparate Treatment Looks Like</h4>
226
226
<pre><codeclass="language-python"># fair.py: protected attribute and its proxy removed
227
227
features = ['Experience_Years', 'Technical_Test_Score']
`Gender` is a direct input. `Age` is both an input and a proxy for gender (women in the dataset more often have career gaps, so age encodes gender signal twice over - once directly, once through correlation). The model was *designed* to see these attributes. The 20.9pp hire rate gap is the disparate impact.
72
+
`Gender` is a direct input. `Age` is both an input and a proxy for gender (women in the dataset more often have career gaps, so age encodes gender signal twice over - once directly, once through correlation). The model was *designed* to see these attributes. The 4.51pp hire rate gap (21.62% vs 17.10%) is the disparate impact.
73
73
74
74
### The Fix - What Removing Disparate Treatment Looks Like
<p>The network didn't contain a rule that said "prefer men." It learned from historical hiring data in which men were hired more. The weights encoded that pattern. The bias was invisible - buried in floating-point numbers across hidden layers.</p>
<p><strong>The network's architecture didn't change. The training procedure didn't change. Only the inputs changed - and the bias disappeared.</strong></p>
304
303
<hr>
305
304
<h3id="how-to-inspect-what-a-network-learned">How to Inspect What a Network Learned</h3>
Copy file name to clipboardExpand all lines: explainers/neural-networks.md
+7-13Lines changed: 7 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -152,9 +152,9 @@ features = [
152
152
153
153
| Group | Hire Rate |
154
154
|---|---|
155
-
| Male candidates |61.2% |
156
-
| Female candidates |40.3% |
157
-
|**Fairness gap**|**20.9%**|
155
+
| Male candidates |21.62% |
156
+
| Female candidates |17.10% |
157
+
|**Fairness gap**|**4.51 percentage points**|
158
158
159
159
The network didn't contain a rule that said "prefer men." It learned from historical hiring data in which men were hired more. The weights encoded that pattern. The bias was invisible - buried in floating-point numbers across hidden layers.
160
160
@@ -172,21 +172,15 @@ features = [
172
172
]
173
173
```
174
174
175
-
**Results:**
176
-
177
-
| Group | Hire Rate |
178
-
|---|---|
179
-
| Male candidates | 54.1% |
180
-
| Female candidates | 54.0% |
181
-
|**Fairness gap**|**0.1%**|
175
+
**Result:** the fairness gap closes to **0.12 percentage points**.
182
176
183
177
### Summary
184
178
185
179
| Approach | Fairness Gap | Reduction |
186
180
|---|---|---|
187
-
| Biased model |20.9% | - |
188
-
| Remove gender only |~18%| Minimal |
189
-
| Remove gender + proxy | 0.1% |**99.5%**|
181
+
| Biased model |4.51% | - |
182
+
| Remove gender only |barely moves (age still proxies it)| Minimal |
183
+
| Remove gender + proxy | 0.12% |**97.3%**|
190
184
191
185
**The network's architecture didn't change. The training procedure didn't change. Only the inputs changed - and the bias disappeared.**
Copy file name to clipboardExpand all lines: faircode/_explainers/demographic-parity.md
+6-12Lines changed: 6 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -50,21 +50,15 @@ A model trained with gender and age as features assigned hire recommendations at
50
50
51
51
| Group | Hire Rate |
52
52
|---|---|
53
-
| Male applicants |~71% |
54
-
| Female applicants |~50% |
55
-
|**Fairness Gap**|**~20.9 percentage points**|
53
+
| Male applicants |21.62% |
54
+
| Female applicants |17.10% |
55
+
|**Fairness Gap**|**4.51 percentage points**|
56
56
57
-
The model was not told to discriminate. It learned to - by treating age as a proxy for gender, because women in the dataset more often had career gaps. Age was correlated with gender, so including it smuggled the gender signal back in even without an explicit gender rule.
58
-
59
-
After dropping gender and age (the protected attribute and its proxy):
57
+
(The disparate-impact ratio here is 17.10 / 21.62 = 0.79, below the 0.80 four-fifths threshold.)
The model was not told to discriminate. It learned to - by treating age as a proxy for gender, because women in the dataset more often had career gaps. Age was correlated with gender, so including it smuggled the gender signal back in even without an explicit gender rule.
66
60
67
-
**97.3% reduction.** The gap wasn't in the underlying merit of candidates - it was in which features the model was permitted to see.
61
+
After dropping gender and age (the protected attribute and its proxy), the gap closes to **0.12 percentage points** - a **97.3% reduction**. The gap wasn't in the underlying merit of candidates - it was in which features the model was permitted to see.
`Gender` is a direct input. `Age` is both an input and a proxy for gender (women in the dataset more often have career gaps, so age encodes gender signal twice over - once directly, once through correlation). The model was *designed* to see these attributes. The 20.9pp hire rate gap is the disparate impact.
72
+
`Gender` is a direct input. `Age` is both an input and a proxy for gender (women in the dataset more often have career gaps, so age encodes gender signal twice over - once directly, once through correlation). The model was *designed* to see these attributes. The 4.51pp hire rate gap (21.62% vs 17.10%) is the disparate impact.
73
73
74
74
### The Fix - What Removing Disparate Treatment Looks Like
Copy file name to clipboardExpand all lines: faircode/_explainers/neural-networks.md
+7-13Lines changed: 7 additions & 13 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -152,9 +152,9 @@ features = [
152
152
153
153
| Group | Hire Rate |
154
154
|---|---|
155
-
| Male candidates |61.2% |
156
-
| Female candidates |40.3% |
157
-
|**Fairness gap**|**20.9%**|
155
+
| Male candidates |21.62% |
156
+
| Female candidates |17.10% |
157
+
|**Fairness gap**|**4.51 percentage points**|
158
158
159
159
The network didn't contain a rule that said "prefer men." It learned from historical hiring data in which men were hired more. The weights encoded that pattern. The bias was invisible - buried in floating-point numbers across hidden layers.
160
160
@@ -172,21 +172,15 @@ features = [
172
172
]
173
173
```
174
174
175
-
**Results:**
176
-
177
-
| Group | Hire Rate |
178
-
|---|---|
179
-
| Male candidates | 54.1% |
180
-
| Female candidates | 54.0% |
181
-
|**Fairness gap**|**0.1%**|
175
+
**Result:** the fairness gap closes to **0.12 percentage points**.
182
176
183
177
### Summary
184
178
185
179
| Approach | Fairness Gap | Reduction |
186
180
|---|---|---|
187
-
| Biased model |20.9% | - |
188
-
| Remove gender only |~18%| Minimal |
189
-
| Remove gender + proxy | 0.1% |**99.5%**|
181
+
| Biased model |4.51% | - |
182
+
| Remove gender only |barely moves (age still proxies it)| Minimal |
183
+
| Remove gender + proxy | 0.12% |**97.3%**|
190
184
191
185
**The network's architecture didn't change. The training procedure didn't change. Only the inputs changed - and the bias disappeared.**
`Gender` is a direct input. `Age` is both an input and a proxy for gender (women in the dataset more often have career gaps, so age encodes gender signal twice over - once directly, once through correlation). The model was *designed* to see these attributes. The 20.9pp hire rate gap is the disparate impact.
1210
+
`Gender` is a direct input. `Age` is both an input and a proxy for gender (women in the dataset more often have career gaps, so age encodes gender signal twice over - once directly, once through correlation). The model was *designed* to see these attributes. The 4.51pp hire rate gap (21.62% vs 17.10%) is the disparate impact.
1211
1211
1212
1212
### The Fix - What Removing Disparate Treatment Looks Like
1213
1213
@@ -1992,21 +1992,15 @@ A model trained with gender and age as features assigned hire recommendations at
The model was not told to discriminate. It learned to - by treating age as a proxy for gender, because women in the dataset more often had career gaps. Age was correlated with gender, so including it smuggled the gender signal back in even without an explicit gender rule.
2000
-
2001
-
After dropping gender and age (the protected attribute and its proxy):
1999
+
(The disparate-impact ratio here is 17.10 / 21.62 = 0.79, below the 0.80 four-fifths threshold.)
The model was not told to discriminate. It learned to - by treating age as a proxy for gender, because women in the dataset more often had career gaps. Age was correlated with gender, so including it smuggled the gender signal back in even without an explicit gender rule.
2008
2002
2009
-
**97.3% reduction.** The gap wasn't in the underlying merit of candidates - it was in which features the model was permitted to see.
2003
+
After dropping gender and age (the protected attribute and its proxy), the gap closes to **0.12 percentage points** - a **97.3% reduction**. The gap wasn't in the underlying merit of candidates - it was in which features the model was permitted to see.
2010
2004
2011
2005
---
2012
2006
@@ -3728,9 +3722,9 @@ features = [
3728
3722
3729
3723
| Group | Hire Rate |
3730
3724
|---|---|
3731
-
| Male candidates | 61.2% |
3732
-
| Female candidates | 40.3% |
3733
-
| **Fairness gap** | **20.9%** |
3725
+
| Male candidates | 21.62% |
3726
+
| Female candidates | 17.10% |
3727
+
| **Fairness gap** | **4.51 percentage points** |
3734
3728
3735
3729
The network didn't contain a rule that said "prefer men." It learned from historical hiring data in which men were hired more. The weights encoded that pattern. The bias was invisible - buried in floating-point numbers across hidden layers.
3736
3730
@@ -3748,21 +3742,15 @@ features = [
3748
3742
]
3749
3743
```
3750
3744
3751
-
**Results:**
3752
-
3753
-
| Group | Hire Rate |
3754
-
|---|---|
3755
-
| Male candidates | 54.1% |
3756
-
| Female candidates | 54.0% |
3757
-
| **Fairness gap** | **0.1%** |
3745
+
**Result:** the fairness gap closes to **0.12 percentage points**.
3758
3746
3759
3747
### Summary
3760
3748
3761
3749
| Approach | Fairness Gap | Reduction |
3762
3750
|---|---|---|
3763
-
| Biased model | 20.9% | - |
3764
-
| Remove gender only | ~18% | Minimal |
3765
-
| Remove gender + proxy | 0.1% | **99.5%** |
3751
+
| Biased model | 4.51% | - |
3752
+
| Remove gender only | barely moves (age still proxies it) | Minimal |
3753
+
| Remove gender + proxy | 0.12% | **97.3%** |
3766
3754
3767
3755
**The network's architecture didn't change. The training procedure didn't change. Only the inputs changed - and the bias disappeared.**
0 commit comments