APERTURE_AUDIT / model.py
Darkweb007's picture
Initial commit: model-agnostic SHAP/LIME explainability audit dashboard
41dfe78
Raw
History Blame Contribute Delete
2.03 kB
"""
The production model being audited: logistic regression over 7 synthetic
credit-application features. Logistic regression is a deliberate choice for
a compliance dashboard, not just a simplification -- it's the closed form
that makes exact, closed-form attribution possible (see explain/shap_exact.py)
rather than requiring a sampling-based approximation. In production this slot
is an arbitrary model (XGBoost, a neural net); the explanation layer in this
repo is built to swap over to KernelSHAP/LIME without assuming linearity --
see the production upgrade path in the README.
"""
from __future__ import annotations
import os
from dataclasses import dataclass
import numpy as np
import pandas as pd
from sklearn.linear_model import LogisticRegression
FEATURES = [
"annual_income_k", "debt_to_income_pct", "credit_history_years",
"num_late_payments_2y", "employment_years", "loan_amount_k", "num_open_accounts",
]
FEATURE_LABELS = {
"annual_income_k": "Annual income ($k)",
"debt_to_income_pct": "Debt-to-income (%)",
"credit_history_years": "Credit history (years)",
"num_late_payments_2y": "Late payments (last 2y)",
"employment_years": "Employment length (years)",
"loan_amount_k": "Loan amount requested ($k)",
"num_open_accounts": "Open credit accounts",
}
@dataclass
class TrainedModel:
model: LogisticRegression
feature_means: pd.Series
train_accuracy: float
coefficients: dict
def train(csv_path: str) -> TrainedModel:
df = pd.read_csv(csv_path)
X = df[FEATURES]
y = df["approved"]
model = LogisticRegression(max_iter=1000)
model.fit(X, y)
acc = float(model.score(X, y))
coefs = dict(zip(FEATURES, model.coef_[0]))
return TrainedModel(
model=model,
feature_means=X.mean(),
train_accuracy=acc,
coefficients=coefs,
)
def predict_proba(trained: TrainedModel, applicant: dict) -> float:
x = pd.DataFrame([applicant])[FEATURES]
return float(trained.model.predict_proba(x)[0][1])