مقاييس الإنصاف: التكافؤ الديموغرافي وتكافؤ الفرص
سيقيس المتعلمون الفرق في التكافؤ الديموغرافي والفرق في تكافؤ الفرص على نموذج للموافقة على القروض، ويحدّدون ما إذا كان النموذج يضر بالمجموعات المحمية.
مقاييس الإنصاف: التكافؤ الديموغرافي وتكافؤ الفرص درس مجاني في Machine Learning Academy على CoddyKit. هذا هو الدرس 3 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Machine Learning Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Machine Learning Academy 4 دروس في المجموع.
بعض أجزاء هذا الدرس لم تُترجم بعد وتظهر باللغة الإنجليزية.
Why Fairness in ML Matters
Machine learning models trained on historical data can perpetuate and amplify existing societal biases. A loan approval model trained on past approvals may systematically deny credit to protected groups not because of their creditworthiness but because of discriminatory historical patterns in the training data. Fairness metrics quantify the extent to which a model treats different demographic groups differently, enabling auditors and engineers to detect and correct discriminatory behaviour.
Protected Attributes and Groups
A protected attribute is a demographic characteristic that should not influence high-stakes decisions — typically race, gender, age, religion, or disability status. A protected group is the subset of examples sharing a value of that attribute (e.g., female applicants). Fairness analysis compares model outcomes across these groups. Even if the protected attribute is removed from the feature set, proxy features (e.g., zip code) can still encode it.
import pandas as pd
import numpy as np
# Toy loan dataset
np.random.seed(42)
df = pd.DataFrame({
'income': np.random.normal(50000, 15000, 1000),
'credit_score': np.random.normal(650, 80, 1000),
'gender': np.random.choice(['M', 'F'], 1000),
'approved': np.random.choice([0, 1], 1000, p=[0.4, 0.6])
})
# Simulate a biased approval: female applicants approved 10% less
df.loc[df['gender'] == 'F', 'approved'] = (
df.loc[df['gender'] == 'F', 'approved'] * 0.85
).round().astype(int).clip(0, 1)
print(df.groupby('gender')['approved'].mean())Demographic Parity
Demographic parity (also called statistical parity) requires that the proportion of positive predictions is equal across all demographic groups. If a model approves 70% of male applicants but only 55% of female applicants, demographic parity is violated. The demographic parity difference is the absolute gap between group positive prediction rates; a value of zero means perfect parity.
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
features = ['income', 'credit_score']
X = df[features].values
y = df['approved'].values
g = df['gender'].values
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
model = LogisticRegression()
model.fit(X_scaled, y)
y_pred = model.predict(X_scaled)
# Demographic parity difference
rate_M = y_pred[g == 'M'].mean()
rate_F = y_pred[g == 'F'].mean()
print(f'Approval rate M: {rate_M:.3f}')
print(f'Approval rate F: {rate_F:.3f}')
print(f'Demographic parity difference: {abs(rate_M - rate_F):.3f}')Equal Opportunity
Equal opportunity requires that the true positive rate (recall) is equal across groups — in other words, qualified applicants from every group should have the same probability of being correctly approved. Unlike demographic parity, equal opportunity conditions on the true label, so it does not require approving unqualified applicants to achieve parity. It specifically targets the error of missing deserving members of a protected group.
from sklearn.metrics import recall_score
# True positive rate per group (recall among actually qualified)
mask_M = g == 'M'
mask_F = g == 'F'
tpr_M = recall_score(y[mask_M], y_pred[mask_M])
tpr_F = recall_score(y[mask_F], y_pred[mask_F])
print(f'True positive rate M (recall): {tpr_M:.3f}')
print(f'True positive rate F (recall): {tpr_F:.3f}')
print(f'Equal opportunity difference: {abs(tpr_M - tpr_F):.3f}')
# A value > 0.05 is often flagged as meaningful unfairnessEqualized Odds
Equalized odds is a stricter criterion that requires both the true positive rate AND the false positive rate to be equal across groups. This prevents the model from simultaneously under-approving qualified minority applicants (low TPR) and over-approving unqualified majority applicants (high FPR). It is the standard fairness criterion used in legal contexts like the US Equal Credit Opportunity Act.
from sklearn.metrics import confusion_matrix
def false_positive_rate(y_true, y_pred):
tn, fp, fn, tp = confusion_matrix(y_true, y_pred).ravel()
return fp / (fp + tn) if (fp + tn) > 0 else 0.0
fpr_M = false_positive_rate(y[mask_M], y_pred[mask_M])
fpr_F = false_positive_rate(y[mask_F], y_pred[mask_F])
print(f'FPR M: {fpr_M:.3f} TPR M: {tpr_M:.3f}')
print(f'FPR F: {fpr_F:.3f} TPR F: {tpr_F:.3f}')
print(f'Equalized odds: TPR diff={abs(tpr_M-tpr_F):.3f}, FPR diff={abs(fpr_M-fpr_F):.3f}')Fairness-Accuracy Trade-offs
Satisfying fairness constraints often comes at a cost to overall accuracy or profit. This is the fairness-accuracy trade-off. Impossibility theorems (Chouldechova 2017, Kleinberg 2016) show that demographic parity, equal opportunity, and calibration cannot all be satisfied simultaneously when base rates differ between groups. Choosing which fairness criterion to optimise is therefore a value judgement that must involve domain experts and affected communities, not just data scientists.
# Visualise trade-off: adjust threshold per group
import numpy as np
proba = model.predict_proba(X_scaled)[:, 1]
# Without fairness: single 0.5 threshold
y_single = (proba >= 0.5).astype(int)
# With equal opportunity: lower threshold for F to equalise TPR
# Find threshold for F that gives same TPR as M
tpr_target = recall_score(y[mask_M], y_single[mask_M])
print(f'Target TPR from M group: {tpr_target:.3f}')
for thresh in np.arange(0.3, 0.7, 0.01):
y_adj = proba[mask_F] >= thresh
if recall_score(y[mask_F], y_adj) >= tpr_target:
print(f'Threshold for F to achieve equal opportunity: {thresh:.2f}')
breakThe fairlearn Library
Microsoft's fairlearn library provides fairness metrics and mitigation algorithms in a scikit-learn-compatible API. Use MetricFrame to compute any metric broken down by group in one call, revealing disparities across the full metric suite without manual indexing. Install with pip install fairlearn.
from fairlearn.metrics import MetricFrame, demographic_parity_difference
from fairlearn.metrics import equalized_odds_difference
from sklearn.metrics import accuracy_score, precision_score, recall_score
mf = MetricFrame(
metrics={
'accuracy': accuracy_score,
'precision': precision_score,
'recall': recall_score
},
y_true=y,
y_pred=y_pred,
sensitive_features=g
)
print(mf.by_group)
print('Demographic parity diff:', demographic_parity_difference(y, y_pred, sensitive_features=g))
print('Equalized odds diff:', equalized_odds_difference(y, y_pred, sensitive_features=g))Calibration Across Groups
Calibration requires that among all applicants given a predicted probability of X%, approximately X% should actually belong to the positive class — and this must hold within each demographic group separately. Poor group calibration means the model is systematically over- or under-confident for a protected group, which distorts risk-based decisions like credit scoring. Use reliability diagrams or sklearn.calibration.calibration_curve per group to check.
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
for group in ['M', 'F']:
mask = g == group
prob_true, prob_pred = calibration_curve(
y[mask], proba[mask], n_bins=5
)
ax.plot(prob_pred, prob_true, marker='o', label=f'gender={group}')
ax.plot([0, 1], [0, 1], 'k--', label='Perfect calibration')
ax.set(xlabel='Mean predicted probability', ylabel='Fraction of positives')
ax.legend()
plt.title('Calibration curves by gender')
plt.tight_layout()
plt.savefig('calibration_by_group.png', dpi=150)Intersectional Fairness
Intersectional fairness considers combinations of protected attributes simultaneously. A model may achieve demographic parity for gender and for race individually, yet still discriminate against Black women as a sub-group. The fairlearn MetricFrame handles this automatically when you pass multiple sensitive columns as a DataFrame, computing metrics for every (gender × race) combination.
import pandas as pd
from fairlearn.metrics import MetricFrame
from sklearn.metrics import accuracy_score
# Add a second protected attribute
df['race'] = np.random.choice(['A', 'B'], len(df))
sensitive_df = df[['gender', 'race']]
mf_intersect = MetricFrame(
metrics={'accuracy': accuracy_score},
y_true=y,
y_pred=y_pred,
sensitive_features=sensitive_df
)
print(mf_intersect.by_group)
print('Worst accuracy subgroup:', mf_intersect.by_group.min())Choosing the Right Fairness Criterion
Different applications call for different fairness criteria. For recidivism prediction, equal opportunity (equalise recall among those who do not re-offend) is paramount. For hiring tools, demographic parity prevents systemic under-representation. For medical screening, equalized odds ensures no group is disproportionately missed. Documenting which criterion was chosen and why is a key part of responsible AI practice and model cards.
# Decision guide: which metric to use
criteria_guide = {
'hiring / college admission': 'Demographic parity — equal representation',
'medical screening': 'Equal opportunity — equalise recall (catch all sick patients)',
'fraud / recidivism': 'Equalized odds — control both FPR and TPR',
'credit scoring': 'Calibration — predicted risk reflects actual risk per group'
}
for use_case, criterion in criteria_guide.items():
print(f'{use_case}: {criterion}')Limitations of Fairness Metrics
Fairness metrics measure statistical disparities, not root causes. A model can satisfy demographic parity while still making individual decisions based on protected attributes through correlated proxies. Additionally, all these metrics assume binary sensitive attributes and binary outcomes; real-world fairness is more complex. Metrics should be complemented by qualitative methods: community engagement, process audits, and impact assessments before deployment.
# Summary of limitations
limitations = [
'Proxy features (zip code, surname) can encode protected attributes even when removed',
'Satisfying one fairness criterion can violate another (impossibility theorem)',
'Metrics are group-level averages; individual unfairness can persist',
'Binary group splits may hide variation within groups',
'Historical data reflects past discrimination; fair training data is often unavailable'
]
for i, lim in enumerate(limitations, 1):
print(f'{i}. {lim}')Quick Check
Test your understanding of Machine Learning with Python concepts from this lesson.
Lesson Recap
In this lesson you learned: demographic parity requires equal positive prediction rates across groups, equal opportunity requires equal recall (true positive rates), and equalized odds additionally requires equal false positive rates. You also saw that these criteria cannot all be satisfied simultaneously when base rates differ, and that the fairlearn library makes group-level metric computation straightforward. Next up we explore concrete strategies to mitigate the bias that these metrics reveal.
تعلم Python مع معلم ذكاء اصطناعي — مجانًا
اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.
- الدورات
- 30
- الدروس
- 120
الأسئلة الشائعة
هل درس «مقاييس الإنصاف: التكافؤ الديموغرافي وتكافؤ الفرص» مجاني؟
نعم — نص درس «مقاييس الإنصاف: التكافؤ الديموغرافي وتكافؤ الفرص» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Machine Learning Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Machine Learning Academy 4 دروس في المجموع.
ماذا ستتعلم في «مقاييس الإنصاف: التكافؤ الديموغرافي وتكافؤ الفرص»؟
سيقيس المتعلمون الفرق في التكافؤ الديموغرافي والفرق في تكافؤ الفرص على نموذج للموافقة على القروض، ويحدّدون ما إذا كان النموذج يضر بالمجموعات المحمية. تتمرن على Machine Learning Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Machine Learning Academy؟
لا تُشترط خبرة سابقة. Machine Learning Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 3 من أصل 4.
كم من الوقت يستغرق درس «مقاييس الإنصاف: التكافؤ الديموغرافي وتكافؤ الفرص»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Machine Learning Academy هذا؟
نعم. كل درس في Machine Learning Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- قيم SHAP: الأهمية العامة والمحلية للميزات
- LIME: تفسيرات محلية قابلة للفهم ومستقلة عن النموذج
- مقاييس الإنصاف: التكافؤ الديموغرافي وتكافؤ الفرص
- استراتيجيات الحد من التحيز: المعالجة المسبقة وأثناء المعالجة وما بعدها