A machine learning model served as a production-style REST API. Predicts the probability that a telecom customer will churn, based on account and service usage features — fully containerized with Docker and ready to deploy.
This project focuses on the deployment side of ML: a trained model is only useful if something can actually call it. Here, the model is wrapped in FastAPI with input validation, a health check endpoint, and a Dockerfile so any team's infrastructure can run it as-is.
Telecom companies lose significant revenue to customer churn. Identifying at-risk customers early lets retention teams intervene (discounts, outreach, plan changes) before the customer leaves. This project trains a classifier on historical account data and exposes it as an API that a CRM or marketing system could call in real time.
Dataset: Telco Customer Churn — Kaggle (~7,000 customers)
Client (curl / app / CRM)
│
▼
FastAPI /predict
│
▼
Pydantic validation ──► Preprocessor (scaling + one-hot encoding) ──► XGBoost model
│
▼
JSON response (prediction, probability, risk level)
churn-prediction-api/
├── src/
│ ├── data/
│ │ ├── preprocess.py # Cleaning + feature engineering
│ │ └── encode.py # Scaling, one-hot encoding, train/test split
│ └── models/
│ └── train.py # Logistic Regression baseline + XGBoost
├── api/
│ ├── main.py # FastAPI app: /, /health, /predict
│ └── schemas.py # Pydantic request/response models
├── tests/
│ ├── test_preprocess.py
│ └── test_api.py # API endpoint tests with mocked model
├── outputs/
│ └── models/ # Saved model + preprocessor artifacts
├── Dockerfile
├── docker-compose.yml
└── requirements.txt
git clone https://github.com/armanesh/churn-prediction-api.git
cd churn-prediction-api
pip install -r requirements.txt
pip install -e .Get the data:
- Download
WA_Fn-UseC_-Telco-Customer-Churn.csvfrom Kaggle - Save it as
data/raw/telco_churn.csv
Train the model:
python -m src.models.trainThis saves churn_xgboost.joblib and preprocessor.joblib to outputs/models/.
uvicorn api.main:app --reloaddocker build -t churn-api .
docker run -p 8000:8000 churn-apidocker-compose up --buildOnce running, open http://localhost:8000/docs for interactive Swagger documentation.
curl -X POST "http://localhost:8000/predict" \
-H "Content-Type: application/json" \
-d '{
"tenure": 12,
"MonthlyCharges": 70.5,
"TotalCharges": 846.0,
"gender": "Female",
"SeniorCitizen": 0,
"Partner": "Yes",
"Dependents": "No",
"PhoneService": "Yes",
"MultipleLines": "No",
"InternetService": "Fiber optic",
"OnlineSecurity": "No",
"OnlineBackup": "Yes",
"DeviceProtection": "No",
"TechSupport": "No",
"StreamingTV": "Yes",
"StreamingMovies": "No",
"Contract": "Month-to-month",
"PaperlessBilling": "Yes",
"PaymentMethod": "Electronic check"
}'Response:
{
"churn_prediction": "Yes",
"churn_probability": 0.7234,
"risk_level": "High"
}pytest tests/ -vAPI tests mock the model and preprocessor so the full test suite runs without requiring trained artifacts — useful for CI pipelines.
FastAPI over Flask: Built-in request validation via Pydantic, automatic OpenAPI/Swagger docs, and async support out of the box — the current standard for ML model serving in Python.
Model loaded once at startup, not per-request: Using FastAPI's lifespan context manager, the model and preprocessor are loaded into memory a single time when the API starts, rather than on every /predict call. This is critical for latency in production.
Class imbalance handling: Churn datasets are typically imbalanced (~73% retained vs ~27% churned here). Handled via scale_pos_weight in XGBoost rather than naive resampling, which avoids duplicated or discarded data.
Separation of model training and serving: Training (src/) and serving (api/) are fully decoupled. The API only loads pre-trained artifacts — it never trains a model itself, which mirrors how real ML systems separate batch training pipelines from low-latency inference services.
Containerization: The Dockerfile builds a self-contained image with the model artifacts baked in, so the API can be deployed to any container orchestration platform (Kubernetes, ECS, Cloud Run) without environment drift.
Ali Rahbarimanesh — Data Scientist & AI Engineer LinkedIn · GitHub