"""
<h1 style="color:Orange;"><center>Pima Indians Diabetes - EDA and Prediction</center></h1> 
"""
"""
Table of Contents:
1. [Introduction](#1)
    - 1.1 [Context](#2)
    - 1.2 [Data Dictionary](#3)
    - 1.3 [Task](#4)
2. [Preparation](#5)
    - 2.1 [Packages](#6)
    - 2.2 [Data](#7)
    - 2.3 [Understanding Data](#8)
3. [Exploratory Data Analysis](#9)
    - 3.1 [Univariate Analysis](#10)
    - 3.2 [Bivariate Analysis](#11)
4. [Data Preprocessing](#12)
    - 4.1 [Conclusions from EDA](#13)
    - 4.2 [Removing the outliers](#14)
    - 4.3 [Removing the skewness](#15)
    - 4.4 [Making features model ready](#16)
5. [Modeling](#17)
    - 5.1 [Packages](#18)
    - 5.1 [Train/test split](#19)
    - 5.2 [Base Modeling](#20)
    - 5.3 [Hyperparameter tuning using GridSearchCV](#21)
    - 5.4 [Bayesian Optimization with gausian process](#22)
"""
"""
### 1. Introduction <a id=1></a>
"""
"""
#### 1.1 Context <a id=2></a>
This dataset is originally from the National Institute of Diabetes and Digestive and Kidney Diseases. The objective of the dataset is to diagnostically predict whether or not a patient has diabetes, based on certain diagnostic measurements included in the dataset. Several constraints were placed on the selection of these instances from a larger database. In particular, all patients here are females at least 21 years old of Pima Indian heritage.
"""
"""
#### 1.2 Data Dictionary <a id=3></a>
`Pregnancies` - Number of times pregnant

`Glucose` - Plasma glucose concentration - 2 hours in an oral glucose tolerance test

`BloodPressure` - Diastolic blood pressure (mm Hg)

`SkinThickness` - Triceps skin fold thickness (mm)

`Insulin` - 2-Hour serum insulin (mu U/ml)

`BMI` - Body mass index

`DiabetesPedigreeFunction` - Diabetes pedigree function

`Age` - Age (years)

`Outcome` - Class variable (0 or 1)
"""
"""
#### 1.3 Task <a id=4></a>
To predict the onset of diabetes based on diagnostic measures.
"""
"""
### 2. Preparation <a id=5></a>
"""
"""
#### 2.1 Packages <a id=6></a>
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import plotly.express as px
import seaborn as sns

import warnings
from termcolor import colored
warnings.filterwarnings("ignore")
"""
#### 2.2 Data <a id=7></a>
"""
df = pd.read_csv('/kaggle/input/pima-indians-diabetes-database/diabetes.csv')
"""
#### 2.3 Understanding Data <a id=8></a>
"""
"""
##### 2.3.1 The shape of the data
"""
print(f"Shape of dataset: {colored(df.shape, 'yellow')}")
"""
##### 2.3.2 Preview of the first five rows of the data
"""
df.head()
"""
##### 2.3.3 Renaming `DiabetesPedigreeFunction` to `DPF` for better consistency
"""
df = df.rename(columns = {'DiabetesPedigreeFunction':'DPF'})
"""
##### 2.3.4 Checking the number of unique values in each column
"""
dict = {}
for i in list(df.columns):
    dict[i] = df[i].value_counts().shape[0]

pd.DataFrame(dict,index=["unique count"]).transpose()
"""
##### 2.3.5 Separating into features and targets
"""
con_cols = list(df.drop('Outcome',axis=1).columns)
target = ['Outcome']
print(f"The columns are : {colored(con_cols, 'yellow')}")
print(f"The target is   : {colored(target,'yellow')}")
"""
##### 2.3.6 Summary statistics
"""
df[con_cols].describe().transpose()
"""
##### 2.3.6 Missing values
"""
df.isnull().sum()
"""
### 3. Exploratory Data Analysis <a id=9></a>
"""
"""
#### 3.1 Univariate Analysis <a id=10></a>
"""
"""
##### 3.1.1 Count of target variable
"""
fig = plt.figure(figsize=(18,7))
gs = fig.add_gridspec(1,2)
gs.update(wspace=0.3, hspace=0.15)
ax0 = fig.add_subplot(gs[0,0])
ax1 = fig.add_subplot(gs[0,1])

background_color = "#c9c9ee"
color_palette = ["#f56476","#ff8811","#001427","#6369d1","#f0f66e"]
fig.patch.set_facecolor(background_color) 
ax0.set_facecolor(background_color) 
ax1.set_facecolor(background_color)

# Title of the plot
ax0.text(0.5,0.5,"Count of the target\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')

ax0.set_xticklabels([])
ax0.set_yticklabels([])
ax0.tick_params(left=False, bottom=False)

# Target Count
ax1.text(0.45,510,"Output",fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax1.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.countplot(ax=ax1, data=df, x = 'Outcome',palette = color_palette)
ax1.set_xlabel("")
ax1.set_ylabel("")
ax1.set_xticklabels(["Low chances of diabetes(0)","High chances of diabetes(1)"])

ax0.spines["top"].set_visible(False)
ax0.spines["left"].set_visible(False)
ax0.spines["bottom"].set_visible(False)
ax0.spines["right"].set_visible(False)
ax1.spines["top"].set_visible(False)
ax1.spines["left"].set_visible(False)
ax1.spines["right"].set_visible(False)
"""
##### 3.1.2 Boxenplot of features
"""
fig = plt.figure(figsize=(18,15))
gs = fig.add_gridspec(3,3)
gs.update(wspace=0.5, hspace=0.25)
ax0 = fig.add_subplot(gs[0,0])
ax1 = fig.add_subplot(gs[0,1])
ax2 = fig.add_subplot(gs[0,2])
ax3 = fig.add_subplot(gs[1,0])
ax4 = fig.add_subplot(gs[1,1])
ax5 = fig.add_subplot(gs[1,2])
ax6 = fig.add_subplot(gs[2,0])
ax7 = fig.add_subplot(gs[2,1])
ax8 = fig.add_subplot(gs[2,2])

background_color = "#c9c9ee"
# c9c9ee
color_palette = ["#f56476","#ff8811","#ff0040","#ff7f6c","#f0f66e","#990000"]
fig.patch.set_facecolor(background_color) 
ax0.set_facecolor(background_color) 
ax1.set_facecolor(background_color)
ax2.set_facecolor(background_color)
ax3.set_facecolor(background_color)
ax4.set_facecolor(background_color)
ax5.set_facecolor(background_color)
ax6.set_facecolor(background_color)
ax7.set_facecolor(background_color)
ax8.set_facecolor(background_color)

# Title of the plot
ax0.spines["bottom"].set_visible(False)
ax0.spines["left"].set_visible(False)
ax0.spines["top"].set_visible(False)
ax0.spines["right"].set_visible(False)
ax0.tick_params(left=False, bottom=False)
ax0.set_xticklabels([])
ax0.set_yticklabels([])
ax0.text(0.5,0.5,
         'Boxenplot plot for various\n features\n_________________',
         horizontalalignment='center',
         verticalalignment='center',
         fontsize=18, fontweight='bold',
         fontfamily='serif',
         color="#000000")

# Pregnancies 
ax1.text(-0.18, 19, 'Pregnancies', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax1.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.boxenplot(ax=ax1,y=df['Pregnancies'],palette=["#f56476"],width=0.6)
ax1.set_xlabel("")
ax1.set_ylabel("")

# Glucose 
ax2.text(-0.1, 217, 'Glucose', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax2.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.boxenplot(ax=ax2,y=df['Glucose'],palette=["#ff8811"],width=0.6)
ax2.set_xlabel("")
ax2.set_ylabel("")

# BloodPressure 
ax3.text(-0.20, 132, 'BloodPressure', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax3.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.boxenplot(ax=ax3,y=df['BloodPressure'],palette=["#ff0040"],width=0.6)
ax3.set_xlabel("")
ax3.set_ylabel("")

# SkinThickness 
ax4.text(-.2, 110, 'SkinThickness', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax4.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.boxenplot(ax=ax4,y=df['SkinThickness'],palette=["#ff7f6c"],width=0.6)
ax4.set_xlabel("")
ax4.set_ylabel("")

# Insulin 
ax5.text(-0.10, 900, 'Insulin', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax5.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.boxenplot(ax=ax5,y=df['Insulin'],palette=["#f0f66e"],width=0.6)
ax5.set_xlabel("")
ax5.set_ylabel("")

# BMI 
ax6.text(-0.08, 77, 'BMI', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax6.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.boxenplot(ax=ax6,y=df['BMI'],palette=["#990000"],width=0.6)
ax6.set_xlabel("")
ax6.set_ylabel("")

# DPF 
ax7.text(-0.065, 2.8, 'DPF', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax7.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.boxenplot(ax=ax7,y=df['DPF'],palette=["#3339FF"],width=0.6)
ax7.set_xlabel("")
ax7.set_ylabel("")

# Age 
ax8.text(-0.08, 86, 'Age', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax8.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.boxenplot(ax=ax8,y=df['Age'],palette=["#34495E"],width=0.6)
ax8.set_xlabel("")
ax8.set_ylabel("")



for s in ["top","right","left"]:
    ax1.spines[s].set_visible(False)
    ax2.spines[s].set_visible(False)
    ax3.spines[s].set_visible(False)
    ax4.spines[s].set_visible(False)
    ax5.spines[s].set_visible(False)
    ax6.spines[s].set_visible(False)
    ax7.spines[s].set_visible(False)
    ax8.spines[s].set_visible(False)
"""
##### 3.1.3 Histogram of features
"""
fig = plt.figure(figsize=(18,15))
gs = fig.add_gridspec(3,3)
gs.update(wspace=0.5, hspace=0.25)
ax0 = fig.add_subplot(gs[0,0])
ax1 = fig.add_subplot(gs[0,1])
ax2 = fig.add_subplot(gs[0,2])
ax3 = fig.add_subplot(gs[1,0])
ax4 = fig.add_subplot(gs[1,1])
ax5 = fig.add_subplot(gs[1,2])
ax6 = fig.add_subplot(gs[2,0])
ax7 = fig.add_subplot(gs[2,1])
ax8 = fig.add_subplot(gs[2,2])

background_color = "#c9c9ee"
# c9c9ee
color_palette = ["#f56476","#ff8811","#ff0040","#ff7f6c","#f0f66e","#990000"]
fig.patch.set_facecolor(background_color) 
ax0.set_facecolor(background_color) 
ax1.set_facecolor(background_color)
ax2.set_facecolor(background_color)
ax3.set_facecolor(background_color)
ax4.set_facecolor(background_color)
ax5.set_facecolor(background_color)
ax6.set_facecolor(background_color)
ax7.set_facecolor(background_color)
ax8.set_facecolor(background_color)

# Title of the plot
ax0.spines["bottom"].set_visible(False)
ax0.spines["left"].set_visible(False)
ax0.spines["top"].set_visible(False)
ax0.spines["right"].set_visible(False)
ax0.tick_params(left=False, bottom=False)
ax0.set_xticklabels([])
ax0.set_yticklabels([])
ax0.text(0.5,0.5,
         'Histogram for various\n features\n_________________',
         horizontalalignment='center',
         verticalalignment='center',
         fontsize=18, fontweight='bold',
         fontfamily='serif',
         color="#000000")

# Pregnancies 
ax1.text(4, 260, 'Pregnancies', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax1.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.histplot(ax=ax1,x=df['Pregnancies'],color="#f56476",kde=True)
ax1.set_xlabel("")
ax1.set_ylabel("")

# Glucose 
ax2.text(55, 105, 'Glucose', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax2.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.histplot(ax=ax2,x=df['Glucose'],color="#ff8811",kde=True)
ax2.set_xlabel("")
ax2.set_ylabel("")

# BloodPressure 
ax3.text(35, 115, 'BloodPressure', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax3.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.histplot(ax=ax3,x=df['BloodPressure'],color="#ff0040",kde=True)
ax3.set_xlabel("")
ax3.set_ylabel("")

# SkinThickness 
ax4.text(25, 250, 'SkinThickness', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax4.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.histplot(ax=ax4,x=df['SkinThickness'],color="#ff7f6c",kde=True)
ax4.set_xlabel("")
ax4.set_ylabel("")

# Insulin 
ax5.text(250, 430, 'Insulin', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax5.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.histplot(ax=ax5,x=df['Insulin'],color="#f0f66e",kde=True)
ax5.set_xlabel("")
ax5.set_ylabel("")

# BMI 
ax6.text(25, 100, 'BMI', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax6.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.histplot(ax=ax6,x=df['BMI'],palette=["#990000"],kde=True)
ax6.set_xlabel("")
ax6.set_ylabel("")

# DPF 
ax7.text(1, 150, 'DPF', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax7.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.histplot(ax=ax7,x=df['DPF'],color="#3339FF",kde=True)
ax7.set_xlabel("")
ax7.set_ylabel("")

# Age 
ax8.text(40, 230, 'Age', fontsize=14, fontweight='bold', fontfamily='serif', color="#000000")
ax8.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.histplot(ax=ax8,x=df['Age'],color="#34495E",kde=True)
ax8.set_xlabel("")
ax8.set_ylabel("")


for s in ["top","right","left"]:
    ax1.spines[s].set_visible(False)
    ax2.spines[s].set_visible(False)
    ax3.spines[s].set_visible(False)
    ax4.spines[s].set_visible(False)
    ax5.spines[s].set_visible(False)
    ax6.spines[s].set_visible(False)
    ax7.spines[s].set_visible(False)
    ax8.spines[s].set_visible(False)
"""
#### 3.2 Bivariate Analysis <a id=11></a>
"""
"""
##### 3.2.1 Correlation matrix of features
"""
df_corr = df.corr().transpose()
df_corr
fig = plt.figure(figsize=(10,10))
gs = fig.add_gridspec(1,1)
gs.update(wspace=0.3, hspace=0.15)
ax0 = fig.add_subplot(gs[0,0])
fig.patch.set_facecolor(background_color) 
ax0.set_facecolor(background_color) 

df_corr = df[con_cols].corr().transpose()
mask = np.triu(np.ones_like(df_corr))
ax0.text(2,-0.1,"Correlation Matrix",fontsize=22, fontweight='bold', fontfamily='serif', color="#000000")
sns.heatmap(df_corr,mask=mask,fmt=".1f",annot=True)
plt.show()
"""
##### 3.2.2 Distribution of features according to target variable
"""
fig = plt.figure(figsize=(18,25))
gs = fig.add_gridspec(8,2)
gs.update(wspace=0.5, hspace=0.5)
ax0 = fig.add_subplot(gs[0,0])
ax1 = fig.add_subplot(gs[0,1])
ax2 = fig.add_subplot(gs[1,0])
ax3 = fig.add_subplot(gs[1,1])
ax4 = fig.add_subplot(gs[2,0])
ax5 = fig.add_subplot(gs[2,1])
ax6 = fig.add_subplot(gs[3,0])
ax7 = fig.add_subplot(gs[3,1])
ax8 = fig.add_subplot(gs[4,0])
ax9 = fig.add_subplot(gs[4,1])
ax10 = fig.add_subplot(gs[5,0])
ax11 = fig.add_subplot(gs[5,1])
ax12 = fig.add_subplot(gs[6,0])
ax13 = fig.add_subplot(gs[6,1])
ax14 = fig.add_subplot(gs[7,0])
ax15 = fig.add_subplot(gs[7,1])


background_color = "#c9c9ee"
color_palette = ["#f56476","#ff8811","#ff0040","#ff7f6c","#f0f66e","#990000"]
fig.patch.set_facecolor(background_color) 
ax0.set_facecolor(background_color) 
ax1.set_facecolor(background_color) 
ax2.set_facecolor(background_color)
ax3.set_facecolor(background_color)
ax4.set_facecolor(background_color)
ax5.set_facecolor(background_color) 
ax6.set_facecolor(background_color) 
ax7.set_facecolor(background_color)
ax8.set_facecolor(background_color)
ax9.set_facecolor(background_color)
ax10.set_facecolor(background_color)
ax11.set_facecolor(background_color)
ax12.set_facecolor(background_color)
ax13.set_facecolor(background_color)
ax14.set_facecolor(background_color)
ax15.set_facecolor(background_color)

# Pregnancies title
ax0.text(0.5,0.5,"Distribution of Pregnancies\naccording to\n target variable\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')
ax0.spines["bottom"].set_visible(False)
ax0.set_xticklabels([])
ax0.set_yticklabels([])
ax0.tick_params(left=False, bottom=False)

# Pregnancies
ax1.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.kdeplot(ax=ax1, data=df, x='Pregnancies',hue="Outcome", fill=True,palette=["#ff8811","#3339FF"], alpha=.5, linewidth=0)
ax1.set_xlabel("")
ax1.set_ylabel("")

# Glucose title
ax2.text(0.5,0.5,"Distribution of Glucose\naccording to\n target variable\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')
ax2.spines["bottom"].set_visible(False)
ax2.set_xticklabels([])
ax2.set_yticklabels([])
ax2.tick_params(left=False, bottom=False)

# Glucose
ax3.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.kdeplot(ax=ax3, data=df, x='Glucose',hue="Outcome", fill=True,palette=["#ff8811","#3339FF"], alpha=.5, linewidth=0)
ax3.set_xlabel("")
ax3.set_ylabel("")

# BloodPressure title
ax4.text(0.5,0.5,"Distribution of BloodPressure\naccording to\n target variable\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')
ax4.spines["bottom"].set_visible(False)
ax4.set_xticklabels([])
ax4.set_yticklabels([])
ax4.tick_params(left=False, bottom=False)

# BloodPressure
ax5.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.kdeplot(ax=ax5, data=df, x='BloodPressure',hue="Outcome", fill=True,palette=["#ff8811","#3339FF"], alpha=.5, linewidth=0)
ax5.set_xlabel("")
ax5.set_ylabel("")

# SkinThickness title
ax6.text(0.5,0.5,"Distribution of SkinThickness\naccording to\n target variable\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')
ax6.spines["bottom"].set_visible(False)
ax6.set_xticklabels([])
ax6.set_yticklabels([])
ax6.tick_params(left=False, bottom=False)

# SkinThickness
ax7.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.kdeplot(ax=ax7, data=df, x='SkinThickness',hue="Outcome", fill=True,palette=["#ff8811","#3339FF"], alpha=.5, linewidth=0)
ax7.set_xlabel("")
ax7.set_ylabel("")

# Insulin title
ax8.text(0.5,0.5,"Distribution of Insulin\naccording to\n target variable\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')
ax8.spines["bottom"].set_visible(False)
ax8.set_xticklabels([])
ax8.set_yticklabels([])
ax8.tick_params(left=False, bottom=False)

# Insulin
ax9.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.kdeplot(ax=ax9, data=df, x='Insulin',hue="Outcome", fill=True,palette=["#ff8811","#3339FF"], alpha=.5, linewidth=0)
ax9.set_xlabel("")
ax9.set_ylabel("")

# BMI title
ax10.text(0.5,0.5,"Distribution of BMI\naccording to\n target variable\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')
ax10.spines["bottom"].set_visible(False)
ax10.set_xticklabels([])
ax10.set_yticklabels([])
ax10.tick_params(left=False, bottom=False)

# BMI
ax11.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.kdeplot(ax=ax11, data=df, x='BMI',hue="Outcome", fill=True,palette=["#ff8811","#3339FF"], alpha=.5, linewidth=0)
ax11.set_xlabel("")
ax11.set_ylabel("")

# DPF title
ax12.text(0.5,0.5,"Distribution of DPF\naccording to\n target variable\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')
ax12.spines["bottom"].set_visible(False)
ax12.set_xticklabels([])
ax12.set_yticklabels([])
ax12.tick_params(left=False, bottom=False)

# DPF
ax13.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.kdeplot(ax=ax13, data=df, x='DPF',hue="Outcome", fill=True,palette=["#ff8811","#3339FF"], alpha=.5, linewidth=0)
ax13.set_xlabel("")
ax13.set_ylabel("")

# Age title
ax14.text(0.5,0.5,"Distribution of Age\naccording to\n target variable\n___________",
        horizontalalignment = 'center',
        verticalalignment = 'center',
        fontsize = 18,
        fontweight='bold',
        fontfamily='serif',
        color='#000000')
ax14.spines["bottom"].set_visible(False)
ax14.set_xticklabels([])
ax14.set_yticklabels([])
ax14.tick_params(left=False, bottom=False)

# Age
ax15.grid(color='#000000', linestyle=':', axis='y', zorder=0,  dashes=(1,5))
sns.kdeplot(ax=ax15, data=df, x='Age',hue="Outcome", fill=True,palette=["#ff8811","#3339FF"], alpha=.5, linewidth=0)
ax15.set_xlabel("")
ax15.set_ylabel("")



for i in ["top","left","right"]:
    ax0.spines[i].set_visible(False)
    ax1.spines[i].set_visible(False)
    ax2.spines[i].set_visible(False)
    ax3.spines[i].set_visible(False)
    ax4.spines[i].set_visible(False)
    ax5.spines[i].set_visible(False)
    ax6.spines[i].set_visible(False)
    ax7.spines[i].set_visible(False)
    ax8.spines[i].set_visible(False)
    ax9.spines[i].set_visible(False)
    ax10.spines[i].set_visible(False)
    ax11.spines[i].set_visible(False)
    ax12.spines[i].set_visible(False)
    ax13.spines[i].set_visible(False)
    ax14.spines[i].set_visible(False)
    ax15.spines[i].set_visible(False)

"""
##### 3.2.3 Pair plot - one plot to rule them all
"""
sns.pairplot(df,hue='Outcome',palette = ["#ff8811","#3339FF"])
plt.show()
"""
##### 3.2.4 Scatter plot of BloodPressure vs Glucose vs Age wrt Outcome 
"""
fig = px.scatter_3d(df, x='Age', y='Glucose', z='BloodPressure',
              color='Outcome',size_max=18,color_continuous_scale=["#3339FF", "#ff8811"])
fig.update_layout({"template":"plotly_dark"})
fig.show()
"""
##### 3.2.5 Scatter plot of Glucose vs Insulin vs DPF wrt Outcome 
"""
fig = px.scatter_3d(df, x='Glucose', y='Insulin', z='DPF',
              color='Outcome',size_max=18,color_continuous_scale=["#3339FF", "#ff8811"])
fig.update_layout({"template":"plotly_dark"})
fig.show()
"""
### 4. Data Preprocessing <a id=12></a>
"""
"""
#### 4.1 Conclusions from EDA <a id=13></a>
1. There are no NaN values in the data.
2. They are a very less number of outliers in all features.
3. There is no apparent linear correlation between feature variable according to the heatmap.
4. The distribution curve of `insulin` and `DPF` is right skewed.
5. The distribution curve of `Glucose` wrt `Outcome` shows that there are less number of people with high Glucose level but they have higher chances of diabetes.
6. The `BloodPressure` lies between 40 and 100, and there are less number of people with diabetes in this range.
7. The plots `3.2.3` tells the following -
    - Over the `Pregnancy` range, females with high glucose have Diabetes.
    - As `Insulin` increase, and as `Glucose`, there are higher chances of Diabetes.
    - As `BMI` increase, and as `Glucose`, there are higher chances of Diabetes.
    - `Age` alone isn't really an indicator of Diabetes.
8. Middle aged people with high `Glucose` level and high `BloodPressure` level have higher chances of Diabetes which is quite intuitive as well.

"""
"""
#### 4.2 Removing the outliers <a id=14></a>
"""
"""
##### 4.2.1 The shape of dataset before removing the outliers
"""
print(f"Shape of dataset: {colored(df.shape, 'yellow')}")
"""
##### 4.2.2 Removing the outliers and checking the shape
"""
df.drop(df[df["Pregnancies"] > 14].index,inplace=True)
df.drop(df[df["Glucose"] < 50].index,inplace=True)
df.drop(df[df["BloodPressure"] > 120].index,inplace=True)
df.drop(df[df["SkinThickness"] > 80].index,inplace=True)
df.drop(df[df["Insulin"] > 600].index,inplace=True)
df.drop(df[df["BMI"] > 55].index,inplace=True)
df.drop(df[df["DPF"] > 2].index,inplace=True)
df.drop(df[df["Age"] > 70].index,inplace=True)

print(f"Shape of dataset: {colored(df.shape, 'yellow')}")
"""
#### 4.3 Removing the skewness <a id=15></a>
"""
"""
##### 4.3.1 Checking the distribution of `Insulin`
"""
sns.kdeplot(df['Insulin'],color='Orange',fill=True)
"""
##### 4.3.2 Removing the skewness using a log function and checking the distribution again
"""
df['Insulin'] = df['Insulin'].map(lambda i : np.log(i) if i > 0 else 0)
sns.kdeplot(df['Insulin'],color='Orange',fill=True)
"""
#### 4.4 Making features model ready <a id=16></a>
"""
# importing the scaler
from sklearn.preprocessing import StandardScaler

# creating a copy of dataframe
df1 = df
col_cols = list(df1.columns)

# removing the target variable from the columns list
col_cols.pop() 

# separating the features and target 
X = df1.drop(['Outcome'],axis=1)
y = df1[['Outcome']]

# instantiating the scaler
scaler = StandardScaler()
X[col_cols] = scaler.fit_transform(X[col_cols])
print("The first 5 rows of X are")
X.head()
"""
### 5. Modeling <a id=17></a>
"""
"""
#### 5.1 Packages <a id=18></a>
"""
# Train test split
from sklearn.model_selection import train_test_split

# Base Models
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegression

# Ensembling and Boosting
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier

# Metrics
from sklearn.metrics import accuracy_score, classification_report, roc_curve

# Cross Validation
from sklearn.model_selection import cross_val_score

# Hyper-parameter tuning
from functools import partial
from skopt import gp_minimize
from skopt import space
from sklearn import model_selection
from sklearn.model_selection import GridSearchCV, RandomizedSearchCV
"""
#### 5.2 Train/test split <a id=19></a>
"""
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,y , test_size = 0.2, random_state = 42)
print(f"The shape of X_train is      {colored(X_train.shape,'yellow')}")
print(f"The shape of X_test is       {colored(X_test.shape,'yellow')}")
print(f"The shape of y_train is      {colored(y_train.shape,'yellow')}")
print(f"The shape of y_test is       {colored(y_test.shape,'yellow')}")
"""
#### 5.3 Base Modeling <a id=20></a>
"""
"""
##### 5.3.1 Training the data with base models without any hyper-parameter tuning
"""
models = [
    ('SVC', SVC()),
    ('DecisionTreeClassifier',DecisionTreeClassifier()),
    ('KNeighborsClassifier',KNeighborsClassifier()),
    ('LogisticRegression',LogisticRegression()),
    ('RandomForestClassifier',RandomForestClassifier()),
    ('AdaBoostClassifier',AdaBoostClassifier()),
    ('GradientBoostingClassifier',GradientBoostingClassifier())
]

print("The accuracy scores of the models are :")
for model_name, model in models:
    model.fit(X_train, y_train)
    y_pred = model.predict(X_test)
    print(f"{colored(model_name,'blue')}")
    print(f"{colored(accuracy_score(y_test,y_pred), 'yellow')}\n")
"""
#### 5.4 Hyperparameter tuning using GridSearchCV <a id=21></a>
"""
"""
##### 5.4.1 Decision Tree Classifier tuning
"""
# define the model
classifier = DecisionTreeClassifier()

# define a grid of parameters
param_grid = {'criterion':['gini','entropy'],
              'splitter':['best','random'],
              'max_depth':[2,3,4,5,6,7,8],
              'max_features':['auto','sqrt','log2'],
             }

# initialize grid search
model = GridSearchCV(
estimator=classifier, param_grid=param_grid, scoring="accuracy", verbose=10,
n_jobs=1,
cv=5 )

# fit the model and extract best score
model.fit(X,y)
print(f"{colored('Decision Tree Classifier', 'blue')}")
print(f"Best score : {colored(model.best_score_,'yellow')}")

print("Best parameters set:")
best_parameters = model.best_estimator_.get_params()
for param_name in sorted(param_grid.keys()):
    print(f"\t{param_name}: {colored(best_parameters[param_name],'yellow')}")
"""
##### 5.4.2 K Neighbors Classifier tuning
"""
# define the model
classifier = KNeighborsClassifier()

# define a grid of parameters
param_grid = {'n_neighbors':[2,3,4,5,6,7,8],
              'weights':['uniform','distance'],
              'algorithm':['auto','ball_tree','kd_tree','brute'],
              'leaf_size':[26,27,28,29,30,31]
             }

# initialize grid search
model = GridSearchCV(
estimator=classifier, param_grid=param_grid, scoring="accuracy", verbose=10,
n_jobs=1,
cv=5 )

# fit the model and extract best score
model.fit(X,y)
print(f"{colored('K Neighbors Classifier', 'blue')}")
print(f"Best score : {colored(model.best_score_,'yellow')}")

print("Best parameters set:")
best_parameters = model.best_estimator_.get_params()
for param_name in sorted(param_grid.keys()):
    print(f"\t{param_name}: {colored(best_parameters[param_name],'yellow')}")
"""
### If you like the notebook, consider giving an upvote.
Check out my other notebooks
1. https://www.kaggle.com/namanmanchanda/star-wars-classifier
2. https://www.kaggle.com/namanmanchanda/gradient-descent-101
3. https://www.kaggle.com/namanmanchanda/cat-vs-dog-classifier-10-lines-of-code-fast-ai
"""