Skip to content

Latest commit

 

History

9 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CardioPredict AI Banner
Typing SVG



Python Flask Scikit-Learn Machine Learning Artificial Intelligence Healthcare AI

NumPy Pandas Matplotlib Git GitHub Responsive Open Source License Version


Hero screenshot placeholder

Placeholder — replace with a real product screenshot of the prediction interface before publishing.



Quick StartML PipelineArchitectureInstallationDeploymentContact


Caution

Medical Disclaimer: CardioPredict AI is an educational and research project. It is not a certified medical device, has not been clinically validated, and must never be used as a substitute for professional medical diagnosis, advice, or treatment. Always consult a qualified healthcare provider for any medical concerns.


📖 Table of Contents

Click to expand full documentation index
1. Introduction 18. Model Selection 35. Screenshots
2. Vision 19. Prediction Workflow 36. Demo
3. Mission 20. Performance Evaluation 37. Engineering Decisions
4. Why CardioPredict AI 21. Confusion Matrix 38. Design Philosophy
5. Problem Statement 22. Classification Metrics 39. AI Philosophy
6. Solution 23. Explainable AI 40. Healthcare Considerations
7. Platform Highlights 24. System Architecture 41. Performance Optimization
8. Healthcare AI Overview 25. Technology Stack 42. Security
9. ML Pipeline 26. Folder Structure 43. Future Improvements
10. Dataset Overview 27. Project Modules 44. Known Limitations
11. Data Preprocessing 28. Flask Backend 45. Lessons Learned
12. Feature Engineering 29. Frontend 46. Contribution Guide
13. Exploratory Data Analysis 30. Installation 47. License
14. Model Training 31. Quick Start 48. Acknowledgements
15. Model Comparison 32. Environment Variables 49. Author
16. Model Selection 33. Local Development 50. Connect With Me
17. Prediction Workflow 34. Deployment Guide 51. Footer

🩺 Introduction

CardioPredict AI is a full-stack machine learning platform that estimates the likelihood of heart disease from a patient's clinical parameters — age, blood pressure, cholesterol, ECG results, and related measurements — using classical supervised classification algorithms trained on the widely-used UCI Cleveland Heart Disease dataset.

The platform pairs a Flask REST API backend, serving a trained scikit-learn model, with a lightweight, responsive web interface that lets a user enter clinical values and instantly receive a predicted risk classification along with a probability score.

This repository is built as a portfolio-grade, technically rigorous reference implementation demonstrating an end-to-end applied ML workflow: data preprocessing, feature engineering, exploratory analysis, multi-model training and comparison, evaluation, and deployment — all wrapped in production-style engineering practices.

Important

This project is intended for educational and research purposes only. It has not undergone clinical trials, regulatory review, or validation against real-world patient outcomes, and must not be used for actual medical decision-making.


🌌 Vision

To demonstrate that rigorous, explainable machine learning can be applied to healthcare-adjacent problems in a way that is transparent about its assumptions, honest about its limitations, and engineered to the same standard as production software — while remaining firmly positioned as a learning and research tool rather than a clinical product.


🎯 Mission

What CardioPredict AI Does

  • Accepts standard clinical parameters as structured input
  • Preprocesses and engineers features consistent with the training pipeline
  • Runs inference through a trained classification model
  • Returns a risk classification plus a probability score
  • Compares multiple ML algorithms transparently

What CardioPredict AI Does Not Do

  • It does not provide a clinical diagnosis
  • It does not replace a cardiologist or physician
  • It does not use real patient data in production
  • It does not claim regulatory (FDA/CE) approval of any kind

💡 Why CardioPredict AI

Challenge Traditional Approach CardioPredict AI Approach
Manually reviewing risk factors is time-consuming Clinician cross-references guidelines by hand Model surfaces a probability-based estimate in milliseconds
ML healthcare demos are often black boxes Prediction with no reasoning shown Explainable AI section documents feature influence transparently
Portfolio ML projects often stop at a notebook Jupyter notebook, no deployment Full REST API + responsive frontend + deployment guide
Model choice is rarely justified One model, no comparison Four algorithms evaluated side-by-side with documented rationale

Tip

Think of CardioPredict AI as a clinical decision-support prototype, not a diagnostic tool — similar in spirit to research dashboards used to explore how classical ML performs on structured clinical data, but explicitly not certified for patient care.


❗ Problem Statement

Cardiovascular disease remains one of the most extensively studied conditions in clinical data science, largely due to the availability of well-structured, feature-rich public datasets such as the UCI Cleveland Heart Disease dataset. The core problem this project addresses:

Given a set of clinical measurements for a patient, can a classification model reliably distinguish between "likely presence" and "likely absence" of heart disease indicators found in the training data?

This is fundamentally a binary classification problem in supervised machine learning, and it serves as an excellent vehicle for demonstrating the full applied ML lifecycle — from raw tabular data to a deployed, queryable API.


✅ Solution

CardioPredict AI addresses this problem through a structured, four-stage pipeline:

flowchart LR
    A[Raw Clinical Dataset] --> B[Preprocessing & Cleaning]
    B --> C[Feature Engineering]
    C --> D[Multi-Model Training]
    D --> E[Model Comparison & Selection]
    E --> F[Deployed Prediction API]
    F --> G[Web Interface]

    style A fill:#0B1120,color:#5EEAD4
    style F fill:#0B1120,color:#5EEAD4
    style G fill:#134E4A,color:#5EEAD4
Loading

Rather than committing to a single algorithm upfront, the project evaluates four distinct classification approaches — Logistic Regression, Random Forest, Support Vector Machine, and K-Nearest Neighbors — and documents the reasoning behind the final model selection, mirroring how a real ML engineering team would approach model selection.


✨ Platform Highlights

🧬 Clinical Data Pipeline

Structured preprocessing and feature engineering tailored to the Cleveland Heart Disease feature set.

🤖 Multi-Model Comparison

Four classical ML algorithms trained and evaluated side-by-side, with documented trade-offs.

⚡ Instant Inference

A Flask REST API serves predictions with probability scores in real time via a simple JSON contract.

📊 Transparent Evaluation

Confusion matrices and classification metrics are generated and documented, not just claimed.

🖥️ Responsive Interface

A clean, dependency-light HTML/CSS/JS frontend works across desktop and mobile viewports.

🔍 Explainability-First

Feature influence is documented and discussed, avoiding black-box "just trust the model" outputs.


🏥 Healthcare AI Overview

Applying machine learning to healthcare-adjacent data introduces engineering and ethical considerations beyond a typical classification task:

mindmap
  root((Healthcare AI))
    Data Quality
      Missing values
      Class imbalance
      Feature reliability
    Model Trust
      Explainability
      Uncertainty communication
      Avoiding overconfidence
    Ethical Use
      No diagnostic claims
      Clear disclaimers
      Educational framing
    Deployment
      Reproducibility
      Versioned models
      Transparent metrics
Loading

CardioPredict AI is designed around these considerations explicitly — see Healthcare Considerations for the full discussion.


🔬 Machine Learning Pipeline

flowchart TD
    subgraph INGEST["1️⃣ Data Ingestion"]
        A[UCI Cleveland Dataset] --> B[Load into Pandas DataFrame]
    end

    subgraph PREP["2️⃣ Preprocessing"]
        B --> C[Handle Missing Values]
        C --> D[Encode Categorical Features]
        D --> E[Feature Scaling / Normalization]
    end

    subgraph ENG["3️⃣ Feature Engineering"]
        E --> F[Derive/Select Relevant Features]
        F --> G[Train/Test Split]
    end

    subgraph TRAIN["4️⃣ Model Training"]
        G --> H1[Logistic Regression]
        G --> H2[Random Forest]
        G --> H3[Support Vector Machine]
        G --> H4[K-Nearest Neighbors]
    end

    subgraph EVAL["5️⃣ Evaluation"]
        H1 & H2 & H3 & H4 --> I[Compare via Classification Metrics]
        I --> J[Select Best-Performing Model]
    end

    subgraph SERVE["6️⃣ Serving"]
        J --> K[Serialize Model]
        K --> L[Flask Inference Endpoint]
    end

    style INGEST fill:#0B1120,color:#5EEAD4
    style TRAIN fill:#0B1120,color:#5EEAD4
    style SERVE fill:#134E4A,color:#5EEAD4
Loading

🗃️ Dataset Overview

CardioPredict AI is trained on the UCI Cleveland Heart Disease dataset, one of the most widely referenced datasets in clinical machine learning research.

Attribute Description
Source UCI Machine Learning Repository — Cleveland Clinic Foundation
Records 303 patient records (standard Cleveland subset)
Target Presence/absence of heart disease indicators
Type Structured / tabular clinical data
License Public research dataset — see UCI repository terms

Feature Descriptions

Feature Description Type
age Patient age in years Numeric
sex Biological sex (1 = male, 0 = female) Categorical
cp Chest pain type (4 categories) Categorical
trestbps Resting blood pressure (mm Hg) Numeric
chol Serum cholesterol (mg/dl) Numeric
fbs Fasting blood sugar > 120 mg/dl Binary
restecg Resting electrocardiographic results Categorical
thalach Maximum heart rate achieved Numeric
exang Exercise-induced angina Binary
oldpeak ST depression induced by exercise Numeric
slope Slope of the peak exercise ST segment Categorical
ca Number of major vessels colored by fluoroscopy Numeric
thal Thalassemia indicator Categorical
target Presence of heart disease (label) Binary

Note

Exact feature encodings and value ranges should be verified against the specific dataset version bundled in data/, as UCI dataset mirrors occasionally differ slightly in encoding conventions.


🧹 Data Preprocessing

flowchart LR
    A[Raw CSV] --> B{Missing Values?}
    B -->|Yes| C[Impute or Drop]
    B -->|No| D[Continue]
    C --> D
    D --> E[Encode Categorical Variables]
    E --> F[Scale Numeric Features]
    F --> G[Train/Test Split]

    style A fill:#0B1120,color:#5EEAD4
    style G fill:#134E4A,color:#5EEAD4
Loading
Step Technique Purpose
Missing value handling Imputation / row filtering Ensures model receives complete, valid input vectors
Categorical encoding One-hot / ordinal encoding Converts non-numeric fields (cp, restecg, thal, etc.) into model-consumable form
Feature scaling Standardization (z-score) Normalizes feature magnitude for distance-based models (SVM, KNN)
Train/test split Stratified split Preserves class balance across training and evaluation sets

Tip

Distance-based algorithms (KNN, SVM) are highly sensitive to unscaled features — a feature like chol (measured in the hundreds) can otherwise dominate distance calculations over a binary feature like sex. Scaling is applied consistently across all models for fair comparison.


🧬 Feature Engineering

Technique Applied To Rationale
One-hot encoding cp, restecg, slope, thal Prevents the model from assuming false ordinal relationships between categories
Binary normalization sex, fbs, exang Ensures consistent 0/1 representation
Standard scaling age, trestbps, chol, thalach, oldpeak Centers and scales continuous features to comparable ranges
Correlation review All numeric features Identifies redundant or weakly predictive features before training

Feature engineering decisions in this project prioritize interpretability alongside predictive value — every transformation is documented so that the relationship between a raw clinical measurement and its model-ready representation stays traceable.


📊 Exploratory Data Analysis

Exploratory Data Analysis (EDA) is performed prior to model training to understand feature distributions, class balance, and inter-feature relationships.

flowchart TD
    A[Load Dataset] --> B[Summary Statistics]
    B --> C[Class Balance Check]
    C --> D[Feature Distribution Plots]
    D --> E[Correlation Heatmap]
    E --> F[Outlier Review]
    F --> G[EDA Report / Notebook]

    style A fill:#0B1120,color:#5EEAD4
    style G fill:#134E4A,color:#5EEAD4
Loading

Typical EDA artifacts produced (see notebooks/eda.ipynb):

  • Class distribution bar chart (presence vs. absence of disease indicators)
  • Histograms for continuous features (age, chol, trestbps, thalach)
  • Correlation heatmap across all numeric features
  • Boxplots to visually inspect outliers per feature

Placeholder — replace with a generated correlation heatmap image.

🏋️ Model Training

Four classical supervised classification algorithms are trained on the identical preprocessed dataset and train/test split, ensuring a fair, apples-to-apples comparison.

flowchart LR
    Data[Preprocessed Training Data] --> LR[Logistic Regression]
    Data --> RF[Random Forest]
    Data --> SVM[Support Vector Machine]
    Data --> KNN[K-Nearest Neighbors]

    LR --> Eval[Evaluation Suite]
    RF --> Eval
    SVM --> Eval
    KNN --> Eval

    style Data fill:#0B1120,color:#5EEAD4
    style Eval fill:#134E4A,color:#5EEAD4
Loading
# Simplified training loop (see src/train.py for full implementation)
models = {
    "logistic_regression": LogisticRegression(max_iter=1000),
    "random_forest": RandomForestClassifier(n_estimators=200, random_state=42),
    "svm": SVC(probability=True, kernel="rbf"),
    "knn": KNeighborsClassifier(n_neighbors=7),
}

for name, model in models.items():
    model.fit(X_train, y_train)
    evaluate(model, X_test, y_test, name=name)

⚖️ Model Comparison

Model Why It Was Evaluated Key Characteristics
Logistic Regression Strong, interpretable baseline for binary classification Fast to train, coefficients are directly interpretable, assumes linear decision boundary
Random Forest Captures non-linear feature interactions Ensemble of decision trees, robust to outliers, provides feature importance scores
Support Vector Machine Effective in higher-dimensional, well-scaled feature spaces Strong margin-based separation, sensitive to feature scaling and kernel choice
K-Nearest Neighbors Simple, non-parametric baseline for comparison Distance-based, intuitive, sensitive to feature scaling and choice of k

Note

No accuracy, precision, recall, F1, or AUC values are published in this README. Run python src/evaluate.py locally to generate real metrics for your training run — see Performance Evaluation for the reporting template.

Comparison Criteria

Criterion Why It Matters
Interpretability Healthcare-adjacent contexts benefit from explainable decisions
Robustness to feature scale Determines preprocessing requirements
Training/inference speed Impacts API response latency
Sensitivity to class imbalance Affects reliability of minority-class predictions

🏆 Model Selection

The final deployed model is selected based on a documented, reproducible evaluation process — not a single accuracy number in isolation.

flowchart TD
    A[Train All 4 Models] --> B[Generate Confusion Matrix per Model]
    B --> C[Compute Precision, Recall, F1 per Model]
    C --> D[Compare Cross-Validation Stability]
    D --> E{Best Balance of Metrics + Interpretability?}
    E -->|Selected| F[Serialize as production model]
    E -->|Not Selected| G[Retained for comparison/reference]

    style F fill:#134E4A,color:#5EEAD4
    style A fill:#0B1120,color:#5EEAD4
Loading

Selection criteria, in priority order:

  1. Balanced performance across precision and recall (not just raw accuracy)
  2. Stability across cross-validation folds
  3. Reasonable inference latency for real-time API use
  4. Degree of interpretability appropriate for a healthcare-adjacent context

Important

The specific model marked as "production" in models/production_model.pkl should be treated as configurable — swap it based on your own evaluation results rather than assuming any one algorithm is universally superior.


🔮 Prediction Workflow

sequenceDiagram
    participant U as User
    participant F as Frontend (HTML/JS)
    participant A as Flask API
    participant M as Trained Model

    U->>F: Enter clinical parameters
    F->>F: Client-side validation
    F->>A: POST /api/predict (JSON payload)
    A->>A: Validate & preprocess input
    A->>M: model.predict_proba(input)
    M-->>A: Class + probability score
    A-->>F: JSON response
    F-->>U: Display risk classification + probability
Loading

Request lifecycle, end to end:

  1. User submits clinical parameters through the web form.
  2. Frontend performs basic client-side validation (required fields, numeric ranges).
  3. A POST request is sent to the Flask /api/predict endpoint as JSON.
  4. The backend applies the same preprocessing pipeline used during training (encoding, scaling).
  5. The trained model produces a class prediction and an associated probability score.
  6. The API returns a structured JSON response, rendered by the frontend as a risk indicator.

📈 Performance Evaluation

Note

No fabricated accuracy, precision, recall, F1, or AUC values are included in this README, per project policy. The template below reflects the reporting format used by src/evaluate.py — populate it with your own generated results.

Reporting template (fill in after running your own evaluation):

Model Accuracy Precision Recall F1-Score AUC
Logistic Regression <run evaluate.py> <run evaluate.py> <run evaluate.py> <run evaluate.py> <run evaluate.py>
Random Forest <run evaluate.py> <run evaluate.py> <run evaluate.py> <run evaluate.py> <run evaluate.py>
Support Vector Machine <run evaluate.py> <run evaluate.py> <run evaluate.py> <run evaluate.py> <run evaluate.py>
K-Nearest Neighbors <run evaluate.py> <run evaluate.py> <run evaluate.py> <run evaluate.py> <run evaluate.py>
# Generate the populated metrics table locally
python src/evaluate.py --model all --output reports/metrics.md

🧮 Confusion Matrix

A confusion matrix is generated per model during evaluation, visualizing true positives, true negatives, false positives, and false negatives.

flowchart LR
    subgraph CM["Confusion Matrix Structure"]
    direction TB
        A["True Positive (TP)<br/>Correctly predicted disease present"] 
        B["False Negative (FN)<br/>Missed disease case"]
        C["False Positive (FP)<br/>Incorrectly flagged as at-risk"]
        D["True Negative (TN)<br/>Correctly predicted no disease"]
    end

    style A fill:#134E4A,color:#5EEAD4
    style D fill:#134E4A,color:#5EEAD4
    style B fill:#7F1D1D,color:#fff
    style C fill:#78350F,color:#fff
Loading

Placeholder — replace with a generated confusion matrix plot per model.

Caution

In a healthcare-adjacent context, false negatives (missed at-risk cases) and false positives (unnecessary alarm) carry very different real-world costs. Model selection should explicitly weigh this trade-off rather than optimizing for accuracy alone — see Healthcare Considerations.


📐 Classification Metrics

Metric Formula What It Tells You
Accuracy (TP + TN) / (TP + TN + FP + FN) Overall correctness — can be misleading with class imbalance
Precision TP / (TP + FP) Of predicted "at-risk" cases, how many were correct
Recall (Sensitivity) TP / (TP + FN) Of actual at-risk cases, how many were correctly identified
F1-Score 2 · (Precision · Recall) / (Precision + Recall) Harmonic balance between precision and recall
AUC-ROC Area under the ROC curve Model's ability to distinguish classes across thresholds

Tip

For a screening-style healthcare use case, recall is often prioritized over raw accuracy, since missing an at-risk patient (false negative) is typically more costly than a false alarm that prompts further clinical review.


🔍 Explainable AI

CardioPredict AI treats explainability as a first-class requirement, not an afterthought — critical in any healthcare-adjacent ML system.

flowchart TD
    A[Trained Model] --> B{Model Type}
    B -->|Logistic Regression| C[Coefficient Magnitude & Sign]
    B -->|Random Forest| D[Feature Importance Scores]
    B -->|SVM / KNN| E[Permutation Importance]
    C --> F[Human-Readable Feature Influence Report]
    D --> F
    E --> F

    style A fill:#0B1120,color:#5EEAD4
    style F fill:#134E4A,color:#5EEAD4
Loading
Technique Applicable Models What It Reveals
Coefficient inspection Logistic Regression Direction and relative strength of each feature's influence
Feature importance Random Forest Which features most reduce impurity across the ensemble
Permutation importance SVM, KNN How much performance drops when a feature is shuffled

Note

Explainability outputs describe statistical influence within the trained model, not causal clinical relationships. They should be interpreted as model-behavior diagnostics, not medical insight.


🏗️ System Architecture

graph TB
    subgraph CLIENT["Client Layer"]
        UI[Responsive Web UI<br/>HTML / CSS / JS]
    end

    subgraph API["API Layer — Flask"]
        Router[REST Router]
        Validator[Input Validator]
        Preproc[Preprocessing Pipeline]
    end

    subgraph ML["ML Layer"]
        Model[Serialized Model<br/>.pkl]
        Explain[Explainability Module]
    end

    subgraph DATA["Data Layer"]
        Dataset[(UCI Cleveland Dataset)]
        Artifacts[(Trained Model Artifacts)]
    end

    UI -->|POST /api/predict| Router
    Router --> Validator
    Validator --> Preproc
    Preproc --> Model
    Model --> Explain
    Model -->|Prediction + Probability| Router
    Router -->|JSON Response| UI

    Dataset -.->|training time| Artifacts
    Artifacts -.-> Model

    style CLIENT fill:#0B1120,color:#5EEAD4
    style API fill:#1E293B,color:#5EEAD4
    style ML fill:#134E4A,color:#5EEAD4
    style DATA fill:#0B1120,color:#5EEAD4
Loading

🛠️ Technology Stack

Layer Technology Purpose
Frontend HTML5 Markup for the prediction interface
Frontend CSS3 Responsive styling
Frontend JavaScript Client-side interactivity, API calls
Backend Python Core backend & ML language
Backend Flask REST API framework
ML Scikit-Learn Model training & evaluation
ML NumPy Numerical computation
ML Pandas Data manipulation
ML Matplotlib Visualization & EDA plots
Dataset UCI Cleveland Heart Disease Dataset Training & evaluation data source
Deployment Render Backend hosting
Deployment Vercel Frontend hosting
Tooling Git Version control
Tooling GitHub Source hosting & collaboration

🗂️ Folder Structure

CardioPredict-AI/
├── backend/
│   ├── app.py                     # Flask application entry point
│   ├── routes/
│   │   └── predict.py             # /api/predict route handler
│   ├── ml/
│   │   ├── preprocess.py          # Preprocessing pipeline (shared train/infer)
│   │   ├── train.py               # Model training script
│   │   ├── evaluate.py            # Evaluation & metrics generation
│   │   └── explain.py             # Explainability utilities
│   ├── models/
│   │   └── production_model.pkl   # Serialized selected model
│   └── requirements.txt
├── frontend/
│   ├── index.html                 # Prediction form UI
│   ├── css/
│   │   └── styles.css
│   └── js/
│       └── app.js                 # Fetch logic, form handling
├── data/
│   └── cleveland_heart_disease.csv
├── notebooks/
│   ├── eda.ipynb                  # Exploratory data analysis
│   └── model_comparison.ipynb     # Model training & comparison
├── reports/
│   └── metrics.md                 # Generated evaluation report
├── docs/
│   └── assets/                    # Diagrams, screenshots (placeholders)
├── .env.example
├── .gitignore
├── requirements.txt
├── LICENSE
└── README.md
graph TD
    Root[CardioPredict-AI/] --> BE[backend/]
    Root --> FE[frontend/]
    Root --> Data[data/]
    Root --> NB[notebooks/]
    BE --> ML[ml/]
    ML --> Preprocess[preprocess.py]
    ML --> Train[train.py]
    ML --> Evaluate[evaluate.py]
    ML --> Explain[explain.py]
    BE --> Models[models/]
    FE --> Index[index.html]
    FE --> JS[js/app.js]

    style Root fill:#0B1120,color:#5EEAD4
Loading

🧱 Project Modules

Module File Responsibility
Preprocessing Pipeline backend/ml/preprocess.py Shared encoding/scaling logic used identically at train and inference time
Training Script backend/ml/train.py Trains all four models and serializes artifacts
Evaluation Script backend/ml/evaluate.py Generates confusion matrices and classification metrics
Explainability Module backend/ml/explain.py Produces feature importance / coefficient reports
Prediction Route backend/routes/predict.py Validates input and returns model predictions via REST
Flask App backend/app.py Application bootstrap, route registration, CORS config
Frontend UI frontend/index.html, frontend/js/app.js Patient input form and API integration

🧩 Flask Backend

flowchart TD
    A[Incoming POST /api/predict] --> B[Validate JSON Schema]
    B -->|Invalid| C[Return 400 Bad Request]
    B -->|Valid| D[Apply Preprocessing Pipeline]
    D --> E[Load Serialized Model]
    E --> F[Run Inference]
    F --> G[Format JSON Response]
    G --> H[Return 200 OK]

    style A fill:#0B1120,color:#5EEAD4
    style H fill:#134E4A,color:#5EEAD4
    style C fill:#7F1D1D,color:#fff
Loading
# backend/routes/predict.py (simplified)
from flask import Blueprint, request, jsonify
from backend.ml.preprocess import preprocess_input
from backend.ml.model_loader import load_model

predict_bp = Blueprint("predict", __name__)
model = load_model("models/production_model.pkl")

@predict_bp.route("/api/predict", methods=["POST"])
def predict():
    payload = request.get_json()
    features = preprocess_input(payload)
    prediction = model.predict(features)[0]
    probability = model.predict_proba(features)[0][1]

    return jsonify({
        "prediction": int(prediction),
        "risk_label": "At Risk" if prediction == 1 else "Low Risk",
        "probability": round(float(probability), 4)
    })

🎨 Frontend

The frontend is a dependency-light, responsive interface built with vanilla HTML/CSS/JS — deliberately avoiding a heavy framework to keep the project approachable and fast-loading.

Component Description
Patient Input Form Structured form covering all model input features
Client-Side Validation Range and required-field checks before submission
Result Panel Displays risk classification and probability score
Responsive Layout CSS Grid/Flexbox layout adapting to mobile and desktop
// frontend/js/app.js (simplified)
async function submitPrediction(formData) {
  const response = await fetch("/api/predict", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(formData),
  });
  const result = await response.json();
  renderResult(result);
}

⚙️ Installation

# 1. Clone the repository
git clone https://github.com/your-username/cardiopredict-ai.git

# 2. Move into the project directory
cd cardiopredict-ai

# 3. Create a virtual environment
python -m venv venv

# 4. Activate the virtual environment
# macOS / Linux:
source venv/bin/activate
# Windows:
venv\Scripts\activate

# 5. Install backend dependencies
pip install -r backend/requirements.txt
Requirement Minimum Version
Python 3.10 or later
pip 23.x or later
Node (optional, for frontend tooling) 18.x or later
OS macOS, Linux, Windows (WSL recommended)

🚀 Quick Start

# 1. Train the models (generates production_model.pkl)
python backend/ml/train.py

# 2. Evaluate all trained models
python backend/ml/evaluate.py

# 3. Run the Flask API
python backend/app.py

# 4. Open the frontend
# Navigate to frontend/index.html in your browser,
# or serve it via a simple static server:
python -m http.server 5500 --directory frontend

Example Prediction Request:

POST /api/predict
Content-Type: application/json

{
  "age": 58,
  "sex": 1,
  "cp": 2,
  "trestbps": 130,
  "chol": 246,
  "fbs": 0,
  "restecg": 1,
  "thalach": 152,
  "exang": 0,
  "oldpeak": 1.2,
  "slope": 1,
  "ca": 0,
  "thal": 2
}

Example Response:

{
  "prediction": 1,
  "risk_label": "At Risk",
  "probability": 0.7842
}

🔑 Environment Variables

# .env.example

FLASK_ENV=development
FLASK_APP=backend/app.py
FLASK_PORT=5000
MODEL_PATH=backend/models/production_model.pkl
CORS_ORIGIN=http://localhost:5500
Variable Description Required
FLASK_ENV development or production
FLASK_APP Entry point for the Flask CLI
FLASK_PORT Port the API listens on ❌ (defaults to 5000)
MODEL_PATH Path to the serialized production model
CORS_ORIGIN Allowed origin for frontend requests

💻 Local Development

# Run the Flask dev server with auto-reload
export FLASK_ENV=development
flask run

# Run backend unit tests
pytest backend/tests/

# Re-generate EDA plots
jupyter nbconvert --to notebook --execute notebooks/eda.ipynb

# Lint Python code
flake8 backend/

☁️ Deployment Guide

flowchart LR
    A[Push to main branch] --> B[CI: Run Tests]
    B --> C{Tests Pass?}
    C -->|No| D[Block Deployment]
    C -->|Yes| E[Deploy Backend to Render]
    C -->|Yes| F[Deploy Frontend to Vercel]
    E --> G[Live API Endpoint]
    F --> H[Live Web Interface]
    H -->|API calls| G

    style A fill:#0B1120,color:#5EEAD4
    style G fill:#134E4A,color:#5EEAD4
    style H fill:#134E4A,color:#5EEAD4
    style D fill:#7F1D1D,color:#fff
Loading
Step Platform Notes
1 Render Deploy backend/ as a Python web service; set environment variables from .env.example
2 Render Configure build command: pip install -r backend/requirements.txt
3 Render Configure start command: gunicorn backend.app:app
4 Vercel Deploy frontend/ as a static site
5 Vercel Set CORS_ORIGIN on the backend to match the deployed frontend URL
# Example Render start command
gunicorn backend.app:app --bind 0.0.0.0:$PORT

🖼️ Screenshots


Placeholder — add a real screenshot of the patient input form.




Placeholder — add a real screenshot of the prediction result panel.

🎬 Demo


Placeholder — replace with an animated GIF demoing form submission → prediction result.

🧠 Engineering Decisions

Decision Rationale
Shared preprocessing module for train & inference Guarantees train/serve consistency, avoiding train-serve skew
Multi-model comparison instead of a single algorithm Mirrors real ML engineering practice and documents trade-offs honestly
Flask over a heavier framework Minimal overhead for a focused, single-purpose inference API
Vanilla JS frontend Keeps the demo lightweight and framework-independent
Model serialized via pickle/joblib Simple, standard scikit-learn deployment pattern
Explicit metrics reporting template (no hardcoded numbers) Prevents misleading claims; encourages reproducible evaluation

🎨 Design Philosophy

CardioPredict AI's interface follows a calm, clinical, low-noise visual language — consistent with enterprise healthcare software rather than a flashy consumer app:

  • Restrained color palette (deep navy, teal accents) evoking trust and clarity
  • Generous whitespace around clinical input fields to reduce cognitive load
  • Clear visual separation between input, prediction result, and disclaimers
  • Accessibility-conscious contrast for readability across devices

🤖 AI Philosophy

Important

CardioPredict AI is built around the principle that an ML system's outputs are only as trustworthy as its transparency about uncertainty and limitations.

This project's approach to applied AI:

  1. No black boxes — every model's decision logic is at least partially explainable (see Explainable AI).
  2. No inflated claims — performance metrics are generated, not asserted; placeholders are used until real numbers exist.
  3. Probability, not certainty — outputs are framed as probability estimates, never as definitive diagnoses.
  4. Reproducibility first — the same input, model, and preprocessing pipeline will always produce the same output.

🏥 Healthcare Considerations

Caution

This section exists because applying ML to health-adjacent data carries responsibilities beyond typical software engineering.

Consideration How This Project Addresses It
Risk of misuse as a diagnostic tool Prominent disclaimers throughout the README and UI
False negative cost Documented explicitly in Classification Metrics as a priority concern
Dataset representativeness UCI Cleveland dataset is a research dataset, not representative of a full modern patient population
Data privacy No real patient data is collected, stored, or transmitted by this application
Bias awareness Dataset demographic skew is not corrected for — flagged under Known Limitations
Regulatory status This project makes no claim of FDA, CE, or any other regulatory clearance

This project should never be used to:

  • Make or influence an actual medical diagnosis
  • Replace consultation with a licensed healthcare professional
  • Inform real treatment or lifestyle decisions without professional medical guidance

⚡ Performance Optimization

Optimization Applied Where Benefit
Model pre-loaded at app startup backend/app.py Avoids reloading the model on every request
Lightweight JSON payloads API contract Minimizes request/response latency
Stateless Flask routes backend/routes/predict.py Enables horizontal scaling without session affinity
Vanilla JS frontend (no framework overhead) frontend/ Faster page load, smaller bundle size
Vectorized preprocessing (NumPy/Pandas) backend/ml/preprocess.py Efficient batch-capable transformations

🔒 Security

Concern Current Status Recommendation
Input validation Basic schema validation on /api/predict Extend with strict type/range enforcement before production use
CORS configuration Restricted via CORS_ORIGIN environment variable Lock down to exact deployed frontend origin
Patient data handling No persistent storage of submitted data Confirm compliance requirements (e.g., HIPAA) before handling real data
Dependency management Pinned versions in requirements.txt Run pip-audit regularly for vulnerability scanning
Rate limiting Not implemented Add rate limiting (e.g., Flask-Limiter) before public deployment
Authentication Not implemented (open demo endpoint) Add API key or OAuth layer for any non-demo deployment

Warning

This project does not implement healthcare-grade data protection (e.g., HIPAA-compliant storage/transmission). Do not submit real patient-identifiable data to any deployment of this demo.


🗺️ Future Improvements

Feature Status Priority
SHAP-based explainability visualizations Planned High
Model versioning & experiment tracking (e.g., MLflow) Planned High
Dockerized deployment Planned Medium
Expanded dataset beyond UCI Cleveland subset Under Consideration Medium
Automated CI/CD pipeline with test gating Planned Medium
User authentication for saved prediction history Under Consideration Low
Mobile-native companion app Under Consideration Low
timeline
    title CardioPredict AI Roadmap
    v1.0 : Core ML pipeline
         : Flask REST API
         : Responsive web UI
    v1.1 : SHAP-based explainability
         : MLflow experiment tracking
    v1.2 : Dockerized deployment
         : CI/CD pipeline
    v2.0 : Expanded dataset support
         : User authentication & history
Loading

🚧 Known Limitations

  • Trained on a relatively small, research-oriented dataset (303 records) — not representative of a broader modern patient population.
  • No correction applied for demographic imbalance within the source dataset.
  • No SHAP/LIME-based per-prediction explanations yet (feature importance is model-level, not prediction-level).
  • No persistent storage, audit logging, or authentication layer.
  • Not validated against real-world clinical outcomes or reviewed by medical professionals.
  • Not tested for robustness against adversarial or malformed input beyond basic schema validation.

📚 Lessons Learned

  • Maintaining a single shared preprocessing function between training and inference eliminated an entire class of subtle bugs caused by train/serve skew.
  • Comparing multiple models side-by-side — rather than committing early to one algorithm — surfaced meaningful trade-offs between interpretability and raw predictive capability.
  • Writing the Healthcare Considerations section early in development, rather than as an afterthought, shaped several downstream engineering decisions (e.g., no persistent data storage).
  • Keeping the frontend framework-free simplified deployment significantly and kept the project approachable for readers focused on the ML/backend engineering.

🤝 Contribution Guide

Contributions are welcome — bug fixes, new evaluation metrics, additional models, documentation improvements, and UI enhancements are all appreciated.

flowchart LR
    A[Fork Repository] --> B[Create Feature Branch]
    B --> C[Implement Change]
    C --> D[Add/Update Tests]
    D --> E[Run pytest]
    E --> F{All Tests Pass?}
    F -->|No| C
    F -->|Yes| G[Open Pull Request]
    G --> H[Code Review]
    H --> I[Merge]

    style A fill:#0B1120,color:#5EEAD4
    style I fill:#134E4A,color:#5EEAD4
Loading
# 1. Fork and clone your fork
git clone https://github.com/your-username/cardiopredict-ai.git

# 2. Create a feature branch
git checkout -b feature/your-feature-name

# 3. Make your changes, then run the test suite
pytest backend/tests/

# 4. Commit using a clear, descriptive message
git commit -m "feat: add SHAP-based per-prediction explanations"

# 5. Push and open a pull request
git push origin feature/your-feature-name
Contribution Type Guidelines
Bug fixes Include a regression test that fails before your fix and passes after
New models/features Open an issue first to discuss scope before submitting a large PR
Documentation Keep tone and disclaimers consistent with the rest of this README
ML pipeline changes Clearly document any change to preprocessing, training, or evaluation logic

Important

Any change to backend/ml/preprocess.py, backend/ml/train.py, or the production model artifact should include updated evaluation metrics generated via evaluate.py, and must preserve the project's disclaimer language.


📄 License

This project is licensed under the MIT License.

MIT License

Copyright (c) 2025 [Your Name]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.

See the LICENSE file for the full text.

Caution

This license covers the software, not medical advice. Use of this software does not constitute, and is not a substitute for, professional medical judgment.


🙏 Acknowledgements

  • UCI Machine Learning Repository & Cleveland Clinic Foundation — for maintaining and publishing the Heart Disease dataset used in this project.
  • The broader open-source data science community — scikit-learn, pandas, NumPy, and Matplotlib maintainers, whose tools made this project possible.
  • Public healthcare AI research and documentation practices from organizations such as Google Health and DeepMind, which informed this project's emphasis on explainability and responsible framing.

👤 Author

Your Name

Machine Learning Engineer • Healthcare AI Enthusiast • Software Engineer


🔗 Connect With Me

GitHub LinkedIn Portfolio Email


footer wave

CardioPredict AI — AI-Powered Heart Disease Risk Prediction Platform

Built with scikit-learn, Flask, and a strong commitment to responsible, explainable applied machine learning. This is an educational and research project — not a certified medical device and not a substitute for professional medical diagnosis or advice.



If this project helped you understand applied healthcare ML, consider starring the repository.

About

Real-time heart disease risk prediction system integrating machine learning with a full-stack web architecture (Flask + MERN). Implements end-to-end data preprocessing, model inference API, and interactive frontend for clinical risk assessment.

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages