# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix
from sklearn.metrics import plot_confusion_matrix
import warnings as w
w.filterwarnings("ignore")
df = pd.read_csv('/kaggle/input/breast-cancer-csv/breastCancer.csv')
df
df.head(10)
df.shape
df.describe()
df.info()
df.columns
print(df['class'].value_counts()/6.99)
df['class'].value_counts()
"""
We can see here that our data is imbalanced.As the class 2 data is about 65% and class 4 is 34.5%.
"""
"""
Let's Check if there are any missing values present in the dataset.
"""
c = {col:df[df[col] == "?"].shape[0] for col in df.columns}
c
"""
Here we can see there are some missing values present in the 'bare_nucleoli' feature.
"""
import numpy as np
for i in range(df.shape[1]):
    for j in range(df.shape[0]):
        if(df.iloc[j,i]=='?'):
            df.iloc[j,i]=np.NaN
list(df['bare_nucleoli'].mode())
df["bare_nucleoli"]=df["bare_nucleoli"].apply(lambda x: 1.0 if pd.isnull(x) else x)
df.corr()
fig1 = plt.figure(figsize=(10,8))
sns.heatmap(df.corr(),annot=True,cmap='YlGnBu',vmax=1.0,vmin=-1.0)
fig2 = plt.figure(figsize=(6,6))
sns.pairplot(df.iloc[:,1:],hue='class',palette='Set2')
"""
**Applying the Train and Test split for splitting the data for applying the models.**
"""
X_train, X_test, y_train, y_test = train_test_split(df.iloc[:,1:-1],df.iloc[:,-1])
print(X_train,"\n")
print(X_test,"\n")
print(y_train,"\n")
print(y_test,"\n")
print("The dimension of X_train is : ",X_train.shape,"\n")
print("The dimension of X_test is : ",X_test.shape,"\n")
print("The dimension of y_train is : ",y_train.shape,"\n")
print("The dimension of y_test is : ",y_test.shape,"\n")
"""
**Applying the K Nearest Neighbour algorithm**
"""
error_rate = []
for i in range(1,40):
    knn = KNeighborsClassifier(n_neighbors=i)
    knn.fit(X_train,y_train)
    pred = knn.predict(X_test)
    error_rate.append(np.mean(pred != y_test))
plt.figure(figsize=(10,6))
plt.plot(range(1,40), error_rate,'o--')
plt.ylabel('Error Rate')
plt.xlabel('K')
"""
***As we can see in above Error rate vs k plot the optimal values for k is 4.***
"""
model1 = KNeighborsClassifier(n_neighbors=4).fit(X_train,y_train)
fig3, axs = plt.subplots(figsize=(5,5))
plot_confusion_matrix(model1,X_test,y_test,ax=axs)
print(classification_report(model1.predict(X_train),y_train))
print(classification_report(model1.predict(X_test),y_test))
print(accuracy_score(y_test,pred))
"""
**Applying the GaussianNB Algorithm.**
"""
gaussnb = GaussianNB()
gaussnb.fit(X_train,y_train)
gaussnbpred = gaussnb.predict(X_test)
gaussnbresults = confusion_matrix(y_test,gaussnbpred)
gaussnbacc_score = accuracy_score(y_test,gaussnbpred)
print("The accuracy of NaiveBayes model is : %0.4f ", gaussnbacc_score)
print("The confusion matrix is :\n", gaussnbresults)
fig4, axs = plt.subplots(figsize=(5,5))
plot_confusion_matrix(gaussnb,X_test,y_test,ax=axs)
print(classification_report(y_test,gaussnbpred))
"""
**Applying Logistic Regression Model.**
"""
logreg = LogisticRegression()
logreg.fit(X_train,y_train)
logpred = logreg.predict(X_test)
logacc_score = accuracy_score(y_test,logpred)
logresults = confusion_matrix(y_test,logpred)
print("The accuracy of Logistic Regression is : %0.4f", logacc_score)
print("The confusion matrix is : \n ", logresults )
fig5, axs = plt.subplots(figsize=(5,5))
plot_confusion_matrix(logreg,X_test,y_test,ax=axs)
print(classification_report(y_test,logpred))
"""
1. After Applying all the Models like Knn,Logitic Regression & GaussianNB we have all the confusion matrix plot and the classification report of the models. 
2. From the above we choose the most accurate algorithm.
"""