Bank Customer Churn Analysis
Classification, survival analysis, and a live risk predictor for bank customer retention
Project information
- Category: Data Science / Finance
- Dataset: Bank Customer Churn (~10,000 customers)
- Stack: Python, XGBoost, SHAP, lifelines, Plotly, Streamlit
- Link to github: GitHub repo →
- Interactive Dashboard: View dashboard →
- Live app: Open predictor in new tab →
Predicting and explaining customer churn
This project combines a classification model with survival analysis to answer two questions a retail bank actually needs answered: which customers are likely to churn, and when in their lifecycle is that risk highest. Three models (Logistic Regression, Random Forest, XGBoost) were compared, then explained with SHAP, and paired with a Cox Proportional Hazards model to translate risk into interpretable hazard ratios — the kind of dual approach an actuarial or risk team would expect.
Project deep dive
Problem statement
Customer acquisition costs far more than retention, but most churn models stop at "will this customer leave?" — which tells a bank who to worry about but not when to act or how much is actually at stake. This project was built to answer all three: who is likely to churn (classification), why — which factors actually drive the decision (SHAP + Cox hazard ratios), and when in the customer relationship the risk peaks (survival analysis), then translates that into a revenue-at-risk ranking a retention team can act on directly.
Dataset
Kaggle "Bank Customer Churn" dataset — 10,000 customers, 2,037 observed churn events (~20% churn rate).
- Features: CreditScore, Geography, Gender, Age, Tenure, Balance, NumOfProducts, HasCrCard, IsActiveMember, EstimatedSalary
- Target:
Exited(1 = churned, 0 = retained)
Methodology
- Exploratory analysis — churn rate broken down by geography, activity status, product count, and age. Germany shows a notably higher churn rate than France/Spain; inactive members and customers holding 3–4 products churn far more than average.
- Feature engineering — one-hot encoding for Geography, binary encoding for Gender, plus two engineered signals:
BalanceSalaryRatio(disengagement signal) andEngagementScore(activity + card ownership combined). - Classification — Logistic Regression, Random Forest, and XGBoost compared using AUC, precision/recall, and a confusion matrix rather than plain accuracy, since the target is imbalanced.
- Explainability — SHAP values on the XGBoost model to rank the true drivers of individual predictions, not just global feature importance.
- Survival analysis — Kaplan-Meier curves (overall and stratified by product count) plus a Cox Proportional Hazards model, using Tenure as duration and Exited as the event flag, to model when risk peaks rather than just whether it occurs.
- Business layer — churn probability weighted by each customer's balance to estimate revenue at risk, ranked into a prioritized retention list for the top 10% highest-risk customers.
Key findings
| Model | AUC | Recall (churn class) |
|---|---|---|
| Logistic Regression | baseline | — |
| Random Forest | — | — |
| XGBoost | 0.868 | 0.744 |
- Cox model (n=10,000, 2,037 events, concordance = 0.70): active members face a 54% lower churn hazard (HR 0.46); each additional year of age raises hazard by ~5%.
- The linear
NumOfProductsterm looked statistically insignificant on its own — but SHAP and Kaplan-Meier stratification both revealed a sharp, non-linear risk spike at 3–4 products. Binning it into a categorical flag recovered a significant effect, a methodological finding worth flagging in its own right.
Tech stack
Full notebook, priority retention list, and dashboard chart exports are in the GitHub repo →