"""
#          Epileptic Seizures Prediction Using Machine Learning Methods
"""
"""
# name:وعد خالد العنزي 
"""
"""
![image.png](attachment:37d84446-34ab-4d5f-b3c7-5dafe945b5cc.png)](http://)
"""
"""
# Features
"""
"""
# Read and Show Dataset
* The original dataset from the reference consists of 5 different folders, each with 100 files, with each file representing a single subject/person. Each file is a recording of brain activity for 23.6 seconds.


* The corresponding time-series is sampled into 4097 data points. Each data point is the value of the EEG recording at a different point in time. So we have total 500 individuals with each has 4097 data points for 23.5 seconds.


* We divided and shuffled every 4097 data points into 23 chunks, each chunk contains 178 data points for 1 second, and each data point is the value of the EEG recording at a different point in time.


* So now we have 23 x 500 = 11500 pieces of information(row), each information contains 178 data points for 1 second(column), the last column represents the label y {1,2,3,4,5}.


* The response variable is y in column 179, the Explanatory variables X1, X2, ..., X178

* The response variable is y in column 179, the Explanatory variables X1, X2, ..., X178, y contains the category of the 178-dimensional input vector. Specifically, y in {1, 2, 3, 4, 5}:

5 - eyes open, means when they were recording the EEG signal of the brain the patient had their eyes open.

4 - eyes closed, means when they were recording the EEG signal the patient had their eyes closed.

3 – Yes, they identify where the region of the tumor was in the brain and recording the EEG activity from the healthy brain area.

2 - They recorder the EEG from the area where the tumor was located.

1 - Recording of seizure activity.


All subjects falling in classes 2, 3, 4, and 5 are subjects who did not have epileptic seizure. Only subjects in class 1 have epileptic seizure.
"""
"""
#  Importing the libraries
"""
%%html
<style>
@import url('https://fonts.googleapis.com/css?family=Ewert|Roboto&effect=3d|ice|');
body {background-color: gainsboro;} 
a {color: #37c9e1; font-family: 'Roboto';} 
h1 {color: #37c9e1; font-family: 'Orbitron'; text-shadow: 4px 4px 4px #aaa;} 
h2, h3 {color: slategray; font-family: 'Orbitron'; text-shadow: 4px 4px 4px #aaa;}
h4 {color: #818286; font-family: 'Roboto';}
span {font-family:'Roboto'; color:black; text-shadow: 5px 5px 5px #aaa;}  
div.output_area pre{font-family:'Roboto'; font-size:110%; color:lightblue;}      
</style>
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
import numpy as np 
import pandas as pd 
import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))
sns.set_style("whitegrid")
plt.style.use("fivethirtyeight")
from sklearn.linear_model import LogisticRegression 
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, f1_score , classification_report
import seaborn as sns
classes=['healthy','Un-healthy']

from sklearn.naive_bayes import GaussianNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn import svm
from sklearn import metrics
"""
# Loading the data
"""
Epilepsy=pd.read_csv('../input/epilepticseizures/data.csv')
Epilepsy.drop('Unnamed: 0',axis=1,inplace=True)
Epilepsy.head()
"""
# 1. Exploratory Data Analysis (EDA)
"""
Epilepsy.info()
Epilepsy.shape
y = Epilepsy.iloc[:,178].values
y
"""
To make this a binary problem, let's turn the non-seizure classes 0 while maintaining the seizure as 1.
"""
y[y>1]=0
y
cols = Epilepsy.columns
tgt = Epilepsy.y
tgt[tgt>1]=0
ax = sns.countplot(tgt,label="Count")
non_seizure, seizure = tgt.value_counts()
print('The number of trials for the non-seizure class is:', non_seizure)
print('The number of trials for the seizure class is:', seizure)
Epilepsy.isna().sum()
Epilepsy.describe()
"""
# 2. Correlation Matrix
"""
Epilepsy.corr()
features_mean= list(Epilepsy.columns[1:11])
print(features_mean)
corr = Epilepsy[features_mean].corr() 
plt.figure(figsize=(12,8))
sns.heatmap(corr, cbar = True,  square = True, annot=True, fmt= '.2f',annot_kws={'size': 12},
           xticklabels= features_mean, yticklabels= features_mean,
           cmap= 'coolwarm')
"""
# 3. Data Processing
"""
"""
# Perform Feature Standerd Scalling
Standardize features by removing the mean and scaling to unit variance

The standard score of a sample x is calculated as:

z = (x - u) / s
"""
from sklearn.preprocessing import StandardScaler

prediction_var = ['X1', 'X2', 'X3', 'X4', 'X5']
train, test = train_test_split(Epilepsy, test_size = 0.3)
# we can check their dimension 
print(train.shape)
print(test.shape)
"""
# 4. Applying machine learning algorithms
"""
train_X = train[prediction_var]
train_y=train.y
test_X= test[prediction_var]
test_y =test.y
model=RandomForestClassifier(n_estimators=100)
model.fit(train_X,train_y)
prediction=model.predict(test_X)
from sklearn.metrics import accuracy_score, confusion_matrix, precision_score, recall_score, f1_score , classification_report
import seaborn as sns
classes=['healthy','Un-healthy']

def print_score(clf, X_train, y_train, X_test, y_test, train=True):
    if train:
        pred = clf.predict(X_train)
        print("Train Result:\n================================================")
        print(f"Accuracy Score: {accuracy_score(y_train, pred) * 100:.2f}%")
        print("_______________________________________________")
        print("Classification Report:", end='')
        print(f"\tPrecision Score: {precision_score(y_train, pred) * 100:.2f}%")
       # recall=recall_score(y_train, pred) 
        print(f"\t\t\tRecall Score: {recall_score(y_train, pred) * 100:.2f}%")
        print(f"\t\t\tF1 score: {f1_score(y_train, pred) * 100:.2f}%")
        print("_______________________________________________")
        print(f"Confusion Matrix: \n {confusion_matrix(y_train, pred)}\n")
        
    elif train==False:
        pred = clf.predict(X_test)
        print("Test Result:\n================================================")        
        print(f"Accuracy Score: {accuracy_score(y_test, pred) * 100:.2f}%")
        print("_______________________________________________")
        print("Classification Report:", end='')
        print(f"\tPrecision Score: {precision_score(y_test, pred) * 100:.2f}%")
        print(f"\t\t\tRecall Score: {recall_score(y_test, pred) * 100:.2f}%")
        print(f"\t\t\tF1 score: {f1_score(y_test, pred) * 100:.2f}%")
        print("_______________________________________________")
        sns.heatmap(confusion_matrix(y_test, pred), annot= True, cmap='YlGnBu',fmt = 'g')
        print(classification_report(y_test,pred))
        cm=(confusion_matrix(y_test,pred))
       # ax.xaxis.set_label_position('top')
        plt.tight_layout()
        plt.title('Confusion matrix for Decision Tree Model', y = 1.1)
        plt.ylabel('Actual label')
        plt.xlabel('Predicted label')
        plt.show()
        total = sum(sum(cm))
        acc = (cm[0, 0] + cm[1, 1]) / total
        sensitivity = cm[0, 0] / (cm[0, 0] + cm[0, 1])
        specificity = cm[1, 1] / (cm[1, 0] + cm[1, 1])
       # print(cm)

        FP = cm.sum(axis=0) - np.diag(cm)  
        FN = cm.sum(axis=1) - np.diag(cm)
        TP = np.diag(cm)
        TN = cm.sum() - (FP + FN + TP)

        FP = FP.astype(float)
        FN = FN.astype(float)
        TP = TP.astype(float)
        TN = TN.astype(float)

        # Sensitivity, hit rate, recall, or true positive rate
        TPR = TP/(TP+FN)
        print('Sensitivity (TPR) : ',TPR)
        # Specificity or true negative rate
        TNR = TN/(TN+FP) 
        print('Specificity (TNR) : ',TNR)
        # Overall accuracy
        print(" Overall accuracy")
        ACC = (TP+TN)/(TP+FP+FN+TN)
        print('Accuracy : ',ACC)
        print("Accuracy: {:.4f}".format(acc))
        print("Average Sensitivity: {:.4f}".format(sensitivity))
        print("Average Specificity: {:.4f}".format(specificity))
        print('\n')
        
        conf_matrix=cm
        print("=========================================")
        # save confusion matrix and slice into four pieces
        TP = conf_matrix[1][1]
        TN = conf_matrix[0][0]
        FP = conf_matrix[0][1]
        FN = conf_matrix[1][0]
        print('True Positives:', TP)
        print('True Negatives:', TN)
        print('False Positives:', FP)
        print('False Negatives:', FN)

        # calculate accuracy
        conf_accuracy = (float (TP+TN) / float(TP + TN + FP + FN))

        # calculate mis-classification
        conf_misclassification = 1- conf_accuracy

        # calculate the sensitivity
        conf_sensitivity = (TP / float(TP + FN))
        # calculate the specificity
        conf_specificity = (TN / float(TN + FP))

        # calculate precision
        conf_precision = (TN / float(TN + FP))
        # calculate f_1 score
        conf_f1 = 2 * ((conf_precision * conf_sensitivity) / (conf_precision + conf_sensitivity))
        print('-'*50)
        print(f'Accuracy: {round(conf_accuracy,2)}') 
        print(f'Mis-Classification: {round(conf_misclassification,2)}') 
        print(f'Sensitivity: {round(conf_sensitivity,2)}') 
        print(f'Specificity: {round(conf_specificity,2)}') 
        print(f'Precision: {round(conf_precision,2)}')
        print(f'f_1 Score: {round(conf_f1,2)}')
"""
# Function to plot ROC and Precision Recall Curve for combination of all models
"""
from sklearn.metrics import precision_recall_curve
from sklearn.metrics import average_precision_score
from sklearn.metrics import roc_curve
from sklearn.metrics import auc
def plotting(true,pred):
    fig,ax=plt.subplots(1,2,figsize=(15,5))
    precision,recall,threshold = precision_recall_curve(true,pred[:,1])
    ax[0].plot(recall,precision,'g--')
    ax[0].set_xlabel('Recall')
    ax[0].set_ylabel('Precision')
    ax[0].set_title("Average Precision Score : {}".format(average_precision_score(true,pred[:,1])))
    fpr,tpr,threshold = roc_curve(true,pred[:,1])
    ax[1].plot(fpr,tpr)
    ax[1].set_title("AUC Score is: {}".format(auc(fpr,tpr)))
    ax[1].plot([0,1],[0,1],'k--')
    ax[1].set_xlabel('False Positive Rate')
    ax[1].set_ylabel('True Positive Rate')
from sklearn.model_selection import train_test_split

X = Epilepsy.drop('y', axis=1)
y = Epilepsy.y

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
"""
Now we've got our data split into training and test sets, it's time to build a machine learning model.

We'll train it (find the patterns) on the training set.

And we'll test it (use the patterns) on the test set.

We're going to try different machine learning models:

1-Logistic Regression

2-K-Nearest Neighbours Classifier

3-Support Vector machine

4-Decision Tree Classifier

5-Random Forest Classifier

6-XGBoost Classifier
"""
"""
# 1. K-nearest neighbors
"""
from sklearn.neighbors import KNeighborsClassifier

knn_classifier = KNeighborsClassifier()
knn_classifier.fit(X_train, y_train)

print_score(knn_classifier, X_train, y_train, X_test, y_test, train=True)
print_score(knn_classifier, X_train, y_train, X_test, y_test, train=False)
"""
# 2. Decision Tree Classifier
"""
from sklearn.tree import DecisionTreeClassifier


tree = DecisionTreeClassifier(random_state=42)
tree.fit(X_train, y_train)

print_score(tree, X_train, y_train, X_test, y_test, train=True)
print_score(tree, X_train, y_train, X_test, y_test, train=False)
"""
# 3. Support Vector machine
"""
from sklearn.svm import SVC


svm_model = SVC(kernel='rbf', gamma=0.1, C=1.0, probability=True)
svm_model.fit(X_train, y_train)

print_score(svm_model, X_train, y_train, X_test, y_test, train=True)
print_score(svm_model, X_train, y_train, X_test, y_test, train=False)
"""
# *4*MLP neural network classifier**
"""
from sklearn.neural_network import MLPClassifier
NN=MLPClassifier(hidden_layer_sizes=(10,50),momentum=0.9,solver='sgd',random_state=42)
               
NN.fit(X_train, y_train)

print_score(NN, X_train, y_train, X_test, y_test, train=True)
print_score(NN, X_train, y_train, X_test, y_test, train=False)
"""
# 5. Random Forest
"""
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import RandomizedSearchCV

rand_forest = RandomForestClassifier(n_estimators=1000, random_state=42)
rand_forest.fit(X_train, y_train)

print_score(rand_forest, X_train, y_train, X_test, y_test, train=True)
print_score(rand_forest, X_train, y_train, X_test, y_test, train=False)
"""
#  6. XGBoost Classifer
"""
from xgboost import XGBClassifier

xgb = XGBClassifier()
xgb.fit(X_train, y_train)

print_score(xgb, X_train, y_train, X_test, y_test, train=True)
print_score(xgb, X_train, y_train, X_test, y_test, train=False)
"""
# 7- naive_bayes
"""
from sklearn.naive_bayes import GaussianNB
nb = GaussianNB()
nb.fit(X_train, y_train)

print_score(nb, X_train, y_train, X_test, y_test, train=True)
print_score(nb, X_train, y_train, X_test, y_test, train=False)  
"""
# ROC
Receiver operator characteristic, used very commonly to assess the quality of models for binary classification.

We will look at at three different classifiers here, a strongly regularized one and two with weaker regularization. The heavily regularized model has parameters very close to zero and is actually worse than if we would pick the labels for our holdout samples randomly.
"""
colors = ['r', 'g', 'b', 'y', 'k', 'c', 'm', 'brown', 'r']
lw = 1
Cs = [1e-6, 1e-4, 1e0]

plt.figure(figsize=(12,6))
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('ROC Curve for different classifiers')

plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')

labels = []
for idx, C in enumerate(Cs):
    clf = LogisticRegression(C = C)
    clf.fit(X_train, y_train)
    print("C: {}, parameters {} and intercept {}".format(C, clf.coef_, clf.intercept_))
    fpr, tpr, _ = roc_curve(y_test, clf.predict_proba(X_test)[:,1])
    roc_auc = auc(fpr, tpr)
    plt.plot(fpr, tpr, lw=lw, color=colors[idx])
    labels.append("C: {}, AUC = {}".format(C, np.round(roc_auc, 4)))

plt.legend(['random AUC = 0.5'] + labels)