FULL MODEL CODE:
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from [Link] import StandardScaler, OneHotEncoder
from [Link] import ColumnTransformer
from [Link] import Pipeline
from sklearn.linear_model import LogisticRegression
from [Link] import RandomForestClassifier
from [Link] import roc_auc_score, accuracy_score, f1_score
from imblearn.over_sampling import SMOTE
from [Link] import Pipeline as ImbPipeline
from xgboost import XGBClassifier
import shap
import warnings
[Link]("ignore")
# ==============================
# Step 3: Upload Dataset
# ==============================
from [Link] import files
uploaded = [Link]() # Upload credit_data.csv manually
data = pd.read_csv("[Link]")
print("Dataset Shape:", [Link])
print("\nColumns:\n", [Link])
[Link]()
# Target variable
y = data["credit_risk"]
# Feature set
X = [Link]("credit_risk", axis=1)
# Sensitive attribute (for fairness)
sensitive_attr = data["personal_status_sex"]
categorical_cols = [
'status','credit_history','purpose','savings',
'employment_duration','personal_status_sex',
'other_debtors','property','other_installment_plans',
'housing','job','telephone','foreign_worker'
numerical_cols = [
'duration','amount','installment_rate',
'present_residence','age','number_credits','people_liable'
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numerical_cols),
('cat', OneHotEncoder(drop='first'), categorical_cols)
X_train, X_test, y_train, y_test, sens_train, sens_test = train_test_split(
X, y, sensitive_attr,
test_size=0.3,
stratify=y,
random_state=42
lr = LogisticRegression(max_iter=1000)
rf = RandomForestClassifier(n_estimators=200, random_state=42)
xgb = XGBClassifier(eval_metric="logloss", use_label_encoder=False)
def build_pipeline(model):
return ImbPipeline(steps=[
('preprocess', preprocessor),
('smote', SMOTE(random_state=42)),
('model', model)
])
pipe_lr = build_pipeline(lr)
pipe_rf = build_pipeline(rf)
pipe_xgb = build_pipeline(xgb)
pipe_lr.fit(X_train, y_train)
pipe_rf.fit(X_train, y_train)
pipe_xgb.fit(X_train, y_train)
w_lr, w_rf, w_xgb = 0.3, 0.3, 0.4
prob_lr = pipe_lr.predict_proba(X_test)[:,1]
prob_rf = pipe_rf.predict_proba(X_test)[:,1]
prob_xgb = pipe_xgb.predict_proba(X_test)[:,1]
y_pred_prob = (w_lr*prob_lr + w_rf*prob_rf + w_xgb*prob_xgb)
auc = roc_auc_score(y_test, y_pred_prob)
acc = accuracy_score(y_test, y_pred_prob >= 0.5)
f1 = f1_score(y_test, y_pred_prob >= 0.5)
print("AUC:", auc)
print("Accuracy:", acc)
print("F1-score:", f1)
from [Link] import (
demographic_parity_difference,
equalized_odds_difference
# Convert probabilities to binary prediction
threshold = 0.5
y_pred_binary = (y_pred_prob >= threshold).astype(int)
# Demographic Parity
dp_gap = demographic_parity_difference(
y_true=y_test,
y_pred=y_pred_binary,
sensitive_features=sens_test
# Equalized Odds
eo_gap = equalized_odds_difference(
y_true=y_test,
y_pred=y_pred_binary,
sensitive_features=sens_test
print("Demographic Parity Difference:", dp_gap)
print("Equalized Odds Difference:", eo_gap)
# Preprocess test data separately
X_test_processed = [Link](X_train).transform(X_test)
explainer = [Link](pipe_xgb.named_steps['model'])
shap_values = explainer.shap_values(X_test_processed)
# Global Explanation
shap.summary_plot(shap_values, X_test_processed)
# Local Explanation (first applicant)
shap.force_plot(
explainer.expected_value,
shap_values[0,:],
X_test_processed[0,:]
def decision(prob, tau=0.5):
return "Approve" if prob < tau else "Reject"
print("Sample Decision:", decision(y_pred_prob[0]))
3. Methodology
3.1 Overview
We propose a hybrid ensemble credit risk prediction framework integrating Logistic
Regression, Random Forest, and XGBoost. To address class imbalance, SMOTE-based
resampling is incorporated within an imbalanced learning pipeline. The model is further
evaluated under fairness constraints using demographic parity and equalized odds metrics.
Explainability is ensured using SHAP-based global and local interpretations.
This study proposes a hybrid ensemble-based credit risk prediction framework integrating
machine learning, class imbalance handling, fairness assessment, and explainable artificial
intelligence (XAI). The methodology consists of six major stages:
1. Data preprocessing and feature transformation
2. Class imbalance mitigation using SMOTE
3. Hybrid ensemble model construction
4. Performance evaluation
5. Fairness assessment
6. Model explainability using SHAP
The overall architecture is designed to ensure predictive accuracy, robustness, fairness, and
interpretability in credit decision-making systems.
3.10 Summary of the Proposed Framework
The proposed methodology integrates:
Structured preprocessing
Imbalance-aware training
Hybrid ensemble learning
Fairness auditing
Explainable AI
Policy-driven decision threshold
This comprehensive pipeline ensures that the model is not only accurate but also fair,
transparent, and practically deployable in financial institutions.