This repository provides a complete end-to-end heart disease prediction system, covering everything from data preprocessing, model training, hyperparameter tuning, and performance evaluation to inference pipeline scripting with production-ready design. It now also includes a browser-based interface so non-technical stakeholders can explore the model safely.
The system is built using Python and scikit-learn, with support for logging, modular structure, error handling, model persistence, and integration points for Airflow or any production-grade orchestration tool. The project was initially developed in a Jupyter notebook and has since been refactored into reusable, maintainable code components.
- Decision Tree (with entropy/gini, pruning, and GridSearchCV tuning)
- Neural Network (MLPClassifier) (tuned with grid search on hidden layers and learning rate)
- AdaBoost (with SAMME/SAMME.R, learning rate tuning, and ensemble optimization)
- Support Vector Machine (SVM) (with kernel, gamma, and regularization tuning)
- K-Nearest Neighbors (KNN) (with distance algorithm, leaf size, and K optimization)
Each model underwent:
- Baseline training
- Hyperparameter tuning via
GridSearchCV - Training/validation/test evaluation
- Learning curves & loss curve analysis
- Final selection based on bias-variance trade-off, AUC-ROC, time complexity, and domain risk (favoring lower false negatives due to the medical domain)
The pipeline includes:
- Preprocessing Steps identical to training pipeline:
- Duplicate removal
- One-hot encoding
- Feature alignment with training schema
- Normalization with MinMaxScaler
- Model Loading from
.joblibfiles - Prediction & Accuracy Scoring
- Logging & Error Handling with
loggingmodule - Runtime Arguments for switching between
svmandadaboostinference modes
Run the inference using:
python main.py --model adaboost
python main.py --model svmThe inference data is expected at Data/inference_heart_disease.csv. This can be swapped with live-streaming data via get_inference_data() in utils.py.
To make experimentation easier the repository now bundles a small Flask application that wraps the AdaBoost model behind a responsive form. The interface exposes the full set of input features expected by the model and includes a visible disclaimer reminding users that the tool is for education only.
The repository now ships with pinned dependencies, a pyproject.toml, and a Makefile to simplify local bootstrap and CI/CD pipelines.
python -m venv .venv
source .venv/bin/activate
make install
make devThe development server runs at http://localhost:8000. Submit the form to trigger a prediction. The result banner communicates whether the model considers the inputs high or low risk and, when available, reports the model's confidence in the prediction.
The web layer loads settings from environment variables prefixed with HD_ (also read from a local .env file):
| Variable | Purpose | Default |
|---|---|---|
HD_MODEL_URI |
Model artefact file or directory to load | model1_adaboost.joblib |
HD_MODEL_CHECKSUM |
Optional SHA-256 checksum to verify the artefact before serving | unset |
HD_DATA_PATH |
Path to the training CSV used for optional MinMax scaling | Data/heart.csv |
HD_LOG_LEVEL |
Structured log verbosity (DEBUG, INFO, etc.) |
INFO |
HD_ENABLE_METRICS |
Expose Prometheus metrics on /metrics |
true |
HD_DISCLAIMER |
Override the UI/API disclaimer text | Educational disclaimer |
HD_PORT |
Port for the Flask app when run via app.py |
8000 |
HD_DEBUG |
Enable Flask debug mode in local development | false |
HD_MODEL_FILENAME |
Model artefact to load | model1_adaboost.joblib |
HD_MODEL_SHA256 |
Optional SHA-256 checksum to verify the artefact before serving | unset |
HD_DATA_DIRECTORY |
Directory containing the training CSV used for preprocessing | Data/ |
HD_LOG_LEVEL |
Structured log verbosity (DEBUG, INFO, etc.) |
INFO |
HD_ENABLE_METRICS |
Expose Prometheus metrics on /metrics |
true |
HD_DISCLAIMER |
Override the UI/API disclaimer text | Educational disclaimer |
POST /api/predict: accepts JSON matching theHeartDiseaseFeaturesschema and returns a structured response with prediction label, probability (if supported by the model), and the disclaimer text.GET /healthz: liveness probe.GET /readyz: readiness probe ensuring the model has been loaded successfully.GET /metrics: Prometheus metrics with request counters, latencies, and prediction totals.
Example request:
curl -X POST http://localhost:8000/api/predict \
-H "Content-Type: application/json" \
-d '{
"age": 57,
"sex": 1,
"chest_pain_type": 2,
"resting_bp": 130,
"cholestoral": 236,
"fasting_blood_sugar": 0,
"restecg": 0,
"max_hr": 174,
"exang": 0,
"oldpeak": 0.0,
"slope": 1,
"num_major_vessels": 1,
"thal": 2
}'The HTML form reuses the same validation layer (Pydantic) as the JSON API, ensuring parity across channels.
The container image is ready for gunicorn-based hosting:
make docker-build
make docker-runThis runs gunicorn --workers 2 --threads 2 Heart-Disease_Classification_Inference.webapp.app:app inside a slim Python image. Tune worker/thread counts based on CPU availability.
For cloud hosting:
- Upload the built image to your container registry (GHCR/ECR/GCR).
- Provide the
Data/heart.csvfile and chosen model artefact via the image or mounted volume. - Configure the
HD_environment variables and any platform-specific secrets. - Point your ingress/ALB at port
8000and terminate TLS at the edge.
The UI ships with a visible disclaimer, but add your own terms of use and privacy policy before exposing the service publicly.
Basic unit tests are included inside the unit_test/ folder to validate:
- Data fetching logic
- Preprocessing alignment
- Dimension checks
- Model I/O
.
├── constants.py # Configuration constants
├── Data/ # Training and inference data files
├── Heart Disease Classification.ipynb # Initial notebook for training & EDA
├── Heart Disease Inference.py # Notebook for inference (converted to script)
├── main.py # Entry point for running inference pipeline
├── model1_adaboost.joblib # Saved AdaBoost model
├── model2_svm.joblib # Saved SVM model
├── utils.py # All reusable utility functions
├── unit_test/ # Unit tests for inference components
├── inference_pipe_exec.log # Logging output file
├── webapp/ # Flask web application (UI + routes)
└── __pycache__/ # Compiled Python cache
- Source: UCI ML Repository - Heart Disease Dataset
- Contains 303 records with 13 attributes
- Features are a mix of categorical and continuous
- Final target: binary classification (
0: no heart disease,1: heart disease)
| Model | Test Accuracy | AUC-ROC | Overfitting | Comments |
|---|---|---|---|---|
| Decision Tree | ~0.84 | Low | Moderate | Simple but underperforming |
| Neural Network | ~0.90 | Good | Slight | Some instability, slight bias |
| AdaBoost | ~0.96 | High | None | ✅ Best performance, generalizes well |
| SVM | ~0.97 | High | None | ✅ Best accuracy, reliable |
| KNN | ~0.89 | Moderate | Slight | Biased, underfit |
🔬 Medical Context: False Negatives are more dangerous. Preference is given to models with fewer FNs (AdaBoost, SVM).
- ✅ Notebook-to-script conversion
- ✅ Modularized code structure (preprocessing, inference, I/O)
- ✅ Trained models persisted via
joblib - ✅ Logging using Python's
loggingmodule - ✅ Robust error handling
- ✅ CLI integration for easy model selection
- ✅ Inference data schema alignment
- ✅ Unit testing support
- ✅ Ready for orchestration with Airflow, Prefect, or cron
This project is fully ready for deployment as a scheduled inference pipeline. You can easily:
- Deploy
main.pyas a DAG in Apache Airflow - Containerize it with Docker
- Schedule inference against live data from an API or database
- Integrate with notification systems on prediction confidence or anomalies
Original dataset compiled by:
- Andras Janosi, William Steinbrunn, Matthias Pfisterer, Robert Detrano
Donated by: - David W. Aha (aha '@' ics.uci.edu)
This project is open for educational and research purposes. Commercial deployment rights are subject to dataset source license (UCI).
Designed, developed, and modularized for production deployment with real-world constraints in mind. Includes all necessary components to transition from prototype to live application.