import pandas as pd
from sklearn.svm import  SVC
from sklearn.model_selection import train_test_split
from sklearn import preprocessing
import sklearn.metrics as met
from termcolor import colored



def class_info(clf, x_test, y_test):

    y_pred = clf.predict(x_test)

    cnf_matrix = met.confusion_matrix(y_test, y_pred)
    print("Matrica konfuzije", cnf_matrix, sep="\n")
    print("\n")

    accuracy = met.accuracy_score(y_test, y_pred)
    print("Preciznost", accuracy)
    print("\n")

    class_report = met.classification_report(y_test, y_pred, target_names=df["Species"].unique())
    print("Izvestaj klasifikacije", class_report, sep="\n")

    print('n_support_', clf.n_support_, sep='\n')
    print()
    print('support_vectors_', clf.support_vectors_, sep='\n')
    print()
    print('dual_coef_', clf.dual_coef_, sep='\n')
    print()
    print('intercept_', clf.intercept_, sep='\n')
    print()

df = pd.read_csv("iris_pandas.csv")

featurs = df.columns[:4].tolist()

#ako zelimo da izdvojimo odredjene atribute za klasifikaciju
#featurs = ["Petal_Length",  "Petal_Width"]

x_original=df[featurs]

#standardizacija atributa
x=pd.DataFrame(preprocessing.scale(x_original))


#normalizacija
#x=pd.DataFrame(preprocessing.MinMaxScaler().fit_transform(x_original))

#dodeljivanje imena kolonama
x.columns = featurs
y=df["Species"]


#podela na trening i test skup
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8, stratify=y)

"""
C : default=1.0
parametar za regularizaciju

kernel : default=’rbf’
         ‘linear’  ( <x, x'>),

         ‘poly’ : ( gamma*<x, x'> + coef0)^degree
                    vezani parametri:
                     degree (stepen): default=3,
                     gamma (koeficijent) : default= 1/n_features
                     coef0 (nezavisni term) default=0.0

         ‘rbf’,  exp(-gamma*|x-x'|^2)
                     vezani parametri:
                     gamma (koeficijent) : default= 1/n_features
                                           gamma>0

         ‘sigmoid’, (tanh(gamma*<x, x'> + coef0)
                     vezani parametri:
                     gamma (koeficijent) : default= 1/n_features
                     coef0 (nezavisni term) default=0.0


probability : default=False
da li proceniti verovatnocu

class_weight : {dict, ‘balanced’}
tezina klasa. Ako nije zadat parametar, sve klase imaju tezinu 1.
Sa opcijom “balanced” tezine su inverzno proporcionalne frekvenciji klase u y

decision_function_shape : ‘ovo’, ‘ovr’ or None, default=None
oblik funkcije za odlucivanje klase:
              ‘ovr’ - one-vs-rest (n_samples, n_classes)
              ‘ovo’ - one-vs-one  (n_samples, n_classes * (n_classes - 1) / 2)

atributi:
support_  -indeksi podrzavajucih vektora
support_vectors_ : podrzavajuci vektori
n_support_ : broj podrzavajucih vektora za svaku klasu
dual_coef_ : niz oblika [n_class-1, n_SV]
koeficijenti podrzavajucih vektora
Ukoliko postoji vise klasa, postoje koeficijenti za sve 1-vs-1 klasifikatore.
coef_ : tezine dodeljene aributima ( samo za linearni kernel)
intercept_ : konstane u funckiji odlucivanja
"""

C_values = [pow(2,x) for x in range(-6,10,2)]
kernels = ['linear'] #, 'poly', 'rbf', 'sigmoid']

models =[]
for c in C_values:
    for kernel in kernels:
            clf = SVC(C=c, kernel=kernel, decision_function_shape='ovo')

            clf.fit(x_train, y_train)
            y_pred = clf.predict(x_test)

            accuracy = met.accuracy_score(y_test, y_pred)
            models.append([clf, accuracy])


max_accuracy = max([x[1] for x in models])
for x in models:
    if x[1]==max_accuracy:
        print(colored("C=" + str(c), "blue"))
        print(colored("kernel=" + kernel, "blue"))

        class_info(x[0], x_test, y_test)

