#importing packages
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
diabetes = pd.read_csv("../input/diabetes/diabetes.csv", sep = ",")
diabetes.head()
diabetes.isnull().sum()
data = diabetes.drop(['Pregnancies', 'Outcome'], axis = 1)
# Replacing 0 with nan values
data.replace(0, np.nan, inplace = True)
data.isnull().sum().sort_values(ascending = False)
"""
**Handling the missing values**
"""
# If data is continuous - replace by mean
# If data is discrete - replace by median
data['Insulin'].uniqueque()
# mean
np.round(data['Insulin'].mean())
data['Insulin'].replace(np.nan, np.round(data['Insulin'].mean()), inplace = True)
"""
**Imputer**
"""
from sklearn.impute import SimpleImputer
# strategy = 'median', 'mean'
impute = SimpleImputer(strategy = 'median')
data_array = impute.fit_transform(data)
data_array
diabetes_df = pd.DataFrame(data_array, columns= data.columns)
diabetes_df
diabetes_df['Pregnancies'] = diabetes.Pregnancies
diabetes_df['Outcome'] = diabetes.Outcome
diabetes_df.isnull().sum()
"""
**Data Augmentation**
* regenerating new samples using bootstrapping for biased dataset
* or else we can apply the weighted value 
"""
# number of samples for each class
diabetes_df['Outcome'].value_counts()
# resample uses "bootstrapping" method to regenerate samples by randomly selecting data for every class
from sklearn.utils import resample
df_0 = diabetes_df[diabetes_df['Outcome'] == 0]
df_1 = diabetes_df[diabetes_df['Outcome'] == 1]
# apply resample
df_1_upsample = resample(df_1, n_samples = 500, replace = True, random_state = 123) 
diabetes_df1 = pd.concat([df_0, df_1_upsample])
diabetes_df1['Outcome'].value_counts()
"""
**Data Features**
"""
plt.figure(figsize = (11,8))
sns.heatmap(diabetes_df1.corr(), annot = True)
"""
**Cross Validation**
"""
X = diabetes_df1.drop(['Outcome'], axis = 1)
Y = diabetes_df1['Outcome']
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 = 2)
"""
**ANN Classification**
"""
from keras.layers import Dense
from keras.models import Sequential
from keras.optimizers import Adam
def build_model():
    model = Sequential()

    # Input Layer
    model.add(Dense(units = 64, activation='relu', input_shape = [len(X.keys())]))

    # Hidden Layer - I
    model.add(Dense(units = 128, activation='relu'))

    # Hidden Layer - II
    model.add(Dense(units = 128, activation='relu'))

    # Output Layer
    model.add(Dense(units = 1, activation='sigmoid'))

    # learning rate for Adam Optimizers
    optimizers = Adam(learning_rate = 0.001)

    # Model compiler
    model.compile(loss = 'binary_crossentropy', optimizer = optimizers, metrics = ['accuracy'])
    
    return model 
model = build_model()
model.summary()
history = model.fit(X_train, Y_train, epochs = 500, batch_size= 25, validation_split = 0.2)
pd.DataFrame(history.history)[['accuracy','val_accuracy']].plot()
model.evaluate(X_test,Y_test)
"""
**Model is overfitted, we will add drop-out between layers**
"""
from keras.layers import Dropout

def build_model():
    model = Sequential()

    # Input Layer
    model.add(Dense(units = 64, activation='relu', input_shape = [len(X.keys())]))
    model.add(Dropout(0.2))

    # Hidden Layer - I
    model.add(Dense(units = 128, activation='relu'))
    model.add(Dropout(0.2))

    # Hidden Layer - II
    model.add(Dense(units = 128, activation='relu'))
    model.add(Dropout(0.2))
    
    # Output Layer
    model.add(Dense(units = 1, activation='sigmoid'))

    # learning rate for Adam Optimizers
    optimizers = Adam(learning_rate = 0.001)

    # Model compiler
    model.compile(loss = 'binary_crossentropy', optimizer = optimizers, metrics = ['accuracy'])
    
    return model 
model = build_model()
model.summary()
history = model.fit(X_train, Y_train, epochs = 500, batch_size= 25, validation_split = 0.2)
pd.DataFrame(history.history)[['accuracy','val_accuracy']].plot()
model.evaluate(X_test, Y_test)
"""
**Classification Report**
"""
predict = model.predict(X_test)
yhat = np.round(predict)
from sklearn.metrics import confusion_matrix
confusion_matrix(Y_test, yhat)

sns.heatmap(confusion_matrix(Y_test, yhat), annot = True)
from sklearn.metrics import classification_report
print(classification_report(Y_test, yhat))