An end-to-end machine learning pipeline for early diabetes screening using the CDC BRFSS 2015 Health Indicators dataset. Achieves 88% recall on diabetic cases with a clinically-calibrated ensemble model.
- Overview
- Dataset
- Project Structure
- Methodology
- Results
- Installation
- Usage
- Key Findings
- Technologies Used
This project builds a binary classification model to predict diabetes risk using survey-based health indicators. Given the real-world cost of missing a diabetic diagnosis (false negatives), the model is intentionally calibrated for high recall (sensitivity), making it suitable as a first-pass clinical screening tool.
The pipeline covers the full ML lifecycle: exploratory data analysis, feature engineering, class imbalance handling, model benchmarking, ensemble construction, and threshold tuning.
Source: CDC Behavioral Risk Factor Surveillance System (BRFSS) 2015
File: diabetes_binary_health_indicators_BRFSS2015.csv
| Property | Value |
|---|---|
| Original rows | ~253,680 |
| After deduplication | ~229,474 |
| Features | 21 health indicators |
| Target | Diabetes_binary (0 = No Diabetes, 1 = Diabetes) |
| Class imbalance | ~85% Non-Diabetic / ~15% Diabetic |
Key features include: HighBP, HighChol, BMI, GenHlth, Age, PhysActivity, Smoker, Stroke, HeartDiseaseorAttack, Income, Education, and more.
Note: The dataset is not included in this repository. Download it from Kaggle and place the CSV in the project root directory.
├── MLminiProject.ipynb # Main notebook (EDA + Modeling)
├── fig1_overview.png # Class distribution & correlations
├── fig2_deepdive.png # Feature deep-dives (BMI, Age, GenHlth, etc.)
├── fig3_combinations.png # Risk factor combinations & engineered features
└── README.md
- Visualized class imbalance, feature correlations, and diabetic rates across all categorical/ordinal variables.
- Identified
GenHlth,HighBP, andBMIas the strongest predictors. - Created 3 comprehensive dark-themed visualization panels covering 10+ charts.
| Feature | Description |
|---|---|
BMI_log |
Log transform of BMI to reduce skew |
BMI_cat |
Ordinal BMI category (Underweight → Extreme Obese) |
is_obese |
Binary flag: BMI ≥ 30 |
physhlth_log / menthlth_log |
Log transforms for health-day counts |
BP_Chol |
Interaction: High BP × High Cholesterol |
risk_count |
Sum of vascular risks (BP, Chol, Stroke, Heart Disease) |
lifestyle_score |
PhysActivity + Fruits + Veggies − HvyAlcoholConsump |
age_high_risk |
Flag for high-risk age groups (55–74) |
- Dropped:
AnyHealthcare,NoDocbcCost(near-zero signal) - Selected: Top 22 features via
SelectKBestwith Mutual Information
Used SMOTE (Synthetic Minority Oversampling Technique) with sampling_strategy=0.4 inside a pipeline to prevent data leakage during cross-validation.
| Model | Description |
|---|---|
| Logistic Regression | Baseline linear model |
| AdaBoost | Adaptive boosting on shallow decision trees |
| XGBoost | Gradient boosted trees (primary model) |
| Weighted Ensemble | Soft-voting ensemble of AdaBoost + XGBoost |
Two thresholds were evaluated:
- Optimal F1 threshold (0.248): Balances precision and recall.
- Medical threshold (0.208): Maximizes recall ≥ 70% to minimize missed diagnoses.
| Model | CV ROC-AUC | CV PR-AUC |
|---|---|---|
| Logistic Regression | 0.8070 | 0.4180 |
| AdaBoost | 0.8032 | 0.4094 |
| XGBoost | 0.8120 | 0.4290 |
| AB + XGB Ensemble | 0.8156 | 0.4399 |
| Metric | Value |
|---|---|
| ROC-AUC | 0.8156 |
| PR-AUC | 0.4399 |
| Recall (Diabetic) | 88% |
The PR-AUC of 0.44 represents a ~3× improvement over the naive baseline of ~0.15.
HighBPGenHlthBMI_catBP_Chol(engineered)Age
# Clone the repository
git clone https://github.com/your-username/diabetes-risk-prediction.git
cd diabetes-risk-prediction
# Create a virtual environment (recommended)
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txtpandas
numpy
matplotlib
seaborn
scipy
scikit-learn
imbalanced-learn
xgboost
jupyter
Or install directly:
pip install pandas numpy matplotlib seaborn scipy scikit-learn imbalanced-learn xgboost jupyter- Download the dataset and place
diabetes_binary_health_indicators_BRFSS2015.csvin the project root. - Launch Jupyter:
jupyter notebook MLminiProject.ipynb
- Run all cells in order. The notebook is structured in sections:
- Cell 1–4: Data loading and EDA setup
- Cell 5–7: Visualizations (Figures 1–3)
- Cell 8–9: Feature engineering and train/test split
- Cell 10–11: XGBoost pipeline + threshold tuning
- Cell 12: Feature importance analysis
- Cell 13: Medical threshold calibration
- Cell 14–16: Cross-validation and model comparison
- Cell 17–18: Ensemble construction and final evaluation
- High Blood Pressure + High Cholesterol together raise diabetic rates dramatically — from ~6% (neither) to ~27% (both).
- BMI is the strongest continuous predictor; obese individuals (BMI ≥ 30) show nearly 3× the diabetic rate of normal-weight individuals.
- Age shows a clear monotonic relationship: diabetic rates rise from ~2% in the 18–24 group to ~24%+ in the 65–74 group.
- Income and Education are inversely correlated with diabetes — lower socioeconomic status is associated with significantly higher risk.
- General Health self-rating is a surprisingly strong predictor: respondents who rate health as "Poor" show ~40% diabetic rates vs. ~4% for "Excellent."
This project is open-source and available under the MIT License.
Built as part of a Machine Learning mini-project exploring real-world health data and clinical model calibration.