# -*- coding: utf-8 -*-
"""
Created on Wed Sep 14 10:30:36 2022

@author: HTG
"""

import pandas as pd
#import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
import pickle
import matplotlib.pyplot as plt
import seaborn as sns



class Knn:
    
    # Function to read the features from file
    def read_features(self, filename_path):
        self.dataset = pd.read_csv(filename_path, skiprows=1)
        #print(self.dataset)
        self.X = self.dataset.iloc[:, :-1]           # all features
        # print(self.X)
        self.y = self.dataset.iloc[:, -1]            # labels
        # print(self.y)
        self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(self.X, self.y, test_size = 0.2, random_state = 0)
        # print(self.X_train)
        self.X_train.to_csv("D:\\ML\\Split_Data\\train_data.csv", index=None)
        #print(self.X_test)
        self.X_test.to_csv("D:\\ML\\Split_Data\\test_data.csv", index=None)
        # print(self.y_train)
        self.y_train.to_csv("D:\\ML\\Split_Data\\train_labels.csv", index=None)
        #print(self.y_test)
        # print(type(self.y_test))
        self.y_test.to_csv("D:\\ML\\Split_Data\\test_labels.csv", index=None)
        
    
    def set_parameters(self, property_name, value):
        if(property_name == "Test_File_Path"):
            self.test_file_path = str(value)
            print(self.test_file_path)
        elif(property_name == "Mode" and (value == "Training_&_Testing" or value == "Testing_only")):
            self.mode = str(value)
            print(self.mode)
        elif(property_name == "Kernel_Type" and (value == "linear" or value == "rbf")):
            self.kernel = str(value)
            print(self.kernel)
            
            
    def knn_train_test(self):
        
        if(self.mode == 'Training_&_Testing'):
            self.knn = KNeighborsClassifier(n_neighbors=100).fit(self.X_train, self.y_train)
            pickle.dump(self.knn, open("Trained_knn.sav", 'wb'))
            self.y_pred = self.knn.predict(self.X_test)
            
            # To calculate the accuracy of the model
            pred_accu = accuracy_score(self.y_test, self.y_pred)
            print("Accuracy of the trained Model:", pred_accu*100,"%")
            
            # To compute the confusion matrix
            self.confusion_matrix = confusion_matrix(self.y_test, self.y_pred)
            print(self.confusion_matrix)
            
            ax = sns.heatmap(self.confusion_matrix, annot=True, cmap='Blues')

            ax.set_title('Confusion Matrix with labels\n\n');
            ax.set_xlabel('\nPredicted Values')
            ax.set_ylabel('Actual Values');
            
            plt.show()
            
            self.test_input = pd.read_csv(self.test_file_path)
            self.predictions = self.knn.predict(self.test_input)
            df = pd.DataFrame(self.predictions)
            df.to_csv("Predictions_Training_&_Testing.csv", index=None, header=None)
            
        elif(self.mode == 'Testing_only'):
            load_model = pickle.load(open('Trained_knn.sav', 'rb'))
            self.test_input = pd.read_csv(self.test_file_path)
            self.predictions = load_model.predict(self.test_input)
            print(self.predictions)
            df = pd.DataFrame(self.predictions)
            df.to_csv("Predictions_Testing_only.csv", index=None, header=None)
        
        
path = "D:\\ML\\V6S1RA_Va_Combined_0.2sWs.csv"
obj = Knn()
obj.read_features(path)
obj.set_parameters("Test_File_Path", "D:\\ML\\v6.csv")
obj.set_parameters("Kernel_Type", 'linear')
obj.set_parameters("Mode", "Testing_only")
obj.knn_train_test()