Author: Jamiu Olamilekan Badmus
Email: jamiubadmus001@gmail.com
LinkedIn: Jamiu Olamilekan Badmus
GitHub: jamiubadmusng
Website: sites.google.com/view/jamiu-olamilekan-badmus
This project develops a machine learning model to assess credit risk and predict loan defaults. Using the German Credit dataset, we build classification models that help financial institutions make informed lending decisions while managing risk exposure.
Key Results:
- Built and evaluated 6 classification models on 1,000 credit applicants
- Engineered risk-based features from 20 applicant attributes
- Implemented cost-sensitive classification for business optimization
- Achieved strong predictive performance with interpretable SHAP analysis
- Problem Statement
- Data Source
- Project Structure
- Installation
- Usage
- Methodology
- Results
- Key Findings
- Business Recommendations
- Future Work
Credit risk assessment is fundamental to banking operations:
- $1.5 trillion in consumer loans are issued annually in the US
- Default rates of 2-5% can significantly impact profitability
- Regulatory requirements (Basel III) mandate robust risk assessment
- Automated scoring enables faster, more consistent decisions
This project addresses: How can we predict which loan applicants are likely to default, enabling risk-adjusted lending decisions?
In credit risk, different types of errors have asymmetric costs:
- False Negative (approving a defaulter): Loss of principal + interest
- False Positive (rejecting a good customer): Lost profit opportunity
Typically, the cost of a missed default is 5x the cost of a lost opportunity.
The dataset is the German Credit Dataset from the UCI Machine Learning Repository.
| Attribute | Value |
|---|---|
| Source | UCI ML Repository |
| Observations | 1,000 credit applicants |
| Features | 20 (7 numerical, 13 categorical) |
| Target | Good Credit (70%) / Bad Credit (30%) |
| Time Period | Historical German bank data |
| Feature | Description |
|---|---|
| checking_status | Status of existing checking account |
| duration | Loan duration in months |
| credit_history | Past credit behavior |
| purpose | Purpose of the loan |
| credit_amount | Loan amount requested |
| savings_status | Savings account balance |
| employment | Present employment duration |
| age | Age of applicant |
| housing | Housing situation (rent/own) |
| job | Job type and skill level |
finance/
├── data/
│ ├── raw/ # Original dataset
│ │ └── german_credit.data
│ └── processed/ # Feature-engineered data
│ └── german_credit_processed.csv
├── docs/
│ ├── analysis_report.md # Detailed analysis write-up
│ └── figures/ # Visualization outputs
│ ├── target_distribution.png
│ ├── numerical_distributions.png
│ ├── categorical_default_rates.png
│ ├── correlation_matrix.png
│ ├── model_comparison.png
│ ├── confusion_matrix.png
│ ├── roc_pr_curves.png
│ ├── threshold_optimization.png
│ ├── shap_importance.png
│ ├── shap_beeswarm.png
│ └── risk_distribution.png
├── models/ # Trained model artifacts
│ ├── credit_risk_model.joblib
│ └── preprocessor.joblib
├── notebooks/
│ └── credit_risk_assessment.ipynb # Main analysis notebook
├── src/
│ └── predict_risk.py # Standalone Python module
├── README.md # This file
├── requirements.txt # Python dependencies
├── LICENSE # MIT License
└── .gitignore # Git ignore file
- Python 3.8 or higher
- pip package manager
-
Clone the repository:
git clone https://github.com/jamiubadmusng/credit-risk-assessment.git cd credit-risk-assessment -
Create and activate a virtual environment:
python -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
-
Install dependencies:
pip install -r requirements.txt
cd notebooks
jupyter notebook credit_risk_assessment.ipynbimport joblib
import pandas as pd
# Load model and preprocessor
model = joblib.load('models/credit_risk_model.joblib')
preprocessor = joblib.load('models/preprocessor.joblib')
# Prepare applicant data
applicant = pd.DataFrame({
'checking_status': ['A11'],
'duration': [24],
'credit_history': ['A32'],
# ... other features
})
# Preprocess and predict
X_processed = preprocessor.transform(applicant)
default_probability = model.predict_proba(X_processed)[:, 1]
print(f"Default Probability: {default_probability[0]:.2%}")- Decoded categorical variables for interpretability
- Converted target variable (1=Good → 0, 2=Bad → 1)
- Created derived features (credit-to-income ratio, monthly payment)
Numerical Features:
- Duration, credit amount, installment rate
- Age, residence duration, existing credits
Categorical Features:
- Checking account status, credit history
- Employment, housing, job type
Derived Features:
- Credit-to-income ratio
- Monthly payment estimate
- Stability indicators (employment, housing)
- 6 classification algorithms evaluated
- 5-fold stratified cross-validation
- 80/20 train-test split
- Implemented asymmetric cost matrix
- Optimized classification threshold
- Balanced precision-recall for business needs
| Model | CV ROC-AUC | Test ROC-AUC | Test F1 |
|---|---|---|---|
| Logistic Regression | 0.7682 | 0.8043 | 0.6055 |
| Random Forest | 0.7831 | 0.8037 | 0.5263 |
| LightGBM | 0.7900 | 0.7793 | 0.5766 |
| Gradient Boosting | 0.7767 | 0.7835 | 0.5636 |
| XGBoost | 0.7664 | 0.7512 | 0.5546 |
| Decision Tree | 0.6753 | 0.7090 | 0.4348 |
Best Model: Logistic Regression with Test ROC-AUC of 80.43%
- Default threshold (0.5): Total Cost = 151
- Optimal threshold (0.30): Total Cost = 93
- Cost reduction: 38.4%
| Threshold | FP | FN | Recall | Total Cost |
|---|---|---|---|---|
| Default (0.50) | 16 | 27 | 55.0% | 151 |
| Optimal (0.30) | 38 | 11 | 81.7% | 93 |
Applicants without a checking account or with low balance show significantly higher default rates. This is the strongest single predictor.
Longer loan durations correlate with higher default risk. Short-term loans (< 12 months) have lower default rates.
Past payment behavior strongly predicts future defaults. Critical accounts have 2-3x higher default rates.
Optimizing the classification threshold for business costs reduces total expected loss.
| Risk Level | Probability | Actual Default Rate | Action |
|---|---|---|---|
| Very Low | < 20% | 11.0% | Auto-approve |
| Low | 20-40% | 17.1% | Standard approval |
| Medium | 40-60% | 54.5% | Enhanced review |
| High | 60-80% | 70.8% | Decline or collateral |
| Very High | > 80% | 72.7% | Decline |
- Immediate: Deploy model for new application scoring
- Short-term: Implement tiered interest rates by risk category
- Long-term: Integrate with loan management system
- Alternative Data: Incorporate transaction history, social data
- Model Monitoring: Implement drift detection and retraining
- Fairness Analysis: Audit for demographic bias
- Deep Learning: Explore neural networks for complex patterns
- UCI Machine Learning Repository - German Credit Dataset
- Basel Committee on Banking Supervision - Basel III Framework
- Lundberg, S. M., & Lee, S. I. (2017). A Unified Approach to Interpreting Model Predictions
This project is licensed under the MIT License - see the LICENSE file for details.
For questions or collaboration opportunities:
- Email: jamiubadmus001@gmail.com
- LinkedIn: Jamiu Olamilekan Badmus
- GitHub: jamiubadmusng
- Website: sites.google.com/view/jamiu-olamilekan-badmus