import numpy as np
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
import itertools
import operator

def warn(*args, **kwargs):
    pass
import warnings
warnings.warn = warn


def generateOvOClassifier(classes):
    """
        Génération du classifier 0V0
    """
    o_vs_o_classifiers = {}
    for elem in itertools.combinations(classes,2):
        class0 = [x_train[index] for index, value in enumerate(y_train) if value == elem[0]]
        class1 = [x_train[index] for index, value in enumerate(y_train) if value == elem[1]]
        value = [0] * len(class0) + [1] * len(class1)
        learn = class0 + class1
        #Apprentissage du modèle
        o_vs_o_classifiers['%d_%d'%elem] = LogisticRegression(solver='lbfgs').fit(learn, value)
    return o_vs_o_classifiers

def predictOVO(test_values, o_vs_o_classifiers):
    """
        Prédiction du classifieur 0V0
    """
    results = {}
    i=0
    for elem in test_values:
        intern_result = {}
        for name,classifiers in o_vs_o_classifiers.items():
            result = classifiers.predict([elem[0]])
            members = name.split('_')
            if intern_result.get(members[result[0]]):
                intern_result[members[result[0]]] += 1
            else:
                intern_result[members[result[0]]] = 1
        results[i] = intern_result
        i+=1
    correct = 0
    for key,elem in results.items():
        predicted = max(elem.items(), key=operator.itemgetter(1))[0]
        value = test_values[key][1]
        if int(predicted) == value:
            correct += 1
        print("Predicted %s and value was %s" %(predicted,value))
    prct = (correct/len(results)*100)
    print("The One versus One score a %f precision score " %prct)

if __name__ == "__main__":
    digits = datasets.load_digits()
    data = digits['data']
    target  = digits['target']
    classes = set(target)
    #Séparation des données entre jeu d'entraînement et de test
    x_train, x_test, y_train, y_test = train_test_split(data, target, test_size=0.2)
    #Creation du classifieur O v O
    o_vs_o_classifiers = generateOvOClassifier(classes)
    # Nous générons un tableau contenant des tuples (images,value)
    test_values = [(x_test[index],value) for index, value in enumerate(y_test)]
    # Lancement de la boucle de prediction des éléments sur le jeu de test
    predictOVO(test_values, o_vs_o_classifiers)