Spaces:
Running
Running
| from __future__ import annotations | |
| import numpy as np | |
| import pandas as pd | |
| from sklearn.metrics import roc_auc_score | |
| def fairness_report(y_true: np.ndarray, y_proba: np.ndarray, groups: pd.Series, threshold: float=0.5, min_group_size: int=200) -> pd.DataFrame: | |
| df = pd.DataFrame({'y': y_true, 'p': y_proba, 'g': groups.values}) | |
| rows = [] | |
| overall_auc = roc_auc_score(y_true, y_proba) | |
| overall_fpr = float(((y_proba >= threshold) & (y_true == 0)).sum() / max((y_true == 0).sum(), 1)) | |
| for (g, sub) in df.groupby('g'): | |
| if len(sub) < min_group_size or sub['y'].nunique() < 2: | |
| continue | |
| pred = (sub['p'] >= threshold).astype(int) | |
| tp = int(((pred == 1) & (sub['y'] == 1)).sum()) | |
| fp = int(((pred == 1) & (sub['y'] == 0)).sum()) | |
| fn = int(((pred == 0) & (sub['y'] == 1)).sum()) | |
| tn = int(((pred == 0) & (sub['y'] == 0)).sum()) | |
| tpr = tp / max(tp + fn, 1) | |
| fpr = fp / max(fp + tn, 1) | |
| auc = roc_auc_score(sub['y'], sub['p']) | |
| rows.append({'group': g, 'n': len(sub), 'positive_rate': float(sub['y'].mean()), 'auc': float(auc), 'auc_gap': float(auc - overall_auc), 'tpr': float(tpr), 'fpr': float(fpr), 'fpr_gap': float(fpr - overall_fpr), 'approval_rate': float((pred == 0).mean())}) | |
| return pd.DataFrame(rows).sort_values('auc_gap').reset_index(drop=True) | |