Retour à la page d'accueilNSI · Première (sans spé maths) · Changer de matière
Commencer gratuitement
Première (sans spé maths) · NSI
Types construits et algorithmique en première NSI · Algorithmique en première

k plus proches voisins, dichotomie et gloutons

Tu ouvres une application de musique : elle te propose un morceau « qui ressemble » à ceux que tu aimes. Tu cherches un nom dans un annuaire de 1 000 pages : tu ne lis pas tout. Une caissière rend la monnaie en prenant toujours le plus gros billet possible. Trois situations, trois algorithmes : les k plus proches voisins, la dichotomie et les algorithmes gloutons. À la fin, on se demandera pourquoi la caissière a de la chance.

Les k plus proches voisins

Un jeu de données contient des éléments dont on connaît la classe (ici, l'espèce d'une fleur). On reçoit un nouvel élément inconnu : on veut prédire sa classe. L'idée : il ressemble à ses voisins.

Chaque élément est un point du plan, par exemple (longueur ; largeur) d'un pétale. La ressemblance se mesure par la distance euclidienne :

$$d(A, B) = \sqrt{(x_B - x_A)^2 + (y_B - y_A)^2}$$ Nuage de points de deux classes A et B ; le cercle autour du point inconnu contient ses 3 plus proches voisins : 2 de classe A et 1 de classe B ? inconnu k = 3 : 2 A, 1 B classe A classe B longueur largeur

En Python, on trie une liste de couples (distance, classe) :

from math import sqrt

def distance(p, q):

    return sqrt((p[0] - q[0]) ** 2 + (p[1] - q[1]) ** 2)

def voisins(donnees, p, k):

    # donnees : liste de triplets (x, y, classe)

    liste = [(distance((x, y), p), c) for (x, y, c) in donnees]

    liste.sort()

    return liste[:k]
Entraîne-toi★☆☆Pas commencé
Dans le plan, on considère les points A(1 ; 2) et B(4 ; 6). a) Calculer la distance euclidienne $d(A, B)$. b) Donner la formule de la distance euclidienne entre…

Dans le plan, on considère les points A(1 ; 2) et B(4 ; 6).

  1. a) Calculer la distance euclidienne $d(A, B)$.
  1. b) Donner la formule de la distance euclidienne entre $(x_1, y_1)$ et $(x_2, y_2)$.
  1. c) Parmi les points C(2 ; 2) et D(5 ; 5), lequel est le plus proche de A ?
Résoudre
Entraîne-toi★★☆Pas commencé
Un jeu de données classe des fleurs en deux espèces, A et B, d'après la longueur et la largeur de leurs pétales (en cm) : (1,0 ; 0,5) : A (1,5 ; 0,4) : A (4,5 ; 1,5) : B…

Un jeu de données classe des fleurs en deux espèces, A et B, d'après la longueur et la largeur de leurs pétales (en cm) :

  • (1,0 ; 0,5) : A

  • (1,5 ; 0,4) : A

  • (4,5 ; 1,5) : B

  • (5,0 ; 1,8) : B

  • (4,0 ; 1,2) : B

  1. a) Calculer la distance de chaque donnée à la fleur inconnue (2,0 ; 0,6).
  1. b) Appliquer l'algorithme des $k$ plus proches voisins avec $k = 3$ et donner l'espèce prédite.
  1. c) Écrire une fonction Python qui renvoie les $k$ plus proches voisins d'un point.
Résoudre
Entraîne-toi★★★Pas commencé
Une table contient des relevés de températures et d'humidité pour des journées classées « pluie » ou « sec » dans une ville de Bretagne. On souhaite prédire la classe…

Une table contient des relevés de températures et d'humidité pour des journées classées « pluie » ou « sec » dans une ville de Bretagne. On souhaite prédire la classe d'une nouvelle journée par $k$ plus proches voisins.

  1. a) Expliquer pourquoi il peut être nécessaire de normaliser les données avant de calculer les distances lorsque les deux attributs n'ont pas la même échelle.
  1. b) Écrire une fonction knn(donnees, p, k) qui renvoie la classe majoritaire parmi les $k$ voisins les plus proches de p, où donnees est une liste de triplets (x, y, classe).
  1. c) Discuter l'effet du choix de $k$ (trop petit, trop grand) sur la prédiction, et donner la complexité de la fonction en fonction de la taille $n$ des données.
Résoudre

La recherche dichotomique

Pour trouver un mot dans un dictionnaire, tu l'ouvres au milieu, puis tu gardes la moitié utile. C'est la dichotomie : elle exige un tableau trié.

def dichotomie(t, x):

    debut, fin = 0, len(t) - 1

    while debut <= fin:

        milieu = (debut + fin) // 2

        if t[milieu] == x:

            return True

        elif t[milieu] < x:

            debut = milieu + 1

        else:

            fin = milieu - 1

    return False

À chaque tour, la zone de recherche est divisée par 2. Pour $n$ éléments, il faut au plus $\lfloor \log_2 n \rfloor + 1$ tours : environ 10 pour 1 000 éléments, environ 20 pour un million. Une recherche séquentielle en demanderait 1 000, ou un million.

Entraîne-toi★☆☆Pas commencé
On recherche par dichotomie la valeur 23 dans le tableau trié [3, 8, 12, 17, 23, 29, 35, 41] (indices de 0 à 7). a) Donner les valeurs successives des indices debut, fin…

On recherche par dichotomie la valeur 23 dans le tableau trié [3, 8, 12, 17, 23, 29, 35, 41] (indices de 0 à 7).

  1. a) Donner les valeurs successives des indices debut, fin et milieu (avec milieu = (debut + fin) // 2).
  1. b) Combien de valeurs du tableau sont comparées à 23 au cours de la recherche ?
Résoudre
Entraîne-toi★★☆Pas commencé
Écrire une fonction dichotomie(t, x) qui renvoie True si x appartient au tableau trié t, False sinon. a) Écrire la fonction avec une boucle while debut <= fin. b)…

Écrire une fonction dichotomie(t, x) qui renvoie True si x appartient au tableau trié t, False sinon.

  1. a) Écrire la fonction avec une boucle while debut <= fin.
  1. b) Indiquer le variant de la boucle.
  1. c) Combien de tours de boucle au maximum pour un tableau de 1 000 éléments ?
Résoudre

Variant et invariant

Comment être sûr que l'algorithme s'arrête et qu'il est correct ?

Pour la dichotomie :

On reprend la fonction dichotomie ci-dessus (dans certains énoncés, debut, fin et milieu sont notés d, f et m, et la fonction renvoie l'indice trouvé ou -1 au lieu de True ou False : le raisonnement est le même).

  • Variant : fin - debut + 1, la taille de la zone de recherche. Tant que debut <= fin, elle est $\geq 1$. À chaque tour, debut augmente ou fin diminue d'au moins 1 : elle décroît strictement. Elle ne peut pas décroître indéfiniment : la boucle se termine.

  • Invariant : « si x est dans t, son indice est entre debut et fin ». C'est vrai au début (debut = 0, fin = len(t) - 1). Si t[milieu] < x, comme t est trié, les indices $\leq$ milieu ne conviennent pas : debut = milieu + 1 conserve la propriété. Même raisonnement pour t[milieu] > x avec fin = milieu - 1.

  • Sortie : si debut > fin, la zone est vide, donc x n'est pas dans t : renvoyer False (ou -1 dans la version qui renvoie un indice) est correct.

Prouver ainsi la correction avec un invariant est essentiel : un jeu de tests ne suffit pas à garantir qu'un programme est correct. La preuve complète de correction peut être présentée par ton professeur ; retiens le principe.

Entraîne-toi★★★Pas commencé
Soit l'algorithme de recherche dichotomique suivant dans un tableau trié t de n éléments : a) Montrer que la quantité $f - d + 1$ est un variant de la boucle et en…

Soit l'algorithme de recherche dichotomique suivant dans un tableau trié t de n éléments :

def recherche(t, x):

    d, f = 0, len(t) - 1

    while d <= f:

        m = (d + f) // 2

        if t[m] == x:

            return m

        elif t[m] < x:

            d = m + 1

        else:

            f = m - 1

    return -1
  1. a) Montrer que la quantité $f - d + 1$ est un variant de la boucle et en déduire la terminaison.
  1. b) Énoncer un invariant : si x est dans t, alors son indice est compris entre d et f. Le démontrer.
  1. c) Montrer que le nombre de tours est au plus $\lfloor \log_2 n \rfloor + 1$.
Résoudre

Les algorithmes gloutons

Un algorithme glouton construit une solution étape par étape, en faisant à chaque fois le choix qui semble le meilleur sur le moment, sans jamais revenir en arrière.

Exemple classique, le rendu de monnaie : rendre la somme avec le moins de pièces et billets.

def rendu(somme, systeme):

    # systeme trié par valeurs décroissantes

    resultat = []

    for valeur in systeme:

        while somme >= valeur:

            resultat.append(valeur)

            somme -= valeur

    return resultat

Autre problème : le sac à dos. On choisit des objets de masse et de valeur donnés, sans dépasser la capacité, pour maximiser la valeur. Plusieurs critères gloutons sont possibles : par valeur décroissante, par masse croissante, ou par rapport valeur/masse décroissant. Ils ne donnent pas toujours le même résultat.

Entraîne-toi★☆☆Pas commencé
On doit rendre 63 € avec des pièces et billets de 50 €, 20 €, 10 €, 5 €, 2 € et 1 €. a) Appliquer l'algorithme glouton de rendu de monnaie et donner la composition du…

On doit rendre 63 € avec des pièces et billets de 50 €, 20 €, 10 €, 5 €, 2 € et 1 €.

  1. a) Appliquer l'algorithme glouton de rendu de monnaie et donner la composition du rendu.
  1. b) Combien de pièces et billets sont utilisés ?
Résoudre
Entraîne-toi★★☆Pas commencé
Un sac à dos de capacité 15 kg doit contenir des objets de valeur maximale. Objets (masse en kg ; valeur en €) : A (12 ; 4), B (2 ; 2), C (1 ; 1), D (1 ; 2), E (4 ; 10).…

Un sac à dos de capacité 15 kg doit contenir des objets de valeur maximale. Objets (masse en kg ; valeur en €) : A (12 ; 4), B (2 ; 2), C (1 ; 1), D (1 ; 2), E (4 ; 10).

  1. a) Appliquer l'algorithme glouton qui choisit les objets par valeur décroissante, sans fractionner les objets.
  1. b) Appliquer l'algorithme glouton qui choisit par rapport valeur/masse décroissant.
  1. c) Comparer les deux résultats.
Résoudre
Entraîne-toi★★★Pas commencé
On considère le système de monnaie $\{1, 3, 4\}$ (en unités quelconques). a) Appliquer l'algorithme glouton pour rendre 6. Donner la solution obtenue. b) Trouver une…

On considère le système de monnaie $\{1, 3, 4\}$ (en unités quelconques).

  1. a) Appliquer l'algorithme glouton pour rendre 6. Donner la solution obtenue.
  1. b) Trouver une solution utilisant moins de pièces. Conclure sur l'optimalité de l'algorithme glouton.
  1. c) Vérifier que le glouton est optimal pour le système $\{1, 2, 5, 10, 20, 50\}$ pour toutes les sommes jusqu'à 20, en justifiant avec un raisonnement général sur le choix de la plus grande pièce.
Résoudre

Retour au début : la caissière a de la « chance » parce que le système en euros est tel que le choix glouton (le plus gros billet possible) donne toujours un rendu optimal.

L'essentiel

  • k plus proches voisins : calculer les distances, garder les $k$ plus petites, prédire la classe majoritaire. Normaliser si les échelles diffèrent ; le choix de $k$ compte.

  • Dichotomie : sur un tableau trié, on coupe la zone en deux à chaque tour ; au plus $\lfloor \log_2 n \rfloor + 1$ tours.

  • Variant : quantité entière qui décroît strictement, preuve de terminaison (ici fin - debut + 1). Invariant : propriété conservée à chaque tour, preuve de correction.

  • Glouton : meilleur choix local à chaque étape, sans retour en arrière. Rapide, mais pas toujours optimal : un contre-exemple suffit à le montrer.

Voir tous les exercices de cette partie