Freedom Sale
Independence Day Special — Unlock the AI Path 70% off our most popular AI course · Limited time offer
--Days
--Hrs
--Min
--Sec
Claim Your Discount
✦ Intermediate ⏱ 40 min

🩺 Build a Diabetes Predictor with scikit-learn

🎯 What You'll Build

A diabetes risk predictor trained on the Pima Indians dataset — with hyperparameter tuning, ROC curve, and a predict_patient() function for new cases.

📋 What You'll Need

1

Load and clean the dataset

The Pima Indians dataset has 768 rows and 8 health features. Some zero values are actually missing data — we replace them.

import pandas as pd
import numpy as np

# Download from: https://www.kaggle.com/datasets/uciml/pima-indians-diabetes-database
df = pd.read_csv('diabetes.csv')
print(df.head())
print(df['Outcome'].value_counts())  # 0 = no diabetes, 1 = diabetes

# Replace biologically impossible zeros with NaN, then fill with median
zero_cols = ['Glucose','BloodPressure','SkinThickness','Insulin','BMI']
df[zero_cols] = df[zero_cols].replace(0, np.nan)
df.fillna(df.median(numeric_only=True), inplace=True)

print(df.isnull().sum())  # Should all be 0 now
2

Train and tune a Gradient Boosting classifier

Use GridSearchCV to find the best hyperparameters automatically.

from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline

X = df.drop('Outcome', axis=1)
y = df['Outcome']

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

pipeline = Pipeline([
    ('scaler', StandardScaler()),
    ('clf',    GradientBoostingClassifier(random_state=42)),
])

params = {
    'clf__n_estimators': [100, 200],
    'clf__learning_rate': [0.05, 0.1],
    'clf__max_depth': [3, 4],
}

grid = GridSearchCV(pipeline, params, cv=5, scoring='roc_auc', n_jobs=-1)
grid.fit(X_train, y_train)

print("Best params:", grid.best_params_)
print(f"Best CV AUC: {grid.best_score_:.4f}")
print(f"Test accuracy: {grid.score(X_test, y_test):.4f}")
Best params: {'clf__learning_rate': 0.1, 'clf__max_depth': 3, 'clf__n_estimators': 200}
Best CV AUC: 0.8412
Test accuracy: 0.7922
3

Plot an ROC curve

The ROC curve shows the trade-off between sensitivity and specificity at different thresholds.

from sklearn.metrics import RocCurveDisplay, classification_report
import matplotlib.pyplot as plt

best_model = grid.best_estimator_
y_pred = best_model.predict(X_test)

print(classification_report(y_test, y_pred, target_names=['No Diabetes','Diabetes']))

fig, ax = plt.subplots(figsize=(6,5))
RocCurveDisplay.from_estimator(best_model, X_test, y_test, ax=ax)
ax.set_title('Diabetes Predictor — ROC Curve')
plt.tight_layout()
plt.savefig('roc_curve.png', dpi=120)
plt.show()
4

Make predictions on new patients

Wrap the model in a function that takes a patient dict and returns a risk assessment.

def predict_patient(patient_dict):
    cols = ['Pregnancies','Glucose','BloodPressure','SkinThickness',
            'Insulin','BMI','DiabetesPedigreeFunction','Age']
    row = pd.DataFrame([patient_dict])[cols]
    prob = best_model.predict_proba(row)[0][1]
    risk = 'HIGH' if prob > 0.5 else 'LOW'
    print(f"Diabetes risk: {risk}  (probability: {prob:.1%})")
    return prob

predict_patient({
    'Pregnancies': 2, 'Glucose': 148, 'BloodPressure': 72,
    'SkinThickness': 35, 'Insulin': 0, 'BMI': 33.6,
    'DiabetesPedigreeFunction': 0.627, 'Age': 50,
})
Diabetes risk: HIGH  (probability: 83.1%)
💡 Tip: This is a demonstration model — do not use it for real medical decisions. The Pima Indians dataset has known limitations including selection bias. Always consult a healthcare professional for actual diabetes screening.

🎉 You Did It!

You trained, tuned, and deployed a diabetes risk model in under 60 lines. The same GridSearchCV + Pipeline pattern applies to any classification problem — just swap the dataset and the estimator.

Found something wrong?

Spotted a bug, broken code, or something that doesn't look right? Tell us what's off and we'll fix it.