An end-to-end Machine Learning pipeline and interactive diagnostic dashboard for predicting heart disease using clinical data.
Here's a full map of our learning journey:
The first step is bringing the data into our project environment.
Our data comes from the UCI Machine Learning Repository — one of the oldest and most trusted sources of public datasets for ML research.
This script handles the downloading and initial loading of the data.
- No Column Names: The raw
.datafile from UCI has no header. We manually assign names using a Python list. - Handling
?Values: Missing lab readings are marked with?. We must handle these before processing. - Binary Encoding: We convert the multi-class target (0-4) into binary (0 = healthy, 1 = disease) to simplify the prediction problem.
Output:
data/heart_disease_raw.csv(Original)data/heart_disease_cleaned.csv(Ready for EDA)
"Garbage in, garbage out" — a model is only as good as the data it learns from.
- Problem 1: Missing Values (
?→NaN): We usepd.read_csv(..., na_values="?")to treat?as missing values. - Problem 2: Missing Value Strategy: We use
df.dropna(). Losing 6 out of 303 rows is acceptable for this dataset. - Problem 3: Target Encoding: Converting severity levels to a clean yes/no binary target.
- Problem 4: Data Types: Ensuring all columns are numeric (float64/int64) for mathematical processing.
Warning
Skipping cleaning leads to "silent failure" where models train on corrupt data and produce dangerous, incorrect medical predictions.
Understanding the data before modeling.
- Target Distribution: Checking if the dataset is balanced (138 healthy vs 165 disease).
- Correlation Heatmap: Identifying which features (like
cp,exang,oldpeak) correlate most with disease. - Age Distribution: Visualizing how disease prevalence peaks in the 55–65 age range.
- Chest Pain Type vs Disease: Revealing that asymptomatic patients (
cp=3) often have the highest disease counts.
Technology Stack:
- Matplotlib: The "engine" (canvas, saving files).
- Seaborn: The "smart brush" (drawing complex statistical charts).
This is where the machine actually learns to map inputs (
- X/y Split: Separating features from the target variable.
- Train/Test Split: Reserving 20% of data for final evaluation to prevent "cheating."
- Feature Scaling: Using
StandardScalerto bring all features (Age vs. Cholesterol) into the same range. - Random Forest: An ensemble of 100 decision trees that use "majority voting" to make robust predictions.
We use a Confusion Matrix to track exactly where the model makes errors (False Positives vs. False Negatives).
Finding the absolute best model for our specific data.
- Logistic Regression: Simple, interpretable baseline.
- KNN (K-Nearest Neighbors): Predicts based on the most similar past patients.
- SVM (Support Vector Machine): Finds the "maximum margin" boundary. Our Winner!
- Random Forest & XGBoost: Advanced ensemble methods using bagging and boosting.
In medical diagnostics, we prioritize Recall to minimize False Negatives (missing a sick patient).
A production-ready tool built with Streamlit for real-time diagnostics.
- Real-time Prediction: Model reruns instantly as sliders move.
- Intelligent Caching: Uses
@st.cache_resourcefor blazing-fast model loading. - Dynamic UI: Red/Green alerts based on diagnostic results.
- Performance Tracking: Live metrics pulled directly from our benchmark results.
graph TD
A[data_loader.py] -->|Cleaned CSV| B[eda.py]
A -->|Cleaned CSV| C[train.py]
A -->|Cleaned CSV| D[compare_models.py]
D -->|best_model.joblib| E[app.py]
D -->|best_scaler.joblib| E
D -->|comparison_results.csv| E
E -->|UI| F[Interactive Dashboard]
Created with ❤️ for AI Diagnostic Research by Rizwan Ullah