Aller au contenu

Recherche de la valeur de k⚓︎

Tester les limites

Comme nous l'avons vu, le résultat obtenu peut différer selon la valeur de k utilisée. Afin de trouver la meilleure valeur de k utiliser, il est possible d'en tester plusieurs pour trouver celle qui donne les meilleurs résultats. Pour cela, il faut un nouvel échantillon que l'on peut classifier de façon exacte.

Nous allons reprendre notre carré avec 4 zones et générer de nouvelles valeurs, mais cette fois en nous concentrant sur les frontières entre les zones pour tester les valeurs limites. La fonction suivante permet de générer un échantillon de test :

from random import gauss, uniform

def generation_echantillon_test(n):
    liste = []
    for i in range(n):
        if i%2 == 0:
            x = gauss(xmoy, (xmax-xmin)/10)
            y = uniform(ymin, ymax)
        else:
            x = uniform(xmin, xmax)
            y = gauss(ymoy, (ymax-ymin)/10)
        liste.append((x, y))
    return liste

L'expression gauss(mu, sigma) génère une valeur aléatoire selon une loi normale d'espérance mu et d'écart-type sigma. C'est-à-dire que les valeurs obtenues sont proches de mu et plus sigma est grand, plus elles seront proches de cette valeur moyenne.

Les valeurs générées ont donc une chance sur deux d'être proches de la frontière horizontale ou de la frontière verticale. Afin de déterminer de façon exacte la catégorie à laquelle appartient chacun des points de l'échantillon de test, nous allons utiliser la fonction suivante :

def determine_categorie(pt):
    x, y = pt
    reponse = 0
    if x > xmoy:
        reponse += 1
    if y > ymoy:
        reponse += 2
    return reponse

Ces deux fonctions peuvent être utilisée dans les exercices suivants.

Exercice 7

Écrire une fonction taux_reussite qui prend en paramètre une liste de valeurs à tester echant_test, un dictionnaire echantillon, un entier k et une fonction distance, et qui renvoie le taux de réussite obtenu en comparant les valeurs attendues avec les valeurs obtenues pour toutes les valeurs de echant_test en utilisant l'algorithme des k plus proches voisins sur l'échantillon et la distance donnés.

Exemples d'utilisation
>>> echantillon = generation_echantillon(10)
>>> echant_test = generation_echantillon_test(100)
>>> taux_reussite(echant_test, echantillon, 3, distance_euclidienne)
0.67
>>> taux_reussite(echant_test, echantillon, 3, distance_manhattan)
0.65
>>> taux_reussite(echant_test, echantillon, 7, distance_euclidienne)
0.7
>>> taux_reussite(echant_test, echantillon, 7, distance_manhattan)
0.69

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : /∞

Influence de la taille de l'échantillon

Vous pouvez remarquer que lorsque la taille de l'échantillon initial augmente, le taux de réussite augmente également.

Exemples d'utilisation
>>> echantillon = generation_echantillon(100)
>>> echant_test = generation_echantillon_test(100)
>>> taux_reussite(echant_test, echantillon, 7, distance_euclidienne)
0.93
>>> echantillon = generation_echantillon(1000)
>>> echant_test = generation_echantillon_test(100)
>>> taux_reussite(echant_test, echantillon, 7, distance_euclidienne)
0.98
Exercice 8

Écrire une fonction choix_k qui prend en paramètre une liste de valeurs à tester echant_test, un dictionnaire echantillon, un entier k_max et une fonction distance, et qui renvoie la valeur de k comprise entre 1 et k_max qui renvoie le meilleur taux de réussite pour les échantillons donnés.

Exemples d'utilisation
>>> echantillon = generation_echantillon(10)
>>> echant_test = generation_echantillon_test(100)
>>> choix_k(echant_test, echantillon, 10, distance_euclidienne)
9
>>> choix_k(echant_test, echantillon, 10, distance_manhattan)
8

###(Dés-)Active le code après la ligne # Tests (insensible à la casse)
(Ctrl+I)
Tronquer ou non le feedback dans les terminaux (sortie standard & stacktrace / relancer le code pour appliquer)
Si activé, le texte copié dans le terminal est joint sur une seule ligne avant d'être copié dans le presse-papier
Évaluations restantes : /∞

Optimisation pour de très grands échantillons

La meilleur valeur de k peut être différente ou la même selon les distances et les échantillons. Lorsque la taille de l'échantillon augmente, le temps de calcul nécessaire augmente aussi. Pour limiter cette augmentation, il est possible de ne pas rechercher les k plus proches voisins pour chaque valeur de k, mais plutôt de le faire pour k_max et ensuite, lors de l'étude de la liste de plus proches voisins, il suffit de noter à chaque étape si la catégorie trouvée est la bonne ou pas.

Pour aller plus loin

Dans la base des iris, il y a également les informations sur les sépales. Cela fait donc 4 mesures par iris.

Toutes les données se trouvent dans le fichier iris-complet.csv.

Vous pouvez utiliser ce fichier pour avoir des résultats plus précis, mais cela nécessite de reprendre quasiment toutes les fonctions.