Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

TelcoChurnML

End-to-end customer churn prediction system built on the IBM Telco dataset. Covers the full ML lifecycle: data preparation, multi-model experimentation tracked with MLflow, model registration, and a live REST inference API served with FastAPI.

Architecture

telco_churn.csv
      |
 data_prep.py        - cleaning, encoding, scaling, scaler persistence
      |
 train.py            - trains 5 models, logs all runs to MLflow Tracking
      |
 MLflow UI           - compare runs by AUC, F1, accuracy, recall
      |
 Model Registry      - best model promoted to @production alias
      |
 serve.py            - FastAPI loads @production model, exposes /predict
      |
POST /predict        - JSON in, churn probability + label out

Project Structure

TelcoChurnML/
|
+-- data/
|   +-- telco_churn.csv          # IBM Telco Customer Churn (Kaggle)
|
+-- src/
|   +-- data_prep.py             # preprocessing pipeline
|   +-- train.py                 # MLflow experiment runner
|   +-- serve.py                 # FastAPI inference server
|
+-- artifacts/
|   +-- scaler.pkl               # fitted StandardScaler (auto-generated)
|   +-- cm_*.png                 # confusion matrix per run (auto-generated)
|
+-- notebooks/
|   +-- 01_eda.ipynb             # exploratory data analysis
|
+-- mlruns/                      # MLflow tracking store (auto-generated)
+-- requirements.txt
+-- README.md

Dataset

IBM Telco Customer Churn - Kaggle

  • 7,043 customers, 21 features
  • Target: Churn (Yes/No) - 26.5% positive rate (class imbalance handled)
  • Features include tenure, contract type, payment method, internet service, monthly charges

Models Trained

Model AUC F1 Accuracy Recall
Random Forest (200) 0.865 0.660 0.793 0.759
Logistic Regression 0.862 0.638 0.751 0.828
XGBoost (100) 0.855 0.634 0.757 0.796
XGBoost (200) 0.854 0.638 0.759 0.802
Random Forest (100) 0.845 0.537 0.793 0.453

Winner: Random Forest (200) - highest AUC at 0.865, strong recall of 0.759 (catches 76% of actual churners). Registered as TelcoChurnModel@production in MLflow Model Registry.

Class imbalance handling:

  • Logistic Regression + Random Forest: class_weight="balanced"
  • XGBoost: scale_pos_weight=3 (ratio of negative/positive class)

Confusion Matrix - Random Forest (200)

                 Predicted
                 Not Churn   Churn
Actual Not Churn    834       202
       Churn         90       283
  • True Positives (caught churners): 283
  • False Negatives (missed churners): 90
  • False Positives (wrong churn flags): 202

Setup

1. Clone the repo

git clone https://github.com/hamzapiracha/TelcoChurnML.git
cd TelcoChurnML

2. Create virtual environment

python -m venv venv
venv\Scripts\activate        # Windows
source venv/bin/activate     # Mac/Linux

3. Install dependencies

pip install -r requirements.txt

4. Add dataset

Download telco_churn.csv from Kaggle and place it in data/.

Running the Pipeline

Step 1 - Train all models and log to MLflow

python src/train.py

Step 2 - Open MLflow UI to compare runs

mlflow ui
# Open http://localhost:5000
# Sort by AUC descending to identify best model
# Register best model as TelcoChurnModel with alias @production

Step 3 - Start inference server

Open a second terminal (keep MLflow UI running in the first):

python src/serve.py
# Server starts at http://localhost:8000

API Reference

POST /predict

Accepts customer features as JSON, returns churn probability and label.

Request body:

{
  "gender": 1,
  "SeniorCitizen": 0,
  "Partner": 0,
  "Dependents": 0,
  "tenure": 2,
  "PhoneService": 1,
  "MultipleLines": 0,
  "OnlineSecurity": 0,
  "OnlineBackup": 0,
  "DeviceProtection": 0,
  "TechSupport": 0,
  "StreamingTV": 0,
  "StreamingMovies": 0,
  "PaperlessBilling": 1,
  "MonthlyCharges": 70.0,
  "TotalCharges": 140.0,
  "InternetService_Fiber_optic": 1,
  "InternetService_No": 0,
  "Contract_One_year": 0,
  "Contract_Two_year": 0,
  "PaymentMethod_Credit_card_automatic": 0,
  "PaymentMethod_Electronic_check": 1,
  "PaymentMethod_Mailed_check": 0
}

Response:

{
  "churn_probability": 0.828,
  "prediction": "Churn",
  "confidence": "82.8%"
}

Field encoding:

Field Encoding
gender 1 = Male, 0 = Female
SeniorCitizen 1 = Yes, 0 = No
All binary service fields 1 = Yes, 0 = No / No service
InternetService_Fiber_optic 1 if Fiber optic, else 0
InternetService_No 1 if No internet, else 0
Contract_One_year 1 if one-year contract, else 0
Contract_Two_year 1 if two-year contract, else 0
PaymentMethod_* 1 if that payment method, else 0

GET /health

curl http://localhost:8000/health
{
  "status": "ok",
  "model_loaded": true
}

requirements.txt

mlflow
fastapi
uvicorn
scikit-learn
xgboost
pandas
numpy
matplotlib
seaborn
pydantic

Screenshots

Add the following screenshots to a screenshots/ folder and link them here:

  • MLflow runs table sorted by AUC
  • Random Forest (200) confusion matrix
  • Model Registry showing TelcoChurnModel@production
  • curl /predict response in terminal

Key Engineering Decisions

Why stratified train/test split? With 26.5% churn rate, a random split risks imbalanced evaluation sets. stratify=y preserves the ratio in both splits — churn rate is 0.266 in train and 0.265 in test.

Why load the model once at startup? Loading from MLflow Registry takes ~1-2 seconds. Loading on every request would make the API unusable under any real traffic. FastAPI's startup event loads both model and scaler into memory once — all requests share the same in-memory objects.

Why alias over stage in MLflow 3.x? MLflow 3.12 deprecated the Staging/Production stage system. The @production alias is the current recommended pattern for marking a model version as live. Load path: models:/TelcoChurnModel@production.

Author

Mohammad Hamza Piracha | Data Scientist & Applied AI Engineer | LinkedIn | hamzapiracha@live.com

About

End-to-end churn prediction - MLflow experiment tracking, model registry, and FastAPI inference API | scikit-learn · XGBoost · Python

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages