Using Machine Learning to Predict Patients’ Diabetes Status
By: Nuhu Ibrahim
Tags: Machine Learning, Python, Supervised Learning, K Nearest Neighbours, Data Science

“There is a major shortage of data scientists.”

M. Stonebraker (Turing Award Winner), March 2020.

www.unsplash.com

In this article, we will go through some of the basics of machine learning and implement them using Python libraries. I will try to be as basic as possible, avoiding the use of too many “technical jargons” to carry along folks that are not yet solid in programming or machine learning.

About the Dataset

The dataset contains 2000 observations from patients, with 8 features and a target that states whether they have diabetes or not. The 8 recorded features about the patient include pregnancies, glucose, blood pressure, skin thickness, insulin, BMI, Diabetes Pedigree Function (likelihood of diabetes based on the family) and age. The target here is titled “outcome”, and is “1” if the patient has diabetes or “0” if they don’t.

𝐅𝐞𝐚𝐭𝐮𝐫𝐞𝐬 (𝐈𝐧𝐝𝐞𝐩𝐞𝐧𝐝𝐞𝐧𝐭 𝐕𝐚𝐫𝐢𝐚𝐛𝐥𝐞𝐬 𝐨𝐫 𝐈𝐧𝐩𝐮𝐭):

Pregnancies Glucose Blood Pressure Skin Thickness Insulin BMI Diabetes Pedigree Function Age

𝐓𝐚𝐫𝐠𝐞𝐭 (𝐃𝐞𝐩𝐞𝐧𝐝𝐞𝐧𝐭 𝐕𝐚𝐫𝐢𝐚𝐛𝐥𝐞 𝐨𝐫 𝐎𝐮𝐭𝐩𝐮𝐭):

Outcome

Want to know some basics of machine learning?

Machine Learning is the science of training computers to make decisions based on data without being explicitly programmed for every scenario. Machine Learning can be broadly classified into two branches, namely supervised and unsupervised learning.

Supervised Learning: Is kind of the most common branches of machine learning and is often what people are referring to when using the term “Machine Learning” and is the task of learning a function that maps an input to an output based on example input-output pairs. The most common supervised learnings are classification models, such as decision trees, which aim to classify observation based on their inputs and regression, which predicts a scalar response variable based on a set of input variables.

Unsupervised Learning: is a type of machine learning algorithm used to draw inferences from datasets consisting of input data without labelled responses. The most common unsupervised learning method is cluster analysis, which is used for exploratory data analysis to find hidden patterns or grouping in data.

Also, a crucial but overlooked step in data science projects is Data Visualization and Exploratory Data Analysis (EDA). EDA is a necessary step to be conducted to get a better sense of how our data looks like and if it conforms with all the requirements before we even train models and see results that will aid decision making.

Our scope in this article

In this article, we will use:

i. Classification methods via a popular library called scikit-learn which handles much of the technical maths behind the algorithms.

ii. NumPy: a Python library that allows us to work with arrays, matrices and perform linear algebra (it stands for Numerical Python).

iii. Pandas: a Python library that provides fast, flexible, and expressive data structures designed to work with relational and * labelled* data. It is a fundamental high-level building block for doing practical, real-world data analysis in Python.

iv. Two popular Python libraries to create visualisations (Matplotlib and Seaborn) as well as looking at some of the common steps used in the first steps of data analysis.

Overall, we will look at how we can understand the diabetes dataset via Exploratory Data Analysis (EDA). We will also look at how to train a model (k-nearest neighbour classification algorithm) with the diabetes dataset and use it to predict if new patients have diabetes. In conclusion, we will discuss various methods of determining how good our model is.

Prerequisites

For this article, I will be using Python & Jupyter notebooks.

The easiest way to use Python is via Anaconda as it comes with all the required packages that you may need.

Caution! Notebooks are essentially an interactive session of Python so that when you create variables, they are stored in memory. This can be problematic when re-running cells out of order (i.e. running one cell before you run the one above it), and so your code may not behave as expected. This is particularly problematic for those who are less familiar with programming, but it can trip up even experienced users as it is unintuitive.

The notebook and dataset used in this article can be found here on Github.

Exploratory Data Analysis (EDA)

First, we need to import some libraries that are commonly used for EDA and visualisations. Matplotlib and Seaborn are two straightforward plotting libraries in Python.

𝐍𝐨𝐭𝐞: "Datern.mplstyle" is a stylesheet that we use to make our visualizations look more presentable.

import numpy as np

import pandas as pd # We will use the Seaborn library

import seaborn as sns # Matplotlib forms basis for visualisation in Python

import matplotlib.pyplot as plt # Set the default style for plots

plt.style.use('Datern.mplstyle')

colors = plt.rcParams["axes.prop_cycle"]() #Gradient colours

from matplotlib.colors import LinearSegmentedColormap

nodes = [0,0.5,1.0]

color = ['#00ACF0','#ffffff']

cmap = LinearSegmentedColormap.from_list("", list(zip(nodes, color))) %config InlineBackend.figure_format='retina'

Now we load the diabetes dataset ( diabetes-dataset.csv ) into the notebook and begin to explore the characteristics within:

df = pd.read_csv('diabetes-dataset.csv')

We can then use Panda to see the types of features that we have in the dataset using .dtypes or even more, detail using .info()

df.dtypes

df.info()

Now to see some of our data, we can look at the first 5 entries using .head()

df.head()

We can look at other parts of the data using .tail() and .sample()

# Prints the last 10 entries

df.tail(10)

# Produces a random sample from the data

df.sample(frac=.01)

We can also get a better understanding of the quantitative variables in the dataset that help understand our continuous data before we start to visualize, using .describe() :

df.describe()

Data Visualisation

Data visualisation is the graphical representation of our data. We use charts, graphs and maps to make it easier to see trends and other features in our dataset.

# Now we make continous plots of quantitative data

fig=plt.figure(figsize=(20,20))

for i,col in enumerate(df.drop(['Outcome'],axis=1)):

ax=fig.add_subplot(4,2,i+1)

sns.distplot(df[col])

Observation

Blood pressure, Glucose and BMI are uniformly distributed. Skin Thickness, Diabetes Pedigree Function, Pregnancies and Age are positively (right) skewed. Blood Pressure, Skin Thickness, Insulin and BMI have zero values which can be regarded as outliers.

_ = sns.countplot(x='Pregnancies', hue='Outcome', data=df).set(title='Pregnancies against Outcome', xlabel='Pregnancies', ylabel='Outcome')

Interpretation

We will observe here that even though there are more people with a low number of pregnancies, it can be assumed that people with a higher number of pregnancies are more likely to have diabetes. This is because not up to half of those with a low number of pregnancies (between 0–2) have diabetes. However, half or more than half of patients with over 3 number of pregnancies have diabetes.

_ = sns.countplot(x='Outcome', data=df).set(title='Patients Diabetes Status Count', xlabel='Outcome', ylabel='Count')

Interpretation

This bar plot shows that more number of people whose observations are taken do not have diabetes.

_ = sns.countplot(x='Pregnancies', data=df).set(title='Patients Pregnancies Status Count', xlabel='Pregnancies', ylabel='Count')

Interpretation

More people of whose observations are taken have low numbers of pregnancies.

Classification (K-Nearest-Neighbour)

Classification is a well-known area of supervised learning where the target variables take the form of categories, such as given an email example, classifying if it is spam or not. In this example, we will be using the k-nearest-neigbour classifier, which is one of the most intuitive classification algorithms. The k-nearest-neighbors classifier is a simple algorithm that stores all available cases and classifies new cases based on a similarity measure (e.g., distance functions).

Building our model

Now we are ready to build our initial model. Scikit-learn has a KNeighborsClassifier module built-in, which makes it very simple for us. Here, we will be seeing how we can predict if a patient is likely to have diabetes or not.

We will start by creating two separate DataFrames for our targets and our features.

# Create feature and target arrays

y = df["Outcome"].values

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

Since KNN uses the distances between observations (not necessarily euclidean though) we will need to scale our data:

#Scaling - crucial for knn

from sklearn.preprocessing import StandardScaler

ss = StandardScaler()

X = ss.fit_transform(X)

Now we need to split our data into train and test set. Observe here that we are splitting into 80% train and 20% test.

from sklearn.model_selection import train_test_split # Split into training and test set

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

Finally, it is time to build and train our model:

from sklearn.neighbors import KNeighborsClassifier # Create a k-NN classifier

knn1 = KNeighborsClassifier() # Fit the classifier to the training data

knn1.fit(X_train,y_train)

Checking the accuracy of our model

Now we need to determine how good our model is. The most common metric is accuracy, which is how many we got right vs how many we got wrong while testing the model against the 20% test data from the dataset that were not part of the train data used in training the model.

# Print the accuracy

print(knn1.score(X_test, y_test))

Our model can predict whether someone is likely to have diabetes or not with 81% accuracy — and that is acceptable!.

A huge thanks to Datern for motivating me to write this piece.

That’s it y’all!

Let’s continue this conversation. Follow me on Twitter @_NuhuIbrahim.