Exercices : Algorithme des K Plus Proches Voisins
Exercice 1 : Compréhension du principe
- Expliquez avec vos propres mots le principe de l'algorithme des K plus proches voisins.
- Est-ce un algorithme d'apprentissage supervisé ou non supervisé ? Pourquoi ?
- Quelle est la différence entre l'utilisation de KNN pour la classification et pour la régression ?
??? success "Correction"
- Principe : Pour classer un nouvel élément, on regarde ses voisins les plus proches dans les données connues. L'élément prend la classe majoritaire parmi ces voisins (ou la moyenne des valeurs pour une régression). C'est le principe du "dis-moi qui tu hantes, je te dirai qui tu es".
- C'est un algorithme d'apprentissage supervisé car il nécessite un jeu de données d'entraînement où les réponses (les classes ou valeurs) sont déjà connues (étiquetées) pour pouvoir faire des prédictions.
- Classification : On prédit une catégorie (classe discrète) par vote majoritaire des voisins. Régression : On prédit une valeur numérique (continue) en faisant la moyenne des valeurs des voisins.
Exercice 2 : Calcul de distance euclidienne
Soient deux points et dans un plan cartésien. Calculez la distance euclidienne entre ces deux points.
??? success "Correction" La formule de la distance euclidienne est .
Exercice 3 : Application manuelle (K=1 et K=3)
On dispose des données d'entraînement suivantes (taille en cm, poids en kg) classées en "Enfant" (E) ou "Adulte" (A) :
- : E
- : A
- : E
- : A
- : E
On veut classer un nouvel individu .
- Calculez la distance (au carré pour simplifier, car l'ordre reste le même) entre et chaque point à .
- Quelle est la classe de pour ?
- Quelle est la classe de pour ?
??? success "Correction" 1. Distances au carré () :
- :
- :
- :
- :
- :
2. Pour K=1 : Le voisin le plus proche est (distance² = 29). Sa classe est E. Donc est classé Enfant.
3. Pour K=3 : Les 3 voisins les plus proches sont :
- (29) -> E
- (34) -> E
- (274) -> E
Les 3 votes sont "Enfant". Donc est classé Enfant.
Exercice 4 : Influence de K
On considère un jeu de données avec deux classes (Rouge et Bleu) mélangées.
- Que se passe-t-il si on choisit ? Le modèle est-il sensible au bruit ?
- Que se passe-t-il si on choisit égal au nombre total de points dans le jeu de données ?
??? success "Correction"
-
Si K=1 : Le modèle copie exactement les données d'entraînement. Si un point rouge est accidentellement au milieu des bleus (bruit), toute une zone autour de lui deviendra rouge. Le modèle est très sensible au bruit et risque le surapprentissage (overfitting). Les frontières de décision seront très irrégulières.
-
Si K = N (total) : Pour tout nouveau point, l'algorithme regardera tous les points existants. La classe majoritaire globale gagnera toujours. Le modèle prédira toujours la même classe (la plus fréquente) quel que soit l'entrée. C'est du sous-apprentissage (underfitting).
Exercice 5 : Implémentation de la distance
Implémentez en Python une fonction distance_euclidienne(point1, point2) qui prend deux listes de coordonnées (ex: [x, y]) et retourne leur distance.
Rappel : sqrt est dans le module math.
import math
def distance_euclidienne(point1, point2):
"""
Calcule la distance euclidienne entre deux points
point1 et point2 sont des listes [x, y]
"""
# À compléter
pass
# Test
p1 = [1, 2]
p2 = [4, 6]
print(distance_euclidienne(p1, p2)) # Doit afficher 5.0
??? success "Correction"
import math
def distance_euclidienne(point1, point2):
somme_carres = 0
for i in range(len(point1)):
somme_carres += (point1[i] - point2[i])**2
return math.sqrt(somme_carres)
# Version avec compréhension de liste (plus concise)
# return math.sqrt(sum([(a - b)**2 for a, b in zip(point1, point2)]))
Exercice 6 : Recherche des voisins
On dispose d'une liste de données :
donnees = [[1, 2, 'A'], [4, 6, 'B'], [1, 3, 'A'], [5, 7, 'B']]
Chaque élément est [x, y, classe].
Écrivez une fonction proches_voisins(donnees, cible, k) qui retourne les plus proches voisins du point cible (ex: [2, 2]).
def proches_voisins(donnees, cible, k):
"""
Retourne la liste des k plus proches voisins
"""
# 1. Calculer les distances pour tous les points
distances = []
# ...
# 2. Trier par distance
# ...
# 3. Renvoyer les k premiers
pass
??? success "Correction"
def proches_voisins(donnees, cible, k):
distances = []
for point in donnees:
# On ne prend que les coordonnées pour le calcul (point[:2])
dist = distance_euclidienne(point[:2], cible)
distances.append((dist, point))
# Tri selon la distance (le premier élément du tuple)
distances.sort(key=lambda x: x[0])
# On extrait juste les points des k premiers résultats
voisins = [d[1] for d in distances[:k]]
return voisins
Exercice 7 : Prédiction de classe (Vote majoritaire)
Écrivez une fonction predire_classe(voisins) qui prend une liste de voisins (ex: [[1, 2, 'A'], [4, 6, 'B'], ...]) et retourne la classe la plus fréquente.
def predire_classe(voisins):
# À compléter
pass
??? success "Correction"
def predire_classe(voisins):
compteur = {}
for v in voisins:
classe = v[2] # La classe est le 3ème élément
if classe in compteur:
compteur[classe] += 1
else:
compteur[classe] = 1
# Trouver la classe avec le max d'occurrences
classe_majoritaire = max(compteur, key=compteur.get)
return classe_majoritaire
Exercice 8 : Système de recommandation de films
On souhaite recommander des films à un utilisateur en se basant sur les goûts d'utilisateurs similaires. Chaque utilisateur a noté 3 genres de films sur 5 : Action, Comédie, Drame.
| Utilisateur | Action | Comédie | Drame | Note Sci-Fi (Cible) |
|---|---|---|---|---|
| Alice | 5 | 2 | 4 | 1 |
| Bob | 1 | 5 | 2 | 5 |
| Charlie | 4 | 3 | 5 | 2 |
| Diana | 2 | 4 | 1 | 5 |
Nouvel utilisateur Eve : Action=4, Comédie=1, Drame=5. On veut prédire sa note pour Sci-Fi avec .
- Calculez les distances entre Eve et les 4 autres utilisateurs (sur les 3 genres connus).
- Identifiez les 2 voisins les plus proches.
- Prédisez la note Sci-Fi pour Eve (moyenne des voisins ou moyenne pondérée par l'inverse de la distance).
??? success "Correction"
1. Calcul des distances (sur Action, Comédie, Drame) :
Eve : [4, 1, 5]
- Alice
[5, 2, 4]: - Bob
[1, 5, 2]: - Charlie
[4, 3, 5]: - Diana
[2, 4, 1]:
2. Les 2 plus proches voisins :
- Alice (dist 1.73) -> Note Sci-Fi : 1
- Charlie (dist 2.00) -> Note Sci-Fi : 2
3. Prédiction :
- Moyenne simple :
- Moyenne pondérée (optionnelle) : Alice est plus proche, sa note compte plus. Le résultat serait proche de 1.5 également (environ 1.46).
On prédit donc que Eve n'aimera pas trop la Sci-Fi (Note ~1.5/5).
Exercice 9 : Optimisations et variantes (Approfondissement)
Analysez ces améliorations possibles de l'algorithme K-NN :
- k-NN pondéré : Les voisins plus proches ont plus d'influence dans le vote.
- Normalisation : Mettre toutes les caractéristiques à la même échelle (ex: 0 à 1).
- Distance de Manhattan : au lieu de la distance euclidienne.
- Dans quel cas la normalisation est-elle indispensable ?
- Quel est l'avantage de la distance de Manhattan ?
??? success "Correction"
-
k-NN pondéré : Utile quand est grand ou quand certains voisins sont beaucoup plus proches que d'autres. Cela évite que des voisins "lointains" aient autant de poids que des voisins très proches.
-
Normalisation : Indispensable quand les caractéristiques ont des unités ou des ordres de grandeur différents (ex: Âge vs Salaire). Sans normalisation, la caractéristique avec les plus grandes valeurs écraserait complètement les autres dans le calcul de distance.
- Exemple de normalisation Min-Max :
-
Distance de Manhattan :
- Formule :
- Avantage : Moins sensible aux valeurs aberrantes (outliers) que la distance euclidienne (qui met les différences au carré, amplifiant les grands écarts). Souvent préférée en très haute dimension.