choix du meilleur K
This commit is contained in:
parent
4f8da781bf
commit
d9fa94a2d6
2 changed files with 64 additions and 25 deletions
66
Code/Knn.py
66
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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue