diff --git a/Code/Knn.py b/Code/Knn.py index f5bab4e..3af7658 100644 --- a/Code/Knn.py +++ b/Code/Knn.py @@ -32,9 +32,42 @@ class Knn: #nom de la class à changer c'est à vous d'utiliser vos propres notations """ self.k=5 + + def set_best_k(self, train, train_labels, nb_split, k_potentiel): + + ## Création des échantillons de validation croisée + shuffle_indices = np.random.permutation([i for i in range(train.shape[0])]) + validation_index = np.array_split(shuffle_indices, nb_split) + + train_index = [] + for i in range(nb_split): + train_index.append(list(set(shuffle_indices)-set(validation_index[i]))) + + ## Itération sur les valeurs de K et sur les échantillons de validation croisée + accuracy_cv = np.empty((len(k_potentiel),nb_split)) + + for k_index in range(len(k_potentiel)): + for i in range(nb_split): + self.k=k_potentiel[k_index] + self.train(train[train_index[i]], train_labels[train_index[i]], verbose=False) + cm,accuracy,precision,recall = self.test(train[validation_index[i]], train_labels[validation_index[i]], verbose=False) + accuracy_cv[k_index][i] = accuracy + + ## Calcul de la moyenne + mean_accuracy = accuracy_cv.mean(axis=1) + + ## Extraction du meilleur K + best_k = k_potentiel[int(min(np.argwhere(mean_accuracy==max(mean_accuracy))))] + + ## Assignation + self.k=best_k + + ## Retourner la valeur + return best_k + - def train(self, train, train_labels): #vous pouvez rajouter d'autres attribus au besoin + def train(self, train, train_labels, verbose=True): #vous pouvez rajouter d'autres attribus au besoin """ c'est la méthode qui va entrainer votre modèle, train est une matrice de type Numpy et de taille nxm, avec @@ -63,7 +96,7 @@ class Knn: #nom de la class à changer """ # on fait seulement utiliser les données du jeu d'entrainement comme paramètre d'un modèle Knn - self.train=train + self.train_set=train self.train_labels=train_labels n,m = train.shape @@ -78,9 +111,9 @@ class Knn: #nom de la class à changer i_range = [i for i in range(n)] i_range.pop(x) nn[x,:,0]=i_range[0:self.k] - nn[x,:,1]=np.apply_along_axis(minkowski_distance,1,self.train[i_range[0:self.k]],train[x],self.minkowski_p) + nn[x,:,1]=np.apply_along_axis(minkowski_distance,1,self.train_set[i_range[0:self.k]],train[x],self.minkowski_p) for i in i_range[self.k:n]: - dist = minkowski_distance(self.train[i],train[x],self.minkowski_p) + dist = minkowski_distance(self.train_set[i],train[x],self.minkowski_p) nn_dist=nn[x,:,1] distdiff = nn_dist-dist max_distdiff=max(distdiff) @@ -95,12 +128,13 @@ class Knn: #nom de la class à changer # on construit la matrice de confusion cm = self.confusion_matrix(train_labels,nn_mode_label) accuracy, precision, recall = self.prediction_metrics(cm,train_labels,nn_mode_label) - self.print_prediction_metrics(cm,accuracy,precision,recall) + if (verbose): + self.print_prediction_metrics(cm,accuracy,precision,recall) return cm,accuracy,precision,recall - def predict(self, exemple, label): + def predict(self, exemple, label, verbose=True): """ Prédire la classe d'un exemple donné en entrée exemple est de taille 1xm @@ -109,12 +143,12 @@ class Knn: #nom de la class à changer alors l'exemple est bien classifié, si non c'est une missclassification """ - n,m = self.train.shape + n,m = self.train_set.shape nn=np.empty((self.k,2)) nn[:,0]=[i for i in range(self.k)] - nn[:,1]=np.apply_along_axis(minkowski_distance,1,self.train[0:self.k],exemple,self.minkowski_p) + nn[:,1]=np.apply_along_axis(minkowski_distance,1,self.train_set[0:self.k],exemple,self.minkowski_p) for i in range(self.k,n): - dist = minkowski_distance(self.train[i],exemple,self.minkowski_p) + dist = minkowski_distance(self.train_set[i],exemple,self.minkowski_p) nn_dist=nn[:,1] distdiff = nn_dist-dist max_distdiff=max(distdiff) @@ -125,11 +159,12 @@ class Knn: #nom de la class à changer nn_labels = self.train_labels[nn[:,0].astype(np.int)] nn_mode_label = mode(nn_labels) - print("Observé:"+str(label)+" Prédit:"+str(nn_mode_label)) + if (verbose): + print("Observé:"+str(label)+" Prédit:"+str(nn_mode_label)) return nn_mode_label - def test(self, test, test_labels): + def test(self, test, test_labels, verbose=True): """ c'est la méthode qui va tester votre modèle sur les données de test l'argument test est une matrice de type Numpy et de taille nxm, avec @@ -152,14 +187,14 @@ class Knn: #nom de la class à changer """ n,m = test.shape - n_ex,m_ex = self.train.shape + n_ex,m_ex = self.train_set.shape nn=np.empty((n,self.k,2)) # Boucle sur chaque ligne du jeu de test for x in range(n): nn[x,:,0]=[i for i in range(self.k)] - nn[x,:,1]=np.apply_along_axis(minkowski_distance,1,self.train[0:self.k],test[x],self.minkowski_p) + nn[x,:,1]=np.apply_along_axis(minkowski_distance,1,self.train_set[0:self.k],test[x],self.minkowski_p) for i in range(self.k,n_ex): - dist = minkowski_distance(self.train[i],test[x],self.minkowski_p) + dist = minkowski_distance(self.train_set[i],test[x],self.minkowski_p) nn_dist=nn[x,:,1] distdiff = nn_dist-dist max_distdiff=max(distdiff) @@ -172,7 +207,8 @@ class Knn: #nom de la class à changer # on construit la matrice de confusion cm = self.confusion_matrix(test_labels,nn_mode_label) accuracy, precision, recall = self.prediction_metrics(cm,test_labels,nn_mode_label) - self.print_prediction_metrics(cm,accuracy,precision,recall) + if (verbose): + self.print_prediction_metrics(cm,accuracy,precision,recall) return cm,accuracy,precision,recall diff --git a/Code/entrainer_tester.py b/Code/entrainer_tester.py index f2ef3e7..5c32691 100644 --- a/Code/entrainer_tester.py +++ b/Code/entrainer_tester.py @@ -19,20 +19,23 @@ En gros, vous allez : """ -# Initializer vos paramètres - -myKnn = Knn.Knn() - -# Initializer/instanciez vos classifieurs avec leurs paramètres - - - - - # Charger/lire les datasets train, train_labels, test, test_labels = ld.load_iris_dataset(0.7) +# Initializer vos paramètres + +## Choix du meilleur K + +findbest_Knn = Knn.Knn() +meilleur_k = findbest_Knn.set_best_k(train, train_labels, nb_split=5, k_potentiel=range(1,16)) +print("Le meilleur K est:"+str(meilleur_k)+"\n\n") + +# Initializer/instanciez vos classifieurs avec leurs paramètres + +myKnn = Knn.Knn() +myKnn.k=meilleur_k + # Entrainez votre classifieur myKnn.train(train, train_labels)