From 2734ebfb76f6a9b8f7b40386c036a32ab9968213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Pelletier?= Date: Mon, 29 Apr 2019 01:10:20 -0400 Subject: [PATCH] ajout fichiers decision tree training --- Code/DecisionTree.py | 158 +++++++++++++++++++++++++++++++++++++++++++ Code/NeuralNet.py | 79 ++++++++++++++++++++++ Code/main.py | 15 ++++ 3 files changed, 252 insertions(+) create mode 100644 Code/DecisionTree.py create mode 100644 Code/NeuralNet.py create mode 100644 Code/main.py diff --git a/Code/DecisionTree.py b/Code/DecisionTree.py new file mode 100644 index 0000000..41f8fd7 --- /dev/null +++ b/Code/DecisionTree.py @@ -0,0 +1,158 @@ +# -*- coding: utf-8 -*- +""" +Vous allez definir une classe pour chaque algorithme que vous allez développer, +votre classe doit contenit au moins les 3 methodes definies ici bas, + * train : pour entrainer le modèle sur l'ensemble d'entrainement + * predict : pour prédire la classe d'un exemple donné + * test : pour tester sur l'ensemble de test +vous pouvez rajouter d'autres méthodes qui peuvent vous etre utiles, mais moi +je vais avoir besoin de tester les méthodes train, predict et test de votre code. +""" + +import numpy as np + + +# le nom de votre classe +# NeuralNet pour le modèle Réseaux de Neurones +# DecisionTree le modèle des arbres de decision + +class DecisionTree: #nom de la class à changer + + def __init__(self, **kwargs): + """ + c'est un Initializer. + Vous pouvez passer d'autre paramètres au besoin, + c'est à vous d'utiliser vos propres notations + """ + self.tree=[] + + def plurality_value(self,train_labels): + values,_,counts = np.unique(train_labels,return_index=True, return_counts=True) + return values[np.argmax(counts)] + + def importance(self,train, train_labels, attribute): + #Entropie Avant + _,_,counts = np.unique(train_labels,return_index=True, return_counts=True) + total_count = sum(counts) + entropie_total = -sum(counts/total_count * np.log2(counts/total_count)) + + #Trouver split + attribute_sort_order = np.argsort(train[:,attribute]) + sorted_labels = train_labels[attribute_sort_order] + lags = np.hstack((np.array([False]),sorted_labels[:-1] != sorted_labels[1:])) + potential_splits = train[attribute_sort_order,attribute][lags] + split_gain = [] + for v in potential_splits: + split_labels_1 = train_labels[train[:,attribute] < v] + split_labels_2 = train_labels[train[:,attribute] >= v] + _,_,counts1 = np.unique(split_labels_1,return_index=True, return_counts=True) + total_count1 = sum(counts1) + entropie_total1 = -sum(counts1/total_count1 * np.log2(counts1/total_count1)) + _,_,counts2 = np.unique(split_labels_2,return_index=True, return_counts=True) + total_count2 = sum(counts2) + entropie_total2 = -sum(counts2/total_count2 * np.log2(counts2/total_count2)) + split_gain.append(entropie_total+(total_count1/total_count*entropie_total1+total_count2/total_count*entropie_total2)) + #Valeur unique attribut + best_split = potential_splits[np.argmax(split_gain)] + best_gain = max(split_gain) + + return best_gain,best_split + + + + def decision_tree_learning(self,train, train_labels, attributes, parent_examples): + n_examples,n_attributes = train.shape + classes_uniques = np.unique(train_labels) + # la feuille est vide + if (n_examples == 0): + return self.plurality_value(parent_examples) + # tous les exemples ont la même classe + elif len(classes_uniques)==1: + return classes_uniques[0] + # la liste d'attributs est vides + elif (sum(attributes)==0): + return self.plurality_value(train_labels) + else: + # Calcul du gain + attr = np.where(attributes==1)[0] + a_gain = [] + a_split = [] + for a in attr: + gain, split = self.importance(train, train_labels, a) + a_gain.append(gain) + a_split.append(split) + # Calcul du meilleur attribut + pos_gain_max = np.argmax(a_gain) + a_max = attr[pos_gain_max] + a_max_split = a_split[pos_gain_max] + tree = [] + tree.append(("Test",a_max,a_max_split)) + attributes[a_max]=0 + # pour chaque valeur de l'attribut, faire un sous-arbre + for v in [True,False]: + train_pos = np.where((train[:,a_max] < a_max_split) == v) + subtree = self.decision_tree_learning(train[train_pos],train_labels[train_pos],attributes,train_labels) + tree.append(("Branche",a_max,a_max_split,v,subtree)) + return tree + + + def train(self, train, train_labels): #vous pouvez rajouter d'autres attribus au besoin + """ + c'est la méthode qui va entrainer votre modèle, + train est une matrice de taille nxm, avec + n : le nombre d'exemple d'entrainement dans le dataset + m : le mobre d'attribus (le nombre de caractéristiques) + + train_labels : est une matrice de taille nx1 + + vous pouvez rajouter d'autres arguments, il suffit juste de + les expliquer en commentaire + + + + ------------ + + """ + + n,m = train.shape + # Vecteur booléen qui définit quels attributs n'ont pas été utilisés + attributes = np.ones(m) + + self.tree = self.decision_tree_learning(train, train_labels, attributes, None) + + + + + def predict(self, exemple, label): + """ + Prédire la classe d'un exemple donné en entrée + exemple est de taille 1xm + + si la valeur retournée est la meme que la veleur dans label + alors l'exemple est bien classifié, si non c'est une missclassification + + """ + + def test(self, test, test_labels): + """ + c'est la méthode qui va tester votre modèle sur les données de test + l'argument test est une matrice de taille nxm, avec + n : le nombre d'exemple de test dans le dataset + m : le mobre d'attribus (le nombre de caractéristiques) + + test_labels : est une matrice taille nx1 + + vous pouvez rajouter d'autres arguments, il suffit juste de + les expliquer en commentaire + + Faites le test sur les données de test, et afficher : + - la matrice de confision (confusion matrix) + - l'accuracy (ou le taux d'erreur) + + Bien entendu ces tests doivent etre faits sur les données de test seulement + + """ + + + # Vous pouvez rajouter d'autres méthodes et fonctions, + # il suffit juste de les commenter. \ No newline at end of file diff --git a/Code/NeuralNet.py b/Code/NeuralNet.py new file mode 100644 index 0000000..45401ba --- /dev/null +++ b/Code/NeuralNet.py @@ -0,0 +1,79 @@ +# -*- coding: utf-8 -*- +""" +Vous allez definir une classe pour chaque algorithme que vous allez développer, +votre classe doit contenit au moins les 3 methodes definies ici bas, + * train : pour entrainer le modèle sur l'ensemble d'entrainement + * predict : pour prédire la classe d'un exemple donné + * test : pour tester sur l'ensemble de test +vous pouvez rajouter d'autres méthodes qui peuvent vous etre utiles, mais moi +je vais avoir besoin de tester les méthodes train, predict et test de votre code. +""" + +import numpy as np + + +# le nom de votre classe +# NeuralNet pour le modèle Réseaux de Neurones +# DecisionTree le modèle des arbres de decision + +class Classifier: #nom de la class à changer + + def __init__(self, **kwargs): + """ + c'est un Initializer. + Vous pouvez passer d'autre paramètres au besoin, + c'est à vous d'utiliser vos propres notations + """ + + + def train(self, train, train_labels): #vous pouvez rajouter d'autres attribus au besoin + """ + c'est la méthode qui va entrainer votre modèle, + train est une matrice de taille nxm, avec + n : le nombre d'exemple d'entrainement dans le dataset + m : le mobre d'attribus (le nombre de caractéristiques) + + train_labels : est une matrice de taille nx1 + + vous pouvez rajouter d'autres arguments, il suffit juste de + les expliquer en commentaire + + + + ------------ + + """ + + def predict(self, exemple, label): + """ + Prédire la classe d'un exemple donné en entrée + exemple est de taille 1xm + + si la valeur retournée est la meme que la veleur dans label + alors l'exemple est bien classifié, si non c'est une missclassification + + """ + + def test(self, test, test_labels): + """ + c'est la méthode qui va tester votre modèle sur les données de test + l'argument test est une matrice de taille nxm, avec + n : le nombre d'exemple de test dans le dataset + m : le mobre d'attribus (le nombre de caractéristiques) + + test_labels : est une matrice taille nx1 + + vous pouvez rajouter d'autres arguments, il suffit juste de + les expliquer en commentaire + + Faites le test sur les données de test, et afficher : + - la matrice de confision (confusion matrix) + - l'accuracy (ou le taux d'erreur) + + Bien entendu ces tests doivent etre faits sur les données de test seulement + + """ + + + # Vous pouvez rajouter d'autres méthodes et fonctions, + # il suffit juste de les commenter. \ No newline at end of file diff --git a/Code/main.py b/Code/main.py new file mode 100644 index 0000000..f9edf32 --- /dev/null +++ b/Code/main.py @@ -0,0 +1,15 @@ +# -*- coding: utf-8 -*- +import numpy as np +import matplotlib.pyplot as plt +import sys +import load_datasets +import NeuralNet # importer la classe du Réseau de Neurones +import DecisionTree # importer la classe de l'Arbre de Décision +# importer d'autres fichiers et classes si vous en avez développés +# importer d'autres bibliothèques au besoin, sauf celles qui font du machine learning + +dt = DecisionTree.DecisionTree() + +dt.train(train,train_labels) + +dt.tree \ No newline at end of file