End-to-End Machine Learning System β Binary Classification with CatBoost + FastAPI Backend + Streamlit Frontend
Financial institutions face significant risk from loan defaults, making accurate credit risk assessment critical for sustainable lending. This project builds an ML system that predicts whether a loan applicant will default β using 209 engineered features derived from 7 relational data source covering application details, credit bureau history, previous loans, and payment behavior.
The system is fully deployed via a FastAPI REST backend and an interactive Streamlit web dashboard, making it ready for real-world credit risk or operational integration.
- Problem Statement
- Dataset
- Project Architecture
- Notebooks & Modeling Workflow
- Model Pipeline Design
- API Reference
- Streamlit UI
- Tech Stack
- Project Structure
- Setup & Run
- Results Summary
- Key Learnings
Goal: Predict the probability of a loan applicant defaulting using administrative, financial, and behavioral features β collected at the time of application.
Why it matters:
- Enables proactive credit risk management and portfolio monitoring
- Helps lenders flag high-risk applicants early before approval
- Supports underwriting teams with data-driven default probability scores
- Provides actionable risk tier segmentation for loan operations
| Property | Detail |
|---|---|
| Primary File | application_train.csv |
| Records | ~300,000 loan applicants |
| Source Tables | 7 relational CSVs |
| Raw Features | 122 application features |
| Engineered Features | 209 total (192 numeric + 17 categorical) |
| Target | TARGET β 1 = Defaulted, 0 = Repaid |
| Class Imbalance | ~8% positive class (default) |
| Source | Home Credit Default Risk β Kaggle |
This project uses the Home Credit Default Risk dataset from Kaggle.
Download & place files as follows:
| File | Description |
|---|---|
application_train.csv |
Primary applicant data β demographics, financials, employment |
bureau.csv |
Credit bureau records from other institutions |
bureau_balance.csv |
Monthly balance history for bureau credits |
previous_application.csv |
Past Home Credit loan applications |
POS_CASH_balance.csv |
Monthly POS and cash loan balance snapshots |
installments_payments.csv |
Repayment history on previous Home Credit loans |
credit_card_balance.csv |
Monthly credit card balance and payment data |
7 Relational CSVs
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββ
β Exploratory Data Analysis β
β EDA and Model Evaluation.ipynb β
β β’ Class imbalance analysis β
β β’ Missing value heatmaps by group β
β β’ EXT_SOURCE distribution plots β
β β’ Feature importance (CatBoost) β
β β’ ROC-AUC, confusion matrix, PR curve β
βββββββββββββββ¬ββββββββββββββββββββββββββββ
β
βΌ
Feature Engineering
(train.py)
6 modular feature groups
209 engineered features
β
βΌ
CatBoost Classifier
ColumnTransformer Pipeline
Serialized artifacts β artifacts/
β
βΌ
app.py (FastAPI)
POST /predict
POST /predict_batch
β
βΌ
streamlit_app.py (Streamlit UI)
Contents:
- Dataset shape and class imbalance analysis (~8% default rate)
- Missing value heatmaps broken down by feature group
- EXT_SOURCE score distribution plots (key external credit signals)
- Feature importance charts from the trained CatBoost model
- ROC-AUC curve and confusion matrix on hold-out set
- Precision-Recall tradeoff analysis for threshold selection
Objective: Engineer 209 features from 7 tables, fit preprocessing, and train CatBoost with early stopping.
Feature engineering modules:
| Module | Key Signals |
|---|---|
| Application | Credit-to-income ratio, annuity ratio, EXT_SOURCE aggregates (mean/std/product), employment-to-age ratio, document count |
| Bureau Balance | Overdue status counts (DPD 1β5), overdue ratio, serious delinquency ratio |
| Bureau | Active/closed credit counts, debt-to-credit leverage, credit age, bureau overdue max/mean |
| Previous Applications | Approval/refusal rates, application-vs-credit diff, days since last decision |
| POS Cash | DPD flag rate, completed contract ratio, unique previous loan count |
| Credit Card | Credit utilisation (balance/limit), card DPD max/mean |
| Installments | Payment delay (days), late payment rate, payment-to-instalment ratio |
CatBoost configuration:
CatBoostClassifier(
iterations=2000,
learning_rate=0.03,
depth=5,
loss_function='Logloss',
eval_metric='AUC',
l2_leaf_reg=15,
random_seed=42,
early_stopping_rounds=100
)The production model is saved as a set of version-locked artifacts β input goes in raw, predictions come out. No separate preprocessing step at inference time.
Raw Input CSV
βββΊ LoanDefaultPredictor (predictor.py)
ββ Load feature_order.pkl β align columns
ββ Load preprocessor.pkl β ColumnTransformer
β ββ SimpleImputer β [numeric columns]
β ββ TargetEncoder β [categorical columns]
ββ Load model.cbm β CatBoost model
βββΊ default_probability (float, 0β1)
βββΊ prediction (0 or 1) + Risk Tier
Model: CatBoost Classifier Β· Tuned with Optuna (30 trials) Β· Threshold: 0.5
| Metric | Score |
|---|---|
| ROC-AUC Score | 0.7907 |
| Accuracy | 0.73 |
| Weighted F1-Score | 0.79 |
| Class | Precision | Recall | F1-Score | Support |
|---|---|---|---|---|
| 0 β No Default | 0.97 | 0.73 | 0.83 | 42,410 |
| 1 β Default | 0.19 | 0.71 | 0.29 | 3,717 |
| Weighted Avg | 0.90 | 0.73 | 0.79 | 46,127 |
βοΈ Note on class imbalance: The dataset is heavily imbalanced (~91% non-default). The model prioritizes high recall on defaults (0.71) to minimize missed risky loans, which is the critical objective in credit risk use cases.
P(Default) < 30% β β
Low Risk β Standard loan terms
P(Default) 30β60% β β οΈ Medium Risk β Additional verification
P(Default) > 60% β β High Risk β Manual review or decline
The FastAPI backend exposes prediction endpoints for both single and batch workflows.
Start the API:
uvicorn app:app --host 0.0.0.0 --port 8000Upload a CSV file of applicants β returns default probabilities and predictions.
Request:
curl -X POST http://localhost:8000/predict \
-F "file=@application_test.csv"Response:
[
{
"SK_ID_CURR": 100001,
"default_probability": 0.23,
"will_default": 0
},
{
"SK_ID_CURR": 100002,
"default_probability": 0.71,
"will_default": 1
}
]Alias for /predict for explicit batch workflow clarity.
Interactive Swagger docs available at: http://localhost:8000/docs
Start the UI (after the API is running):
streamlit run streamlit_app.pyFeatures:
- Landing state: Feature pipeline overview, model architecture, performance specs
- After upload: Portfolio summary metrics, three-tier risk segmentation cards
- Plotly donut chart of risk distribution + probability histogram with tier thresholds
- Cumulative default curve for portfolio analysis
- Scrollable predictions table with per-applicant risk labels
- CSV download of full prediction results
- Dark-themed UI with IBM Plex Sans typography
Label mappings displayed to user:
| Prediction | Label | Recommendation |
|---|---|---|
| 0 (P < 30%) | β Low Risk | Eligible for standard loan terms |
| 0/1 (P 30β60%) | Recommend additional verification | |
| 1 (P > 60%) | β High Risk | Flag for manual review or decline |
Landing Page β Model Overview

Prediction Page β Upload Overview

Risk Segmentation β Three-Tier Portfolio View

Risk Analytics β Donut Chart & Probability Distribution

| Layer | Technology |
|---|---|
| Data Processing | pandas, numpy |
| ML Model | catboost |
| Feature Encoding | TargetEncoder, SimpleImputer, ColumnTransformer |
| Model Serialization | joblib, .cbm (CatBoost native) |
| API Backend | FastAPI, uvicorn, python-multipart |
| Frontend | Streamlit, Plotly |
| EDA | matplotlib, seaborn |
home-credit-loan-default-predictor/
β
βββ π EDA and Model Evaluation.ipynb # EDA + model evaluation notebook
β
βββ π train.py # Feature engineering + training pipeline
βββ π predictor.py # LoanDefaultPredictor inference class
βββ π app.py # FastAPI REST API server
βββ π streamlit_app.py # Streamlit web dashboard
βββ π predict.py # CLI batch prediction script
β
βββ πΎ artifacts/
β βββ model.cbm # Serialized CatBoost model (~1.3 MB)
β βββ preprocessor.pkl # Fitted ColumnTransformer
β βββ feature_order.pkl # Ordered feature list for inference
β βββ metadata.json # Column lists, threshold, config
β
βββ π data/ # β οΈ CSVs not included (too large β download from Kaggle)
β βββ application_train.csv # ~300K rows, 122 features
β βββ bureau.csv # Credit bureau records
β βββ bureau_balance.csv # Bureau monthly balances
β βββ previous_application.csv # Past HC applications
β βββ POS_CASH_balance.csv # POS and cash loan snapshots
β βββ installments_payments.csv # Repayment history
β βββ credit_card_balance.csv # Credit card monthly data
β
βββ π requirements.txt # Python dependencies
βββ π Dataset Description.pdf # Official feature dictionary
βββ πΈ screenshots/ # UI screenshots for README
git clone https://github.com/ENGABHAY/home-credit-loan-default-predictor.git
cd home-credit-loan-default-predictorpython -m venv venv
venv\Scripts\activate # Windows
source venv/bin/activate # macOS/Linuxpip install -r requirements.txtDownload all 7 CSV files from the Home Credit Default Risk Kaggle competition and place them into the data/ folder:
data/
application_train.csv
bureau.csv
bureau_balance.csv
previous_application.csv
POS_CASH_balance.csv
installments_payments.csv
credit_card_balance.csv
python train.py
# Artifacts saved to: artifacts/uvicorn app:app --host 0.0.0.0 --port 8000
# API running at: http://localhost:8000
# Swagger UI at: http://localhost:8000/docsstreamlit run streamlit_app.py
# UI running at: http://localhost:8501python predict.py data/application_test.csv \
data/bureau.csv \
data/bureau_balance.csv \
data/previous_application.csv \
data/POS_CASH_balance.csv \
data/installments_payments.csv \
data/credit_card_balance.csv
# Outputs: predictions.csv
β οΈ The Streamlit dashboard calls the FastAPI backend athttp://127.0.0.1:8000β both must be running simultaneously.
| Model | Task | Algorithm | Key Config |
|---|---|---|---|
| Loan Default Classifier | Binary Default Prediction | CatBoost | 2000 iterations, lr=0.03, depth=5, L2=15, early stopping |
| Preprocessing Pipeline | Imputation + Encoding | ColumnTransformer | SimpleImputer + TargetEncoder, 209 features |
| Risk Segmentation | 3-Tier Portfolio Bucketing | Threshold-based | <30% Low, 30β60% Medium, >60% High |
The production model uses version-locked artifacts β zero data leakage, production-safe, single .predict() call at inference.
- Multi-table feature engineering across 7 relational sources is where most of the predictive signal lives β raw application features alone significantly underperform the full 209-feature set.
- CatBoost's native categorical handling eliminates the need for one-hot encoding on high-cardinality columns like
OCCUPATION_TYPEandORGANIZATION_TYPE, reducing preprocessing complexity. - Class imbalance (~8% default rate) is handled via automatic
scale_pos_weight-equivalent class weighting in CatBoost, preserving dataset integrity without resampling. - Artifact-first design (separate
model.cbm,preprocessor.pkl,feature_order.pkl,metadata.json) makes model versioning and A/B testing trivial β swap one file to compare iterations. - Separating the API layer (FastAPI) from the UI layer (Streamlit) makes the system modular β the API can serve any frontend, mobile app, or downstream risk system independently.
- EXT_SOURCE features (external credit scores) are consistently the top predictors β aggregating them as mean, std, and product captures more signal than using them individually.
- SHAP explanations β
pip install shapand callshap.TreeExplainer(model)for per-applicant feature attribution - Hyperparameter tuning β use
optunawithCatBoostClassifierfor AUC-optimised search - Threshold calibration β adjust the 0.5 default threshold via
predict(threshold=0.35)for higher recall - Docker deployment β wrap
app.pyin a Dockerfile for containerised API serving - Model versioning β swap
artifacts/model.cbmto compare model iterations without code changes
Pull requests are welcome. For major changes, please open an issue first to discuss what you'd like to change.
π License
This project is for educational and personal portfolio purposes.
