Responsible AI
Models affect people; build them with fairness, privacy and transparency in mind.
Machine-learning systems make decisions about loans, hiring and health. With that power comes responsibility.
Key concerns
- Bias — a model learns the biases in its data. Check performance across groups.
- Privacy — handle personal data lawfully and minimally.
- Transparency — be able to explain important decisions.
- Accountability — keep a human in the loop for high-stakes calls.
A model that is accurate on average can still be unfair to a subgroup. Always test who it works for.
Example
from sklearn.metrics import accuracy_score
# Check accuracy separately for each group, not just overall
def accuracy_by_group(y_true, y_pred, groups):
for g in set(groups):
idx = [i for i, x in enumerate(groups) if x == g]
acc = accuracy_score([y_true[i] for i in idx],
[y_pred[i] for i in idx])
print(g, 'accuracy:', round(acc, 2))
# Big gaps between groups can signal unfair bias
print('audit models across subgroups, not just overall')When to use it
- A hiring platform audits its ML screening tool by computing approval rates by gender to detect and address disparate impact before deployment.
- A healthcare company uses differential privacy techniques during model training so that patient records cannot be inferred from the trained model.
- A team uses SHAP values to explain individual predictions of a loan-denial model, fulfilling a legal requirement to tell applicants why they were rejected.
More examples
Audit predictions for disparate impact
Groups outcome labels by a protected attribute (gender) and computes the disparate impact ratio; a value below 0.8 signals potential discrimination under the 4/5ths rule.
import pandas as pd
from sklearn.ensemble import RandomForestClassifier
df = pd.DataFrame({
'score': [0.6, 0.8, 0.4, 0.9, 0.3, 0.7],
'gender': ['M', 'F', 'M', 'F', 'M', 'F'],
'label': [1, 1, 0, 1, 0, 1]
})
approval_rate = df.groupby('gender')['label'].mean()
print(approval_rate)
print('Disparate impact ratio:', (approval_rate.min() / approval_rate.max()).round(3))SHAP values for explainability
Uses SHAP TreeExplainer to compute per-feature contributions to each prediction, enabling explanation of why the model classified a specific sample as it did.
import shap
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
X, y = load_breast_cancer(return_X_y=True)
model = RandomForestClassifier(n_estimators=50, random_state=0).fit(X, y)
explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X[:5])
print('SHAP shape:', shap_values[0].shape)
print('Feature contributions for sample 0:', shap_values[0][0].round(3))Check for data leakage before training
Splits the data before computing imputation statistics and applies training-set means to fill both splits, preventing future test-set information from contaminating training.
import pandas as pd
from sklearn.model_selection import train_test_split
df = pd.read_csv('loans.csv')
X = df.drop(columns=['loan_id', 'default'])
y = df['default']
# Split BEFORE any computation on X
X_tr, X_te, y_tr, y_te = train_test_split(X, y, test_size=0.2, random_state=0)
# Compute mean only from training data
train_mean = X_tr.mean()
X_tr_filled = X_tr.fillna(train_mean)
X_te_filled = X_te.fillna(train_mean) # use TRAIN mean, not test
print('No leakage: imputed with train stats only')
Discussion