Predict annual medical insurance charges from demographic and health features. Exposes a production-ready FastAPI service with ensemble ML models (Decision Tree, Random Forest, Ridge Regression), input validation, KS-test drift monitoring, and a full test suite.
# 1. Clone
git clone https://github.com/atharvadevne123/Medical-Insurance-Cost-Prediction
cd Medical-Insurance-Cost-Prediction
# 2. Install
make install
# 3. Run API server
make run
# → http://localhost:8000/docs
# 4. Or with Docker
make docker-upcurl -X POST http://localhost:8000/predict \
-H "Content-Type: application/json" \
-d '{"age":35,"sex":"male","bmi":27.5,"children":2,"smoker":"no","region":"northeast"}'
# → {"predicted_charge": 6420.18, "model_version": "v1-decision-tree"}| Column | Type | Description |
|---|---|---|
age |
int | Age of primary beneficiary (0–120) |
sex |
categorical | male / female |
bmi |
float | Body Mass Index (0–100) |
children |
int | Number of dependents (0–20) |
smoker |
categorical | yes / no |
region |
categorical | northeast / northwest / southeast / southwest |
charges |
float | Target — annual insurance cost (USD) |
Source: insurance_predictor/data/insurance.csv (1,338 rows, no missing values).
Medical-Insurance-Cost-Prediction/
├── app/
│ ├── main.py # FastAPI application (lifespan, endpoints, middleware)
│ ├── schemas.py # Pydantic request/response models
│ ├── models.py # Ensemble: DecisionTree, RandomForest, Ridge
│ ├── monitoring.py # KS-test drift detection (DriftMonitor)
│ └── persistence.py # joblib save/load helpers
├── insurance_predictor/
│ ├── predictor.py # Core: load_data, preprocess, train, predict, run
│ └── data/insurance.csv
├── tests/ # pytest test suite (9 modules, 80+ tests)
├── scripts/
│ └── train_pipeline.py # CLI: train all models, save best
├── Dockerfile
├── docker-compose.yml
├── Makefile
└── requirements.txt
Request flow: POST /predict → Pydantic validation → preprocess() → trained model → response.
Returns service health and whether the model is loaded.
{"status": "healthy", "model_loaded": true, "version": "1.0.0"}Returns model performance from the last training run.
{"train_mae": 1823.4, "test_mae": 2541.7, "test_rmse": 4312.5, "test_r2": 0.857, "model_version": "v1-decision-tree"}Returns API and Python version info.
Predict insurance charge for one individual.
Request body:
{
"age": 35, "sex": "male", "bmi": 27.5,
"children": 2, "smoker": "no", "region": "northeast"
}Response:
{"predicted_charge": 6420.18, "model_version": "v1-decision-tree"}Predict for up to 1000 individuals.
{"records": [{"age": 25, "sex": "female", "bmi": 22.0, "children": 0, "smoker": "no", "region": "southwest"}]}- Load —
insurance_predictor.predictor.load_data()validates schema and raisesFileNotFoundError/ValueErroron bad input. - Preprocess —
StandardScaleron continuous features, one-hot encoding on categorical features. - Train — Three models evaluated; best by test MAE is served.
- Monitor —
DriftMonitorcompares incoming feature distributions to training baseline using the two-sample KS test.
make test
# Or:
PYTHONPATH=. pytest tests/ -v| Test module | What it covers |
|---|---|
test_data_loading.py |
Schema, nulls, value ranges |
test_preprocessing.py |
Encoding, scaling, shape preservation |
test_training.py |
Metrics, reproducibility, hyperparameters |
test_prediction.py |
Array shape, positivity, batch sizes |
test_api.py |
All endpoints, validation rejection |
test_models.py |
Ensemble model comparison |
test_monitoring.py |
KS drift detection |
test_persistence.py |
Save/load/roundtrip |
See CONTRIBUTING.md. Run make lint and make test before opening a PR.
Atharva Devne