End-to-End Data Science Example: Predicting Diabetes with Logistic Regression
By: Keshav Dhandhania
Tags: Data Science, Data Visualization, Machine Learning

As the title suggests, this tutorial is an end-to-end example of solving a real-world problem using Data Science. We’ll be using Machine Learning to predict whether a person has diabetes or not, based on information about the patient such as blood pressure, body mass index (BMI), age, etc. The tutorial walks through the various stages of the data science workflow. In particular, the tutorial has the following sections

Overview

Data Description

Data Exploration

Data Preparation

Training and Evaluating the Machine Learning Model

Interpreting the ML Model

Saving the Model

Making Predictions with the Model

Next Steps

Overview

The data was collected and made available by “National Institute of Diabetes and Digestive and Kidney Diseases” as part of the Pima Indians Diabetes Database. Several constraints were placed on the selection of these instances from a larger database. In particular, all patients here belong to the Pima Indian heritage (subgroup of Native Americans), and are females of ages 21 and above.

We’ll be using Python and some of its popular data science related packages. First of all, we will import pandas to read our data from a CSV file and manipulate it for further use. We will also use numpy to convert out data into a format suitable to feed our classification model. We’ll use seaborn and matplotlib for visualizations. We will then import Logistic Regression algorithm from sklearn . This algorithm will help us build our classification model. Lastly, we will use joblib available in sklearn to save our model for future use.

import pandas as pd

import numpy as np

import seaborn as sns

import matplotlib.pyplot as plt

% matplotlib inline from sklearn.linear_model import LogisticRegression

from sklearn.externals import joblib

Data Description

We have our data saved in a CSV file called diabetes.csv . We first read our dataset into a pandas dataframe called diabetesDF , and then use the head() function to show the first five records from our dataset.

diabetesDF = pd.read_csv('diabetes.csv')

print(diabetesDF.head())

First 5 records in the Pima Indians Diabetes Database

The following features have been provided to help us predict whether a person is diabetic or not:

Pregnancies: Number of times pregnant

Number of times pregnant Glucose: Plasma glucose concentration over 2 hours in an oral glucose tolerance test

Plasma glucose concentration over 2 hours in an oral glucose tolerance test BloodPressure: Diastolic blood pressure (mm Hg)

Diastolic blood pressure (mm Hg) SkinThickness: Triceps skin fold thickness (mm)

Triceps skin fold thickness (mm) Insulin: 2-Hour serum insulin (mu U/ml)

2-Hour serum insulin (mu U/ml) BMI: Body mass index (weight in kg/(height in m)2)

Body mass index (weight in kg/(height in m)2) DiabetesPedigreeFunction: Diabetes pedigree function (a function which scores likelihood of diabetes based on family history)

Diabetes pedigree function (a function which scores likelihood of diabetes based on family history) Age: Age (years)

Age (years) Outcome: Class variable (0 if non-diabetic, 1 if diabetic)

Let’s also make sure that our data is clean (has no null values, etc).

diabetesDF.info() # output shown below <class 'pandas.core.frame.DataFrame'>

RangeIndex: 768 entries, 0 to 767

Data columns (total 9 columns):

Pregnancies 768 non-null int64

Glucose 768 non-null int64

BloodPressure 768 non-null int64

SkinThickness 768 non-null int64

Insulin 768 non-null int64

BMI 768 non-null float64

DiabetesPedigreeFunction 768 non-null float64

Age 768 non-null int64

Outcome 768 non-null int64

dtypes: float64(2), int64(7)

memory usage: 54.1 KB

Note that the data does have some missing values (see Insulin = 0) in the samples in the previous figure. Ideally we could replace these 0 values with the mean value for that feature, but we’ll skip that for now.

Data Exploration

Let us now explore our data set to get a feel of what it looks like and get some insights about it.

Let’s start by finding correlation of every pair of features (and the outcome variable), and visualize the correlations using a heatmap.

corr = diabetesDF.corr()

print(corr)

sns.heatmap(corr,

xticklabels=corr.columns,

yticklabels=corr.columns)

Output of feature (and outcome) correlations

Heatmap of feature (and outcome) correlations

In the above heatmap, brighter colors indicate more correlation. As we can see from the table and the heatmap, glucose levels, age, BMI and number of pregnancies all have significant correlation with the outcome variable. Also notice the correlation between pairs of features, like age and pregnancies, or insulin and skin thickness.

Let’s also look at how many people in the dataset are diabetic and how many are not. Below is the barplot of the same:

Barplot visualization of number of non-diabetic (0) and diabetic (1) people in the dataset

It is also helpful to visualize relations between a single variable and the outcome. Below, we’ll see the relation between age and outcome. You can similarly visualize other feature. The figure is a plot of the mean age for each of the output classes. We can see that the mean age of people having diabetes is higher.