Intelligent Stroke Risk Assessment Using Explainable Machine Learning

Built for the Undergraduate Students' Competition in the Application of Artificial Intelligence in Medicine — NACOS UI + DATICAN + University of Ibadan, 2026.
- Overview
- Live Demo
- Features
- Architecture
- ML Pipeline
- Tech Stack
- Project Structure
- Local Setup
- Training the Models
- Deployment
- API Documentation
- Screenshots
- Team
- License
NeuroPredict AI is a full-stack web application that predicts stroke risk using an ensemble of four machine learning models. The system provides transparent, explainable predictions powered by SHAP (SHapley Additive exPlanations), allowing clinicians and patients to understand exactly which factors contribute to an individual's stroke risk.
The platform features a real-time risk gauge, interactive what-if scenario simulator, comprehensive analytics dashboard, and educational resources — all wrapped in a modern, responsive medical-grade user interface.
Stroke remains the second leading cause of death globally, with over 130,000 deaths annually in Nigeria alone. Early identification of at-risk individuals enables timely intervention and preventive care. NeuroPredict AI bridges the gap between complex ML models and clinical usability by providing:
- Explainable predictions — not black-box outputs
- Multi-model consensus — four independent models for robust predictions
- Interactive exploration — what-if analysis to understand risk modification
- Clinical-grade UI — designed for healthcare professionals and patients
🌐 View Deployed Application (Update after deployment)
- 4-Model Ensemble: Random Forest, XGBoost, Logistic Regression, and Neural Network (MLP)
- SMOTE Oversampling: Handles class imbalance (4.9% positive → 50/50 balanced training)
- Weighted Ensemble: XGBoost-weighted averaging for optimal prediction accuracy
- SHAP Explainability: Per-feature contribution analysis with interactive visualization
- Animated circular gauge with color-coded risk levels (green/yellow/red)
- Updates instantly as user types — provides immediate visual feedback
- Canvas-rendered at 60fps for smooth animations
- SHAP horizontal bar chart showing feature contributions
- Side-by-side model comparison with confidence badges
- Personalized health recommendations based on risk factors
- Interactive sliders for glucose, BMI, and age
- Toggle switches for hypertension, heart disease, and smoking
- Real-time risk reduction calculation — shows impact of lifestyle changes
- Stroke rate distribution by age group
- Global feature importance ranking
- Gender and smoking status distribution charts
- All data sourced from the Kaggle Stroke Prediction Dataset (5,110 patients)
- FAST acronym awareness cards (Face, Arm, Speech, Time)
- Comprehensive risk factor education
- Prevention strategies and lifestyle recommendations
- 6-step ML methodology explanation
- Dark/Light mode toggle
- Fully responsive design (mobile, tablet, desktop)
- Smooth animations powered by Framer Motion
- Glassmorphism navigation bar
- Server connection error handling with troubleshooting guide
┌──────────────────────────────────────────────────────────┐
│ FRONTEND (Next.js 16) │
│ Hosted on Netlify │
│ │
│ ┌──────────┐ ┌──────────┐ ┌───────────────────────┐ │
│ │ React │ │ Tailwind │ │ Recharts + Framer │ │
│ │ 19 │ │ CSS 4 │ │ Motion + shadcn/ui │ │
│ └────┬─────┘ └────┬─────┘ └───────────┬───────────┘ │
│ └──────────────┼────────────────────┘ │
│ │ │
│ ┌──────────▼──────────┐ │
│ │ /api/predict Route │ │
│ │ (Next.js API) │ │
│ └──────────┬──────────┘ │
└──────────────────────┼───────────────────────────────────┘
│ HTTP POST
│
┌──────────────────────▼───────────────────────────────────┐
│ BACKEND (FastAPI) │
│ Hosted on Render │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Model Loading Layer │ │
│ │ model_rf.pkl model_xgb.pkl model_lr.pkl │ │
│ │ model_mlp.pkl scaler.pkl label_encoders.pkl │ │
│ │ shap_explainer.pkl feature_names.pkl │ │
│ └──────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────┐ │
│ │ Prediction Pipeline │ │
│ │ Input → LabelEncode → Scale → Predict → SHAP │ │
│ └──────────────────────┬───────────────────────────┘ │
│ │ │
│ ┌──────────────────────▼───────────────────────────┐ │
│ │ Response Builder │ │
│ │ risk_score + risk_level + shap_values + │ │
│ │ model_results + recommendations │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
| Property | Value |
|---|---|
| Source | Kaggle Stroke Prediction Dataset |
| Author | fedesoriano |
| Samples | 5,110 patients |
| Features | 10 (gender, age, hypertension, heart_disease, ever_married, work_type, residence_type, avg_glucose_level, bmi, smoking_status) |
| Target | stroke (0 = no stroke, 1 = stroke) |
| Positive Cases | 249 (4.9%) — heavily imbalanced |
| Missing Values | BMI: 201 NaN values |
- Missing Data: BMI imputed with median value
- Categorical Encoding: LabelEncoder applied to gender, ever_married, work_type, Residence_type, smoking_status
- Feature Scaling: StandardScaler applied to age, avg_glucose_level, bmi
- Class Imbalance: SMOTE (Synthetic Minority Over-sampling Technique) applied to balance the dataset from 4.9% to 50% positive class
| # | Model | Hyperparameters | Purpose |
|---|---|---|---|
| 1 | Random Forest | n_estimators=200, max_depth=10 | Robust baseline with low variance |
| 2 | XGBoost | n_estimators=200, max_depth=6, lr=0.1 | High-performance gradient boosting |
| 3 | Logistic Regression | max_iter=1000 | Interpretable linear model |
| 4 | Neural Network (MLP) | layers=(64, 32), max_iter=500 | Non-linear pattern capture |
Predictions from all 4 models are combined using a weighted average:
- Random Forest: weight = 1.0
- XGBoost: weight = 1.3 (highest performing model)
- Logistic Regression: weight = 0.8
- Neural Network: weight = 1.0
SHAP (SHapley Additive exPlanations) TreeExplainer is applied to the XGBoost model to compute per-feature contribution scores. This allows users to see exactly how much each health factor (age, glucose, BMI, etc.) contributes to their predicted risk.
| Technology | Purpose |
|---|---|
| Next.js 16 | React framework with server-side API routes |
| React 19 | UI component library |
| TypeScript | Type-safe development |
| Tailwind CSS 4 | Utility-first CSS framework |
| shadcn/ui | Pre-built accessible UI components |
| Framer Motion | Animations and transitions |
| Recharts | Data visualization charts |
| Lucide React | Icon library |
| next-themes | Dark/Light mode |
| Technology | Purpose |
|---|---|
| Python | Programming language |
| FastAPI | High-performance API framework |
| Uvicorn | ASGI server |
| scikit-learn | ML models (RF, LR, MLP) + preprocessing |
| XGBoost | Gradient boosting model |
| SHAP | Model explainability |
| imbalanced-learn | SMOTE oversampling |
| Pandas | Data manipulation |
| NumPy | Numerical computing |
| Joblib | Model serialization |
| Service | Purpose | Cost |
|---|---|---|
| Netlify | Frontend hosting | Free |
| Render | Backend hosting | Free |
| Google Colab | Model training | Free |
Neuropredict/
├── frontend/ # Next.js 16 Application
│ ├── src/
│ │ ├── app/
│ │ │ ├── layout.tsx # Root layout, fonts, theme provider
│ │ │ ├── page.tsx # Main page composing all sections
│ │ │ ├── globals.css # Custom medical-themed color system
│ │ │ └── api/
│ │ │ └── predict/
│ │ │ └── route.ts # API proxy to FastAPI backend
│ │ ├── components/
│ │ │ ├── stroke/
│ │ │ │ ├── navbar.tsx # Sticky glassmorphism navigation
│ │ │ │ ├── hero.tsx # Hero section with animated counters
│ │ │ │ ├── predict-section.tsx # Patient input form + error handling
│ │ │ │ ├── risk-gauge.tsx # Canvas-rendered animated gauge
│ │ │ │ ├── results-dashboard.tsx # SHAP chart + model comparison
│ │ │ │ ├── analytics-dashboard.tsx # 4 data visualization charts
│ │ │ │ ├── what-if-simulator.tsx # Interactive risk modifier
│ │ │ │ ├── education-section.tsx # FAST signs + prevention
│ │ │ │ └── footer.tsx # Links and attribution
│ │ │ └── ui/ # shadcn/ui component library
│ │ └── lib/
│ │ └── stroke-prediction.ts # Local risk estimation (live gauge)
│ ├── package.json
│ ├── next.config.ts
│ ├── tailwind.config.ts
│ ├── tsconfig.json
│ └── postcss.config.mjs
│
├── backend/ # FastAPI Python Backend
│ ├── main.py # API application with /health + /predict
│ ├── train.py # Model training script (run locally)
│ ├── requirements.txt # Python dependencies
│ ├── Procfile # Render deployment configuration
│ ├── COLAB_TRAINING.md # Google Colab step-by-step guide
│ ├── README.md # Backend-specific documentation
│ └── model_artifacts/ # Trained ML model files
│ ├── model_rf.pkl # Random Forest
│ ├── model_xgb.pkl # XGBoost
│ ├── model_lr.pkl # Logistic Regression
│ ├── model_mlp.pkl # Neural Network
│ ├── scaler.pkl # StandardScaler
│ ├── label_encoders.pkl # Categorical encoders
│ ├── shap_explainer.pkl # SHAP TreeExplainer
│ └── feature_names.pkl # Feature column names
│
├── .gitignore
└── README.md # This file
- Node.js 18+ (download)
- Python 3.9+ (download)
- Git (download)
- Kaggle dataset: healthcare-dataset-stroke-data.csv
git clone https://github.com/DATICANcompetitionUI/Neuropredict.git
cd Neuropredictcd backend
# Create virtual environment
python -m venv venv
# Activate (Windows)
venv\Scripts\activate
# Activate (Mac/Linux)
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Place the CSV in this folder, then train models
python train.py
# Start the backend server
uvicorn main:app --port 8000Verify: Open http://localhost:8000/health — should return {"status":"ok"}.
Open a new terminal:
cd frontend
# Install dependencies
npm install
# Start the development server
npm run devOpen http://localhost:3000 in your browser.
Fill the prediction form and click "Run Full Analysis". The results should come from your real ML models. If the backend is not running, a clear error message will be displayed.
cd backend
python train.pyThis trains all 4 models on your machine, ensuring version compatibility.
See backend/COLAB_TRAINING.md for the complete step-by-step Colab notebook.
Steps:
- Download the CSV from Kaggle
- Upload to Google Colab
- Run the training cells
- Download the generated
model_artifacts.zip - Extract into
backend/model_artifacts/
⚠️ Important: Models trained on Colab may have version incompatibilities with your local Python environment. If you encounterXGBoostError: input stream corrupted, retrain locally usingpython train.py.
- Push this repository to GitHub
- Go to render.com → New Web Service
- Connect the GitHub repository
- Configure:
- Root Directory:
backend - Runtime: Python 3
- Build Command:
pip install -r requirements.txt - Start Command:
uvicorn main:app --host 0.0.0.0 --port $PORT
- Root Directory:
- Deploy → Copy the URL (e.g.,
https://neuropredict-api.onrender.com)
- Go to netlify.com → Add New Site → Import from Git
- Connect the GitHub repository
- Configure:
- Root Directory:
frontend - Build Command:
npm run build - Publish Directory:
.next
- Root Directory:
- In Site Settings → Environment Variables, add:
BACKEND_URL=https://neuropredict-api.onrender.com(your Render URL)
- Deploy!
⚠️ Before deploying frontend: UpdateBACKEND_URLinfrontend/src/app/api/predict/route.tsfrom the hardcodedhttp://localhost:8000toprocess.env.BACKEND_URL || "".
GET /health
Response:
{
"status": "ok",
"models_loaded": true,
"features": ["gender", "age", "hypertension", ...],
"shap_enabled": true
}POST /predict
Content-Type: application/json
Request Body:
{
"gender": "Male",
"age": 67,
"hypertension": 1,
"heart_disease": 0,
"ever_married": "Yes",
"work_type": "Private",
"residence_type": "Urban",
"avg_glucose_level": 228.69,
"bmi": 36.6,
"smoking_status": "formerly smoked"
}Response:
{
"risk_score": 73.2,
"risk_level": "high",
"shap_values": [
{ "feature": "Age", "value": 0.4521 },
{ "feature": "Avg Glucose Level", "value": 0.3201 },
{ "feature": "BMI", "value": 0.1502 }
],
"model_results": [
{ "name": "Random Forest", "probability": 71.3 },
{ "name": "XGBoost", "probability": 78.5 },
{ "name": "Logistic Regression", "probability": 65.2 },
{ "name": "Neural Network", "probability": 72.8 }
],
"recommendations": [
{
"category": "Blood Sugar",
"icon": "droplets",
"text": "Your glucose level is elevated..."
}
]
}| Feature | Preview |
|---|---|
| Hero Section | |
| Prediction Form | |
| SHAP Results | |
| What-If Simulator |
(Replace placeholders with actual screenshots after deployment)
DATICAN Competition Team — University of Ibadan
Undergraduate Students' Competition in the Application of Artificial Intelligence in Medicine, 2026.
This project is developed for educational and competition purposes.
- Kaggle Stroke Prediction Dataset by fedesoriano
- SHAP Library for model explainability
- NACOS UI + DATICAN for organizing the competition
- University of Ibadan, Department of Computer Science