Assignment Overview
In this assignment, you will build a complete Ethical AI Evaluation Framework for a loan approval system. This comprehensive project requires you to apply ALL concepts from Module 6: AI ethics principles, bias detection, fairness metrics, model explainability (SHAP/LIME), privacy considerations, and production deployment monitoring. You will analyze a pre-trained model, identify ethical issues, and build tools to ensure responsible AI deployment.
Ethics & Fairness (6.2)
Bias detection, demographic parity, equalized odds, disparate impact analysis
Explainability (6.2)
SHAP values, feature importance, individual decision explanations
Deployment (6.2)
Model monitoring, data drift detection, prediction logging, alerts
The Scenario
FairLend Financial Services
You have been hired as an AI Ethics Engineer at FairLend Financial Services, a lending company that uses machine learning to make loan approval decisions. The company recently received complaints about potential discrimination in their AI system. The Chief Ethics Officer has given you this task:
"We need you to audit our loan approval model for bias and fairness. Analyze whether our AI treats all demographic groups equally, explain how it makes decisions, and build a monitoring system so we can catch problems in production. Our reputation depends on responsible AI."
Your Task
Create a Jupyter Notebook called ethics_framework.ipynb that implements a complete
ethical AI evaluation system. Your code must analyze a pre-trained loan approval model, detect
biases across protected groups (gender, race, age), generate explanations using SHAP, and build
production monitoring infrastructure.
The Dataset
You will work with a synthetic loan application dataset designed to contain realistic biases. This dataset has been carefully constructed to test your bias detection skills.
File: loan_applications.csv (1000 rows)
applicant_id,age,gender,race,income,credit_score,debt_ratio,employment_years,loan_amount,approved
A001,35,Male,White,75000,720,0.28,8,25000,1
A002,28,Female,Black,52000,680,0.35,4,15000,0
A003,45,Male,Asian,92000,750,0.22,15,40000,1
A004,31,Female,Hispanic,48000,650,0.42,3,12000,0
A005,55,Male,White,110000,780,0.18,25,50000,1
...
Feature Columns
applicant_id- Unique identifier (string)age- Applicant age in years (integer, 18-70)gender- Male or Female (protected attribute)race- White, Black, Asian, Hispanic (protected attribute)income- Annual income in dollars (integer)credit_score- FICO score 300-850 (integer)debt_ratio- Debt-to-income ratio (float, 0-1)employment_years- Years at current job (integer)loan_amount- Requested loan amount (integer)
Target Column
approved- Loan decision (1 = approved, 0 = denied)
Protected Attributes
The gender and race columns are protected attributes under
fair lending laws. Your model should NOT use these directly, but the pre-trained model
may have learned proxy biases from correlated features.
Pre-trained Model: loan_model.pkl
# Load the pre-trained model
import joblib
model = joblib.load('loan_model.pkl') # RandomForestClassifier
# The model was trained on features (excluding protected attributes):
# ['income', 'credit_score', 'debt_ratio', 'employment_years', 'loan_amount', 'age']
# Make predictions
predictions = model.predict(X_test)
probabilities = model.predict_proba(X_test)[:, 1]
generate_data.py script.
Requirements
Your ethics_framework.ipynb must implement ALL of the following components.
Each component is mandatory and will be evaluated individually.
Load and Explore Data
Create functions to load and analyze the loan application dataset:
- Load
loan_applications.csvusing pandas - Calculate approval rates by gender and race
- Visualize distribution differences across protected groups
- Identify potential sources of bias in the data
def load_and_explore(filepath):
"""Load data and compute approval rates by protected groups."""
df = pd.read_csv(filepath)
# Approval rates by gender
gender_rates = df.groupby('gender')['approved'].mean()
# Approval rates by race
race_rates = df.groupby('race')['approved'].mean()
return df, gender_rates, race_rates
Calculate Fairness Metrics
Implement functions to compute key fairness metrics:
- Demographic Parity: P(approved | group A) = P(approved | group B)
- Equalized Odds: Same TPR and FPR across groups
- Disparate Impact Ratio: Must be between 0.8 and 1.25 (80% rule)
- Predictive Parity: Same precision across groups
def calculate_demographic_parity(y_true, y_pred, protected_attr):
"""Calculate demographic parity difference between groups."""
pass
def calculate_equalized_odds(y_true, y_pred, protected_attr):
"""Calculate TPR and FPR difference between groups."""
pass
def calculate_disparate_impact(y_true, y_pred, protected_attr):
"""Calculate disparate impact ratio (must be 0.8-1.25)."""
pass
Detect Bias in Model Predictions
Analyze the pre-trained model for bias:
- Load the pre-trained
loan_model.pkl - Generate predictions on the test set
- Apply fairness metrics to predictions (not just training data)
- Identify which groups are disadvantaged by the model
- Determine if bias exceeds legal thresholds
def analyze_model_bias(model, X_test, y_test, protected_attrs):
"""Analyze model predictions for bias across protected groups."""
predictions = model.predict(X_test)
results = {}
for attr in protected_attrs:
results[attr] = {
'demographic_parity': calculate_demographic_parity(...),
'equalized_odds': calculate_equalized_odds(...),
'disparate_impact': calculate_disparate_impact(...)
}
return results
Generate SHAP Explanations
Use SHAP to explain model decisions:
- Create a SHAP TreeExplainer for the Random Forest model
- Generate global feature importance plot
- Create individual explanations for 5 denied applicants
- Identify if protected attributes (via proxies) influence decisions
- Generate a SHAP summary plot
import shap
def generate_explanations(model, X_test, feature_names):
"""Generate SHAP explanations for model decisions."""
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X_test)
# Global importance
shap.summary_plot(shap_values[1], X_test, feature_names=feature_names)
return shap_values
Build Monitoring System
Create a production monitoring class:
- Log predictions with timestamps, features, and confidence
- Track approval rate over time (detect drift)
- Implement data drift detection using KL divergence
- Generate alerts when fairness metrics degrade
- Create a monitoring dashboard visualization
class FairnessMonitor:
"""Monitor model fairness in production."""
def __init__(self, baseline_metrics):
self.baseline = baseline_metrics
self.predictions = []
self.alerts = []
def log_prediction(self, features, prediction, protected_attrs):
"""Log a prediction for monitoring."""
pass
def check_fairness_drift(self, window_size=100):
"""Check if fairness metrics have degraded."""
pass
def generate_report(self):
"""Generate monitoring report with alerts."""
pass
Write Ethics Evaluation Report
Create a markdown report (ETHICS_REPORT.md) that includes:
- Executive summary of findings
- Detailed bias analysis with visualizations
- Fairness metric results and interpretation
- SHAP explanation insights
- Recommendations for bias mitigation
- Monitoring strategy for production
Main Execution
Create a main section that demonstrates all components:
# Main execution
if __name__ == "__main__":
# 1. Load data
df, gender_rates, race_rates = load_and_explore('loan_applications.csv')
print(f"Approval rate by gender:\n{gender_rates}")
print(f"Approval rate by race:\n{race_rates}")
# 2. Load model and prepare data
model = joblib.load('loan_model.pkl')
X = df[['income', 'credit_score', 'debt_ratio', 'employment_years',
'loan_amount', 'age']]
y = df['approved']
# 3. Analyze bias
bias_results = analyze_model_bias(model, X, y,
protected_attrs=['gender', 'race'])
print(f"Bias Analysis Results:\n{bias_results}")
# 4. Generate explanations
shap_values = generate_explanations(model, X, X.columns.tolist())
# 5. Initialize monitoring
monitor = FairnessMonitor(baseline_metrics=bias_results)
# 6. Simulate production predictions
for i in range(100):
monitor.log_prediction(X.iloc[i], model.predict([X.iloc[i]])[0],
{'gender': df.iloc[i]['gender'],
'race': df.iloc[i]['race']})
# 7. Check for drift
drift_report = monitor.check_fairness_drift()
print(f"Drift Report:\n{drift_report}")
print("Ethics evaluation complete!")
Submission
Create a public GitHub repository with the exact name shown below:
Required Repository Name
fairlend-ethics-framework
Required Files
fairlend-ethics-framework/
├── ethics_framework.ipynb # Your Jupyter Notebook with ALL components
├── loan_applications.csv # Input dataset
├── loan_model.pkl # Pre-trained model file
├── ETHICS_REPORT.md # Written ethics evaluation report
├── figures/ # Folder for generated visualizations
│ ├── approval_rates.png
│ ├── shap_summary.png
│ ├── fairness_metrics.png
│ └── monitoring_dashboard.png
└── README.md # Project documentation
README.md Must Include:
- Your full name and submission date
- Brief description of your evaluation methodology
- Summary of key findings (bias detected, fairness scores)
- Instructions to run your notebook
- List of required packages with versions
Do Include
- All 7 components implemented and working
- Clear visualizations with proper labels
- Docstrings for all functions and classes
- ETHICS_REPORT.md with actionable recommendations
- All generated figures in the figures/ folder
- requirements.txt with package versions
Do Not Include
- Virtual environment folders (venv, .env)
- Jupyter checkpoints (.ipynb_checkpoints)
- Cache files (__pycache__)
- Code that does not run without errors
- Plagiarized code from other sources
- Hardcoded results (we will test with different data)
Enter your GitHub username - we will verify your repository automatically
Grading Rubric
Your assignment will be graded on the following criteria:
| Criteria | Points | Description |
|---|---|---|
| Fairness Metrics Implementation | 50 | Correct implementation of demographic parity, equalized odds, disparate impact, and predictive parity |
| Bias Detection Analysis | 40 | Thorough analysis of model predictions across protected groups with clear visualizations |
| SHAP Explanations | 40 | Proper use of SHAP library, global and local explanations, feature importance analysis |
| Monitoring System | 40 | Complete FairnessMonitor class with logging, drift detection, and alerting |
| Ethics Report Quality | 40 | Well-written ETHICS_REPORT.md with findings, interpretations, and actionable recommendations |
| Code Quality | 40 | Clean code, docstrings, comments, proper naming, error handling, and organization |
| Total | 250 |
Ready to Submit?
Make sure you have completed all requirements and reviewed the grading rubric above.
Submit Your AssignmentWhat You Will Practice
Fairness Metrics (6.2)
Implementing and interpreting demographic parity, equalized odds, disparate impact, and predictive parity across protected groups
Bias Detection (6.2)
Analyzing model predictions for discriminatory patterns, identifying advantaged and disadvantaged groups, visualizing disparities
Explainability (6.2)
Using SHAP to generate global feature importance and individual decision explanations, identifying proxy discrimination
Production Monitoring (6.2)
Building monitoring infrastructure to track fairness metrics over time, detect drift, and generate alerts for degradation
Pro Tips
Fairness Best Practices
- Use multiple fairness metrics (no single metric captures everything)
- Compare against legal thresholds (80% rule for disparate impact)
- Consider intersectionality (e.g., Black women vs. White men)
- Document your fairness definitions and rationale
SHAP Tips
- Use TreeExplainer for Random Forest (faster than KernelExplainer)
- Generate summary plot for global understanding
- Use force plots for individual explanations
- Look for proxy variables that correlate with protected attributes
Monitoring Tips
- Use sliding windows to detect recent drift
- Set alert thresholds based on baseline variance
- Log predictions with timestamps for time-series analysis
- Include confidence scores in prediction logs
Common Mistakes
- Computing fairness metrics on training data instead of predictions
- Ignoring base rates when interpreting metrics
- Not handling edge cases (empty groups, division by zero)
- Forgetting to save figures before clearing notebook output