ajout fichiers decision tree training

This commit is contained in:
François Pelletier 2019-04-29 01:10:20 -04:00
parent 1e7e355f7e
commit 2734ebfb76
3 changed files with 252 additions and 0 deletions

158
Code/DecisionTree.py Normal file
View file

@ -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.

79
Code/NeuralNet.py Normal file
View file

@ -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.

15
Code/main.py Normal file
View file

@ -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