Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Loan Approval Predictor

A machine-learning credit-decisioning project that predicts whether a loan application should be approved, with a feature set and evaluation approach designed around affordability checks used in microfinance and cooperative lending (the kind of underwriting a SACCO, Ajo/Esusu group, or microfinance institution does manually) rather than a generic Kaggle notebook.

The goal isn't just "get a good F1 score" - it's to build a small, honest, end-to-end credit-risk pipeline: clean data → engineered affordability features → multiple models compared fairly → the winner tuned and explained → shipped behind a CLI and a small interactive app.

Live demo · Results · Why these features


Why this project

Across many African markets, formal credit-history data is thin, but informal and cooperative savings/lending groups (Ajo, Esusu, Chama, SACCOs) have been assessing creditworthiness for generations using a handful of simple, explainable signals: can this person actually afford the repayment, given their income and existing obligations? This project takes a classic loan-approval dataset and rebuilds the pipeline around that lens - explicit affordability features (EMI burden, balance income after repayment, income-to-loan ratio) instead of throwing raw income/loan columns at a model and hoping for the best.

Problem Statement

Given an applicant's demographic and financial profile, predict whether Dream Housing Finance approves the loan (Loan_Status = Y/N).

Dataset

  • Source: Loan Prediction Problem Dataset (Analytics Vidhya / Kaggle, public domain for ML practice)
  • Samples: 614 applications - 422 approved (68.7%), 192 denied (31.3%)
  • Raw features: 11 inputs (demographic + financial) + 1 target
  • Missingness: 7 of 12 raw columns have missing values (Credit_History alone is missing for 50 rows)
Feature Description
Gender, Married, Dependents Household demographics
Education, Self_Employed Employment profile
ApplicantIncome, CoapplicantIncome Monthly income streams
LoanAmount, Loan_Amount_Term Requested loan (thousands) and term (months)
Credit_History 1 = clean, 0 = adverse/no history
Property_Area Urban / Semiurban / Rural
Loan_Status Target: Y (approved) / N (denied)

Feature Engineering

On top of cleaning (mode/median imputation, Dependents string→int, an explicit Credit_History_Missing flag since a missing credit history is itself a signal - a first-time or informal-sector borrower with no prior formal credit trail), this project adds affordability features that mirror manual loan-committee checks:

Engineered feature What it represents
TotalIncome Household income (applicant + co-applicant)
EMI Estimated monthly repayment (LoanAmount / Term)
BalanceIncome Income left over after the EMI - the real affordability signal
IncomeToLoanRatio How large the loan is relative to income
LogTotalIncome, LogLoanAmount Log-transforms to tame right-skew
HasCoapplicant Whether a co-applicant shares repayment responsibility

Results

Seven baseline classifiers were trained on an 80/20 stratified split, then the best baseline was tuned with 5-fold GridSearchCV (scoring = F1). All numbers below are from an actual run of src/train.py on this repo's code - not copied from elsewhere.

Model Accuracy Precision Recall F1 ROC-AUC
Random Forest 0.8862 0.8989 0.9412 0.9195 0.8475
Logistic Regression 0.8618 0.8400 0.9882 0.9081 0.8508
SVM (RBF) 0.8537 0.8317 0.9882 0.9032 0.8517
Naive Bayes 0.8455 0.8367 0.9647 0.8962 0.8387
KNN (K=7) 0.8293 0.8200 0.9647 0.8865 0.7364
Gradient Boosting 0.8293 0.8478 0.9176 0.8814 0.8207
Decision Tree 0.7154 0.8205 0.7529 0.7853 0.6923
Random Forest (Tuned, deployed) 0.8618 0.8469 0.9765 0.9071 0.8635

Why the tuned model is deployed even though it isn't the single highest F1 on this test split: GridSearchCV selects parameters by cross-validated F1 on the training folds, not by test-set F1 - that's the honest way to tune without leaking test data. The tuned Random Forest (max_depth=4, n_estimators=200) trades a hair of test-set F1 for a better ROC-AUC and a shallower, less overfit tree, which generalizes better in practice. Both numbers are reported here deliberately, instead of only showing the flattering one.

Key Findings

  • Credit_History dominates (44% of Random Forest's feature importance on its own): ~79.6% approval rate when clean vs. ~7.9% when adverse. This matches how loan committees actually behave - almost everything else is a tiebreaker.
  • IncomeToLoanRatio and BalanceIncome (engineered, not raw) rank second and third in importance - evidence that the affordability framing adds real signal beyond the raw income/loan columns.
  • Semiurban applicants have the highest approval rate (76.8%) - higher than Urban (65.8%) or Rural (61.5%), likely reflecting a lender sweet spot between rural income volatility and urban competition/risk.
  • Raw income is only mildly predictive on its own - approved applicants' raw incomes aren't meaningfully higher than denied applicants', which is exactly why BalanceIncome (income after obligations) and IncomeToLoanRatio are more informative than income alone.

Explainability

src/explain.py generates a feature-importance chart (models/feature_importance.png) so every prediction can be traced back to why - critical for any credit-decisioning tool that affects real people's access to a loan.

Project Structure

loan-approval-predictor/
├── app.py                     # Streamlit demo app
├── data/
│   └── loan.csv                # Raw dataset (614 rows)
├── models/                     # Generated: trained pipeline, results, chart
├── notebooks/
│   └── 01_eda.ipynb             # Exploratory data analysis
├── src/
│   ├── data_prep.py             # Cleaning + feature engineering
│   ├── train.py                 # Model comparison, tuning, persistence
│   ├── predict.py               # CLI single-applicant inference
│   └── explain.py               # Feature importance chart
├── tests/
│   └── test_pipeline.py         # Unit tests (data prep + pipeline shape)
├── .github/workflows/ci.yml    # CI: tests + training smoke test on every push
├── requirements.txt
├── LICENSE
└── README.md

Quickstart

git clone https://github.com/<your-username>/loan-approval-predictor.git
cd loan-approval-predictor
pip install -r requirements.txt

# Train the model (reproduces the results table above)
python -m src.train

# Generate the explainability chart
python -m src.explain

# Predict for a single applicant via CLI
python -m src.predict --applicant_income 4500 --coapplicant_income 1500 \
    --loan_amount 120 --credit_history 1 --property_area Semiurban \
    --married Yes --dependents 1

# Run the interactive demo app
streamlit run app.py

Run the test suite:

pytest tests/ -v

Tech Stack

pandas, numpy, scikit-learn, matplotlib/seaborn, joblib, Streamlit, pytest, GitHub Actions.

Limitations & Future Work

  • Trained on a small (614-row), single-lender, home-loan dataset - not production-ready credit scoring, and not validated for fairness/bias across protected attributes (an important next step before any real deployment, especially given Gender and Married are in the feature set).
  • Next steps: SHAP-based per-prediction explanations (not just global feature importance), fairness auditing across demographic slices, and a synthetic extension modeling group-liability cooperative loans (where a member's repayment is influenced by their savings group's track record) - a closer analogue to Ajo/Esusu/SACCO-style lending than an individual home loan.

Credits

Dataset: Dream Housing Finance / Analytics Vidhya loan prediction problem (public, via Kaggle). Project structure was originally inspired by the Beginner-Data-Science-Projects collection by Taimour Karim (MIT licensed); this repository's feature engineering, model pipeline, explainability tooling, CLI, app, tests, and CI are an original build on top of that starting point.

License

MIT - see LICENSE.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages