Aller au contenu

K plus proches voisins

Programme

Notions Compétences Remarques
Algorithme des k plus proches voisins Écrire un algorithme qui prédit la classe d’un élément en fonction de la classe majoritaire de ses k plus proches voisins. Il s’agit d’un exemple d’algorithme d’apprentissage.
Algorithme KNN et problème de classification
  • Les algorithmes des k plus proches voisins est abrĂ©gĂ© kppv en français. En anglais, K Nearest Neighbors souvent abrĂ©gĂ© en knn.
  • L’algorithme des k plus proches voisins appartient Ă  la famille des algorithmes d’apprentissage automatique (machine learning) qui constituent le poumon de l'intelligence artificielle actuellement.
  • Pour simplifier, l'apprentissage automatique part souvent de donnĂ©es (data) et essaye de dire quelque chose des donnĂ©es qui n'ont pas encore Ă©tĂ© vues : il s'agit de gĂ©nĂ©raliser, de prĂ©dire.
Activité 1 - Un ours ou un phoque ?

Le problème revient à prédire à quelle catégorie, ou classe, appartient ce nouvel élément donné. Il est appelé problème de classification. L'algorithme des k plus proches voisins permet de trouver les k voisins les plus proches (si k = 5 on cherche les 5 voisins les plus proches) de ce nouvel élément dans le but de lui associer une classe plausible (Psy ou Eau, dans cet exemple).

banquise

L'animal inconnu est-il un ours ou un phoque ?

Lancer l'appli

Activité 2 - Classification des Pokémons

choix pokemon

Notebook

Fonctionnement de l'algorithme KKN

A partir d'un jeu de données (par exemple, les données sur nos 34 Pokémons) et d'une donnée cible (le nouveau Pokemon à classifier), l'algorithme des k plus proches voisins détermine les k données les plus proches de la cible. (si k=3 les 3 plus proches voisins de la cible seront pris en compte, si k=5 les 5, ...)

**Données : **

  • une table donnĂ©es de taille n contenant les donnĂ©es et leurs classes
  • une donnĂ©e cible : cible
  • un nombre k infĂ©rieur Ă  n
  • une formule permettant de calculer la distance entre deux donnĂ©es

Résultat : Un tableau contenant les k plus proches voisins de la donnée cible.

Étapes de l'algorithme :

  • CrĂ©er une table distances_voisins contenant les Ă©lĂ©ments de la table donnĂ©es et leurs distances avec la donnĂ©e cible.
  • Trier les donnĂ©es de la table distances_voisins selon la distance dĂ©croissante avec la donnĂ©e cible
  • Renvoyer les k premiers Ă©lĂ©ments de cette table triĂ©e.
  • PrĂ©diction : dĂ©termination de la classe majoritaire (la plus prĂ©sente) dans les k plus proches voisins.
Influence de la valeur de k

k impair

On est contents si k est impair car il ne peut pas y avoir d'ex-aequo.

Remarque

La valeur de k est très importante, elle doit être choisie judicieusement car elle a une influence forte sur la prédiction. Regardons le résultat de la prédiction pour différentes valeurs de k sur notre exemple.

k = 1

Si k=1, cela revient à chercher la donnée la plus proche de notre élément cible.
Ici, on se rend compte que s la classe du plus proche élément est "Eau" (point bleu)
➜ on classerait le nouveau Pokémon comme étant de type "Eau".

k = 3

Si k=3, on se rend compte que la classe majoritaire dans les 3 plus proches voisins est "Psy" (2 points rouges contre 1 point bleu) donc on classerait le Pokémon inconnu comme étant de type "Psy".

k = 9

La classe majoritaire parmi les 9 plus proches voisin est "Eau" (5 points bleus contre 4 points rouges) donc on classerait le Pokémon inconnu comme étant de type "Eau".

Remarque

Si on choisit k = 34 (le nombre total de données), alors la prédiction serait toujours "Psy" car c'est la classe majoritaire de l'échantillon. Il est donc incorrect de penser que plus la valeur de k augmente meilleure sera la prédiction, c'est plus complexe que cela. Il faudra observer les resultats.

Choix des distances

L'algorithme des plus proches voisins repose sur la distance entre deux données. Dans les exemples vus précédemment, c'est la distance "naturelle" qui a été choisie (celle "à vol d'oiseau").

La distance euclidienne

Dans un repère orthonormé, si A et B de coordonnées \((x_{A},y_{A})\) et \((x_{B},y_{B})\), alors la distance entre ces deux points est donnée par la formule :

\(AB=\sqrt{(x_{B}-x_{A})^{2}+(y_{B}-y_{A})^{2}}\)

On parle alors de la distance euclidienne.

Activité 3 - Des Pokémons inconnus

Dans l'activité précédente, nous avons obtenu la figure suivante :

Mettre en oeuvre l'algorithme knn pour prédire le type des trois Pokémon représentés en vert, qui sont inconnus.
Ce sont des "cibles" :

  • cible_1 : points de vie : 65 et valeur d'attaque : 25
  • cible_2 : points de vie : 75 et valeur d'attaque : 80
  • cible_3 : points de vie : 95 et valeur d'attaque : 125
Indices
  • La liste de dictionnaires pokemons est dĂ©jĂ  implĂ©mentĂ©e, mais cachĂ©e pour ne pas alourdir l'exercice.

    pokemons = [{'Attaque': 105, 'Nom': 'Aligatueur', 'Points de vie': 85, 'Type': 'Eau'},  
    {'Attaque': 92, 'Nom': 'Bargantua', 'Points de vie': 70, 'Type': 'Eau'},  
    {'Attaque': 63, 'Nom': 'Carabaffe', 'Points de vie': 59, 'Type': 'Eau'},  
    ... ] 
    

  • cible est un dictionnaire reprĂ©sentant un pokĂ©mon dont on cherche Ă  dĂ©terminer le type.

Par exemple cible_1 = {'Attaque': 25, 'Points de vie' : 65}

  • La fonction cree_liste prend en paramètre la liste pokemons et le dictionnaire cible.
    Elle renvoie la liste des listes composées du nom des Pokémon, de leur type, et de leur distance à la cible.

Par exemple

>>> cree_liste(pokemons, cible_1)
[['Aligatueur', 'Eau', 82.46211251235322],
['Bargantua', 'Eau', 67.1863081289633],
... ]
👉 La fonction cree_liste_triee prend en paramètre la liste pokemons et le dictionnaire cible.
Elle renvoie la liste des listes composées du nom des Pokémon, de leur type et de leur distance à la cible triée par ordre croissant des distances.

Par exemple

>>> cree_liste_triee(pokemons, cible_1)
[['Spoink', 'Psy', 5.0],
['Munna', 'Psy', 11.0],
...]
👉 La fonction knn prend en paramètre la liste pokemons et le dictionnaire cible.
Elle renvoie la liste des k premiers éléments de la liste créée par la fonction cree_liste_triee

###(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 : 5/5

.128013rAt=7*flb)1 2e/vyg:,-]8Tsw9nuph5aS(o3qNk_i4+6P;[cdm0050Y0o0d0H0Q0i0z0m0X0i0H0z0z0e010d0Q0E010406050z0D0Z0Z0H0b0r040I0K0i0D0^0K0C050p0 1113150}0E04051l1e1o0p1l0}0Y0Q0q0-0/0;0?0F0Q0s0F0i1C0F0d0{050(0j0i0o1x0:0=011B1D1F1D0d1L1N1J0d0b1m0d0F0-180z0E0H0C0?0n011P1z010h0*0o0C0H0Z0o1J1,1.1?1R1_1N1|1~0{0a0m0U0b0K0E0K0z0Q1b0C0m0$1*0b0b0o0X2j1e210C1m0p1(2w1#1%1$1K0Y230?1F0C1{2g1J1u1w0.1Q2G0Q2I0C0K2M1J0E2p1m2u2w2!0~1-2k2O1@2T0b120i0{0m0l2t2(0|2%222*1R2,2.2:0n2?1.2^2u2F012}0H2/040m0L312v0}342{0?37390m0R3d332(353j2:0G3n3f3p3h360K2-382:0T3u2_2)1y2|3z2~3a0f3E3g3H3i3J3B3a0x3N3w3P3y3A3k0B3V2`3X3r040l0!3$3G2P3Y3K0l2=1f2@3v3%3/3)0l303@323_3.2+3R390l3c3 3e3F3q440{0l3m483o3`433Z4d3t4g414b4k3*3D4n4a3x3|3M4t3O3{4c3*3U4y3W4A4q0l3#4E4i3I4q0n3,4K424M3K0n3?2!4o4v4B0n3~2$1r2Y1e2M2z0Y1%2E3x0X2U1 1m4*1n4(4$2$4:0$2Z4F1@0O0C0{0h2d0Z3n0m4u3(5204121(57593/510{0Q0Z2f0b0d5f4z2+0{0z0M5n3u4X3X0O0{0$0h5p4 2|0h5A0Q0z0(0C0X0o3n5g1@0`040J5O5q2|0{2f0O0o0Z1c5U5E0?5R0u5D4L3i0{0X0Q1M5N4g5P1R5R0k0t3u0m5~585V0?5z042p0d0D0b1d4g605(365s5u5o5@61015R0J5T6h6c5b5:5=5%5-6j0{0W6s4R0?0z0l0{02030L0B0V0U0K2R0d0,2m0q0Q0o6D6F0V6x355R0w6U3x0K0{0v6Y3(5X0K5Z5#692$6i5R6w6n6t6A6C6E6G6I6K6M1O6O6Q6_6T6=6y6u040w0k6%3/6!040g0g791@0Z0Q0{4#2@0m065 6b6t7b0S5,746k7f5W046q1N7w5)6v7B016@046R6G0c1X0H0M0D706S7E6W7E7b6$733q6)6+5$7W3x6:7E7G7I0V7K0(7N7P6G7R0{777T0{7d7E7h7j7;04784n5x5h5A0o5C6a5^3i5G7y2p0o0P1F5J5?6.6c7v7#6(045Y5!1c0z7}5+866i6p5;7A8k3/5`5|4n7o87016365676-7l8E6:6;8h6t5b8n6,7}8N2@8E7)710N0K0Z7*7}0w8s2!7p748Q6*8o8J328L7D8y1@8X6S0y0r0E7/728O7u7=8)8K8u5H5J1.5M7}6m907X8m8.8S8@5_0{93328+9d7z8g8V6/0{0k6X8C8D6i630h3z7t9d8R7!8*8E0K0A5j8:2v9m4v7Y8/8q9h7C765w8E635B9B4v890s0%0P1u975L9p8;9r5S7E5b0Y1c2I9+2v8=7~8B4W9w6c8G0%8I9Y8l9;0C9?8T7`7i047k9,8i7=9U9x83859F8u890X8b8d5I0d8c1#6P9@4~6t8j9c9N9e7Z0C9Qay3X5*a23{5/8wau9_5{5}5 8E9:ap980o0z0P9oaD946c7b0eaH5r8a0o8c8eaq9a9/9O6,aYacaw9ja%7x9o7}7 9|aP95049(5K5MaVaX0Pasa*a_0?a#ba360j5s3zaq0Ya.9R6db1aS9*b5aKa=9^9-9k9LaQ0{5Z0r7@04a$bl5b9#0d9%bo99bl5`aO5~9V0{8H68bdaR9)b4aWbrb70bataf9~ahbT89519Kav919.bEa:8p8rbTaJ6rbLa^8t6obya|9{3^9}8P0{0q6J2haCbZ6Pbs3a9G0{bDajb}a)a+aparb!b9b`b/aEaIaA9Pb?b|c37yaKa|bN9M8l2p0 0i0(6gcg7qcebd7%b:04c55I2RaVb8cb9_8Ua?8,5j8%bd9y9AcvcY040Qbd9H9JbTbf641.9#bkcqa(0Oa|9ua~bOag64a0bSc(9dcD0DcF0HcH3^1e4|0o2w2Xdd4)1v4+2z2C2x0H5=2w4*0}0p0$0(0*0z04.