Pima Indians Diabetes - Prediction & KNN Visualization | by Hardik Deshmukh | Towards Data Science

In India, diabetes is a major issue. Between 1971 and 2000, the incidence of diabetes rose ten times, from 1.2% to 12.1%. 61.3 million people 20–79 years of age in India are estimated living with diabetes (Expectations of 2011). It is expected that by 2030 this number will rise to 101,2 million. In India there are reportedly 77.2 million people with prediabetes. In 2012, nearly 1 million people in India died of diabetes. 1 out of 4 individuals living in Chennai’s urban slums suffer from diabetes, which is about 7 per cent by three times the national average. One third of the deaths in India involve people under non-communicable diseases Sixty years old. Indians get diabetes 10 years before their Western counterparts on average. Changes in lifestyle lead to physical decreases Increased fat, sugar and activities activity calories and higher insulin cortisol levels Obesity and vulnerability. In 2011, India cost around $38 billion annually as a result of diabetes.
Reference: http://www.arogyaworld.org/wp-content/uploads/2010/10/ArogyaWorld_IndiaDiabetes_FactSheets_CGI2013_web.pdf
Code by Hardik
Link to Colab notebook: https://colab.research.google.com/drive/1n4FNgK0DwtK0QALoWcyWjBtkCLxjGs-S?usp=sharing
Pima Indians Diabetes Database (Predict the onset of diabetes based on diagnostic measures)
UCI Machine Learning — Repository:https://www.kaggle.com/uciml/pima-indians-diabetes-database
This dataset comes from the Diabetes and Digestive and Kidney Disease National Institutes. The purpose of this dataset is to diagnose whether or not a patient is diabetic, on the basis of certain diagnostic measures in the dataset. The selection of these instances from a larger database was subject to several restrictions. All patients are women from the Indian heritage of Pima, at least 21 years old.
The data sets comprise several variables of the medical predictor, and one objective variable, Outcome. The forecasting variables include the patient’s number of pregnancies, BMI levels, insulin levels, age, etc.
Smith, J.W., Everhart, J.E., Dickson, W.C., Knowler, W.C., & Johannes, R.S. (1988). Using the ADAP learning algorithm to forecast the onset of diabetes mellitus. In Proceedings of the Symposium on Computer Applications and Medical Care (pp. 261–265). IEEE Computer Society Press.
Can you build a machine learning model to accurately predict whether or not the patients in the dataset have diabetes or not?
Imports
import numpy as npimport pandas as pd# Visualization importsimport matplotlib.pyplot as pltimport seaborn as sns# plotly import for Colabdef configure_plotly_browser_state():  import IPython  display(IPython.core.display.HTML('''        <script src="/static/components/requirejs/require.js"></script>        <script>          requirejs.config({            paths: {              base: '/static/base',              plotly: 'https://cdn.plot.ly/plotly-latest.min.js?noext',            },          });        </script>        '''))  # plotly importimport plotly.express as pxfrom plotly import __version__import cufflinks as cffrom plotly.offline import download_plotlyjs,init_notebook_mode,plot,iplotinit_notebook_mode(connected=True)cf.go_offline()import IPythonIPython.get_ipython().events.register('pre_run_cell', configure_plotly_browser_state)
Dataset
# Loading Datasetdf = pd.read_csv('/content/drive/My Drive/dataset/knn/datasets_228_482_diabetes.csv')df.head()
‘0’ value in below columns makes no sense. Hence making them NaN.
df[['Glucose','BloodPressure','SkinThickness','Insulin','BMI']] = df[['Glucose','BloodPressure','SkinThickness','Insulin','BMI']].replace(0,np.NaN)df.isnull().sum()
import missingno as msnop = msno.bar(df)
!pip install impyuteimport sysfrom impyute.imputation.cs import fast_knnsys.setrecursionlimit(100000) #Increase the recursion limit of the OS# start the KNN trainingimputed_training=fast_knn(df[['Glucose','BloodPressure','SkinThickness','Insulin','BMI']].values, k=30)df_t1 = pd.DataFrame(imputed_training,columns=['Glucose','BloodPressure','SkinThickness','Insulin','BMI'])df[['Glucose','BloodPressure','SkinThickness','Insulin','BMI']] = df_t1[['Glucose','BloodPressure','SkinThickness','Insulin','BMI']]df.isnull().sum()
df.info()
df.describe()
sns.heatmap(df.corr(),annot=True)
p = df[df['Outcome']==1].hist(figsize = (20,20))plt.title('Diabetes Patient')
KNN Visualization all features with Outcome
X = df[[‘Pregnancies’, ‘Glucose’, ‘BloodPressure’, ‘SkinThickness’, ‘Insulin’,’BMI’, ‘DiabetesPedigreeFunction’, ‘Age’]]
y = df[‘Outcome’]
Note: 0 — Non Diabetic Patient and 1 — Diabetic Patient
from sklearn.decomposition import PCAfrom mlxtend.plotting import plot_decision_regionsfrom sklearn.svm import SVCclf = SVC(C=100,gamma=0.0001)pca = PCA(n_components = 2)X_train2 = pca.fit_transform(X)clf.fit(X_train2, df['Outcome'].astype(int).values)plot_decision_regions(X_train2, df['Outcome'].astype(int).values, clf=clf, legend=2)
KNN features visualization with each other:
from sklearn import datasets, neighborsfrom mlxtend.plotting import plot_decision_regionsdef ok(X,Y):  x = df[[X,Y]].values  y = df['Outcome'].astype(int).values  clf = neighbors.KNeighborsClassifier(n_neighbors=9)  clf.fit(x, y)  # Plotting decision region  plot_decision_regions(x, y, clf=clf, legend=2)  # Adding axes annotations  plt.xlabel(X)  plt.ylabel(Y)  plt.title('Knn with K='+ str(9))  plt.show()tt = ['Pregnancies', 'Glucose', 'BloodPressure', 'SkinThickness', 'Insulin','BMI', 'DiabetesPedigreeFunction', 'Age']ll = len(tt)for i in range(0,ll):  for j in range(i+1,ll):    ok(tt[i],tt[j])
Note: 0 — Non Diabetic and 1 — Diabetic
Data Z is rescaled to μ = 0 and ρ = 1, and this form is applied:
from sklearn.preprocessing import StandardScalerscaler = StandardScaler()scaler.fit(df.drop('Outcome', axis = 1))scaler_features = scaler.transform(df.drop('Outcome', axis = 1))df_feat = pd.DataFrame(scaler_features, columns = df.columns[:-1])# appending the outcome featuredf_feat['Outcome'] = df['Outcome'].astype(int)df = df_feat.copy()df.head()
# to reverse scaler transformation#s = scaler.inverse_transform(df_feat)#df_feat = pd.DataFrame(s, columns = df.columns[:-1])
Split
X = df.drop('Outcome', axis = 1)y = df['Outcome']from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(  X, y, test_size=0.3, random_state=0)
Check for the best K value by getting Receiver Operating Characteristic Accuracy for each K ranging from 1 to 100
import sklearntt = {}il = []ac=[]for  i in range(1,100):  from sklearn.neighbors import KNeighborsClassifierknn = KNeighborsClassifier(n_neighbors=i)knn.fit(X_train,y_train)y_pred = knn.predict(X_test)from sklearn.metrics import accuracy_score  il.append(i)  ac.append( sklearn.metrics.roc_auc_score(y_test,y_pred) )tt.update({'K':il})  tt.update({'ROC_ACC':ac})vv = pd.DataFrame(tt)vv.sort_values('ROC_ACC',ascending=False,inplace=True,ignore_index=True)vv.head(10)
Selecting ‘k = 9’
from sklearn.neighbors import KNeighborsClassifierknn = KNeighborsClassifier(n_neighbors=9)knn.fit(X_train,y_train)y_pred = knn.predict(X_test)from sklearn.metrics import classification_reportprint(classification_report(y_test,y_pred))
from sklearn.metrics import confusion_matrixprint(confusion_matrix(y_test,y_pred))sns.heatmap(confusion_matrix(y_test,y_pred),annot=True)
from sklearn.metrics import roc_curveplt.figure(dpi=100)fpr, tpr, thresholds = roc_curve(y_test, y_pred)plt.plot(fpr,tpr,label = "%.2f" %sklearn.metrics.roc_auc_score(y_test,y_pred))plt.legend(loc = 'lower right')plt.xlim([0.0, 1.0])plt.ylim([0.0, 1.0])plt.title('ROC curve for Diabetes classifier')plt.xlabel('False positive rate (1-Specificity)')plt.ylabel('True positive rate (Sensitivity)')plt.grid(True)
import sklearnsklearn.metrics.roc_auc_score(y_test,y_pred)
0.7399724565329662
data = {'test':y_test.values.ravel(),'pred':y_pred.ravel(),'number':np.arange(0,len(y_test))}pt = pd.DataFrame(data)pt.iplot(            kind='scatter',            x='number',            y=['test','pred'],             color=['white','yellow'],            theme='solar',            mode='lines+markers'          )