Accéder au contenu principal

Apprentissage automatique en R pour débutants

Ce court tutoriel vous initie aux bases de l’apprentissage automatique en R : il vous montre comment utiliser R avec KNN.
Actualisé 19 sept. 2026  · 15 min lire

Explorer avec l’IA

ChatGPTClaudePerplexity

Introduction : l’apprentissage automatique en R

L’apprentissage automatique est un domaine de l’informatique qui étudie la conception d’algorithmes capables d’apprendre. Les tâches typiques incluent l’apprentissage de concepts, l’apprentissage de fonctions (ou « modélisation prédictive »), le clustering et la recherche de motifs prédictifs. Ces tâches s’appuient sur des données disponibles, observées via l’expérience ou l’instruction, par exemple. L’idée est que l’intégration de l’expérience améliore progressivement l’apprentissage. L’objectif ultime est d’automatiser suffisamment le processus pour qu’il n’exige plus d’intervention humaine.

Ce court tutoriel a pour but de vous initier aux fondamentaux de l’apprentissage automatique en R : plus précisément, il vous montrera comment utiliser R avec l’algorithme bien connu « KNN », ou k plus proches voisins.

Si vous souhaitez suivre un cours, jetez un œil à notre Introduction to Machine Learning with R ou au cours Unsupervised Learning in R de DataCamp !

Utiliser R pour les k plus proches voisins (KNN)

L’algorithme KNN, ou des k plus proches voisins, est l’un des plus simples en apprentissage automatique. C’est un exemple d’apprentissage à base d’instances : de nouvelles données sont classées à partir d’exemples étiquetés et mémorisés.

Plus précisément, on calcule la distance entre les données stockées et la nouvelle instance au moyen d’une mesure de similarité. Cette similarité est généralement exprimée par une mesure de distance telle que la distance euclidienne, la similarité cosinus ou la distance de Manhattan.

Autrement dit, pour chaque nouveau point que vous soumettez au système, on évalue sa similarité avec les données déjà présentes.

Vous utilisez ensuite cette similarité pour effectuer de la modélisation prédictive. Celle-ci peut être : soit de la classification (attribuer une étiquette ou une classe à la nouvelle instance), soit de la régression (attribuer une valeur). Le choix entre classification et régression dépend bien sûr de la façon dont vous paramétrez votre modèle KNN.

L’algorithme des k plus proches voisins complète ce principe de base : une fois les distances entre le nouveau point et toutes les observations stockées calculées, on trie ces valeurs et on retient les k voisins les plus proches. Leurs étiquettes sont rassemblées, puis un vote majoritaire (ou pondéré) est utilisé pour la classification ou la régression.

En d’autres termes, plus un point stocké obtient un score élevé, plus la nouvelle instance a de chances de recevoir la même classe que ce voisin. En régression, la valeur attribuée au nouveau point est la moyenne de ses k plus proches voisins.



Étape 1. Récupérer vos données

L’apprentissage automatique commence généralement par des données observées. Vous pouvez utiliser votre propre jeu de données ou parcourir d’autres sources pour en trouver un.

Jeux de données intégrés à R

Ce tutoriel utilise le jeu de données Iris, très connu en apprentissage automatique. Il est intégré à R ; vous pouvez l’inspecter en tapant ceci dans votre console :

eyJsYW5ndWFnZSI6InIiLCJzYW1wbGUiOiJpcmlzIn0=

UC Irvine Machine Learning Repository

Si vous préférez télécharger le jeu de données plutôt que d’utiliser celui intégré à R, rendez-vous sur le UC Irvine Machine Learning Repository et recherchez « Iris ».


Astuce : ne vous contentez pas du dossier « data » d’Iris ; consultez aussi la page de description du jeu de données !

Ensuite, utilisez la commande suivante pour charger les données :

eyJsYW5ndWFnZSI6InIiLCJzYW1wbGUiOiIjIFJlYWQgaW4gYGlyaXNgIGRhdGFcbmlyaXMgPC0gcmVhZC5jc3YodXJsKFwiaHR0cDovL2FyY2hpdmUuaWNzLnVjaS5lZHUvbWwvbWFjaGluZS1sZWFybmluZy1kYXRhYmFzZXMvaXJpcy9pcmlzLmRhdGFcIiksIFxuICAgICAgICAgICAgICAgICBoZWFkZXIgPSBGQUxTRSkgXG5cbiMgUHJpbnQgZmlyc3QgbGluZXNcbmhlYWQoaXJpcylcblxuIyBBZGQgY29sdW1uIG5hbWVzXG5uYW1lcyhpcmlzKSA8LSBjKFwiU2VwYWwuTGVuZ3RoXCIsIFwiU2VwYWwuV2lkdGhcIiwgXCJQZXRhbC5MZW5ndGhcIiwgXCJQZXRhbC5XaWR0aFwiLCBcIlNwZWNpZXNcIilcblxuIyBDaGVjayB0aGUgcmVzdWx0XG5pcmlzIn0=

Cette commande lit le fichier .csv (« Comma Separated Values ») depuis le site. L’argument header est fixé à FALSE, ce qui signifie que, dans cette source, Iris ne fournit pas de noms d’attributs.

À la place, lorsque vous inspectez l’objet iris avec une fonction comme head(), vous pouvez voir des noms de colonnes du type « V1 », « V2 », etc. Ceux-ci sont affectés automatiquement.

Pour faciliter le travail, il est judicieux de nommer vous‑même les colonnes : utilisez la fonction names(), qui récupère ou définit les noms d’un objet. Concaténez les noms d’attributs tels que vous souhaitez les voir apparaître. Dans l’exemple de code ci‑dessus, vous avez listé Sepal.Length, Sepal.Width, Petal.Length, Petal.Width et Species.

Encore une fois, ces noms ne sortent pas de nulle part : consultez la description du jeu de données liée ci‑dessus ; vous y trouverez normalement tous ces noms.

Learn Python for Data Science With DataCamp

Étape 2. Bien connaître vos données

Maintenant que vous avez chargé Iris dans RStudio, il est temps de comprendre en profondeur ce que contiennent vos données. Se contenter de regarder ou lire à leur sujet n’est pas suffisant pour démarrer !

Mettez les mains dans le cambouis : explorez, visualisez, et si nécessaire, complétez votre connaissance métier si les données vous semblent obscures.

Vous avez probablement déjà la connaissance métier utile, mais pour mémoire, toutes les fleurs ont un sépale et un pétale. Le sépale entoure les pétales et est généralement vert et foliacé, tandis que les pétales sont des feuilles colorées. Pour les iris, c’est un peu différent, comme le montre l’illustration suivante :

machine learning R

Aperçu initial du jeu de données

Commencez par vous faire une idée via quelques graphiques, tels que des histogrammes ou des boîtes à moustaches. Ici, des nuages de points sont particulièrement parlants : il est intéressant de voir dans quelle mesure une variable influence une autre.

Autrement dit, vous cherchez à détecter une éventuelle corrélation entre deux variables.

Vous pouvez tracer des nuages de points avec le package ggvis, par exemple.

Remarque : commencez par charger le package ggvis :

# Load in `ggvis`
library(ggvis)

# Iris scatter plot
iris %>% ggvis(~Sepal.Length, ~Sepal.Width, fill = ~Species) %>% layer_points()

correlation iris

On observe une forte corrélation entre la longueur et la largeur du sépale pour la variété Setosa, alors qu’elle est un peu moins marquée pour Virginica et Versicolor : les points sont plus dispersés et ne forment pas un amas compact comme chez Setosa.

Le nuage de points qui met en regard la longueur et la largeur des pétales raconte une histoire similaire :

iris %>% ggvis(~Petal.Length, ~Petal.Width, fill = ~Species) %>% layer_points()

scatterplot iris

Ce graphique indique une corrélation positive entre la longueur et la largeur des pétales pour toutes les espèces présentes dans Iris. Bien sûr, pour en avoir le cœur net, vous pouvez tester davantage cette hypothèse :

eyJsYW5ndWFnZSI6InIiLCJzYW1wbGUiOiIjIE92ZXJhbGwgY29ycmVsYXRpb24gYFBldGFsLkxlbmd0aGAgYW5kIGBQZXRhbC5XaWR0aGBcbmNvcihpcmlzJFBldGFsLkxlbmd0aCwgaXJpcyRQZXRhbC5XaWR0aClcblxuIyBSZXR1cm4gdmFsdWVzIG9mIGBpcmlzYCBsZXZlbHMgXG54PWxldmVscyhpcmlzJFNwZWNpZXMpXG5cbiMgUHJpbnQgU2V0b3NhIGNvcnJlbGF0aW9uIG1hdHJpeFxucHJpbnQoeFsxXSlcbmNvcihpcmlzW2lyaXMkU3BlY2llcz09eFsxXSwxOjRdKVxuXG4jIFByaW50IFZlcnNpY29sb3IgY29ycmVsYXRpb24gbWF0cml4XG5wcmludCh4WzJdKVxuY29yKGlyaXNbaXJpcyRTcGVjaWVzPT14WzJdLDE6NF0pXG5cbiMgUHJpbnQgVmlyZ2luaWNhIGNvcnJlbGF0aW9uIG1hdHJpeFxucHJpbnQoeFszXSlcbmNvcihpcmlzW2lyaXMkU3BlY2llcz09eFszXSwxOjRdKSJ9

Vous constatez qu’en combinant les trois espèces, la corrélation est un peu plus forte que lorsqu’on les considère séparément : la corrélation globale est de 0,96, tandis que pour Versicolor elle est de 0,79. Setosa et Virginica affichent des corrélations de 0,31 et 0,32 respectivement (après arrondi) entre longueur et largeur des pétales.

Astuce : curieux de ggvis, des graphiques ou des histogrammes en particulier ? Consultez notre tutoriel histogrammes et/ou le cours ggvis.

Après cet aperçu visuel général, vous pouvez aussi afficher les données en tapant

eyJsYW5ndWFnZSI6InIiLCJzYW1wbGUiOiIjIFJldHVybiBhbGwgYGlyaXNgIGRhdGFcbmlyaXNcblxuIyBSZXR1cm4gZmlyc3QgNSBsaW5lcyBvZiBgaXJpc2BcbmhlYWQoaXJpcylcblxuIyBSZXR1cm4gc3RydWN0dXJlIG9mIGBpcmlzYFxuc3RyKGlyaXMpIn0=

Vous verrez toutefois que ce n’est pas la meilleure manière d’inspecter vos données : l’ensemble occupe trop d’espace dans la console, ce qui gêne la compréhension. Il est préférable d’utiliser head(iris) ou str(iris).

Notez que la dernière commande vous aide à distinguer clairement le type num et les trois modalités de l’attribut Species, qui est un facteur. Pratique, car de nombreux classifieurs R exigent que la variable cible soit de type facteur.

Rappelez‑vous : les facteurs représentent des variables catégorielles en R. Ils ne prennent qu’un nombre limité de valeurs.

Un rapide coup d’œil à Species montre une répartition 50‑50‑50 des espèces. Pour vérifier la répartition en pourcentage, demandez un tableau de proportions :

eyJsYW5ndWFnZSI6InIiLCJzYW1wbGUiOiIjIERpdmlzaW9uIG9mIGBTcGVjaWVzYFxudGFibGUoaXJpcyRTcGVjaWVzKSBcblxuIyBQZXJjZW50dWFsIGRpdmlzaW9uIG9mIGBTcGVjaWVzYFxucm91bmQocHJvcC50YWJsZSh0YWJsZShpcmlzJFNwZWNpZXMpKSAqIDEwMCwgZGlnaXRzID0gMSkifQ==

Remarque : round arrondit les valeurs du premier argument, prop.table(table(iris$Species))*100, au nombre de décimales indiqué, ici une décimale. Adaptez‑le via l’argument digits.

Compréhension approfondie des données

Ne restez pas sur une vue trop macro ! R vous permet d’aller plus loin avec la fonction summary(). Pour les variables numériques, elle renvoie minimum, premier quartile, médiane, moyenne, troisième quartile et maximum. Pour la variable de classe, elle renvoie le nombre d’occurrences de chaque modalité :

eyJsYW5ndWFnZSI6InIiLCJzYW1wbGUiOiIjIFN1bW1hcnkgb3ZlcnZpZXcgb2YgYGlyaXNgXG5zdW1tYXJ5KC4uLi4pIFxuXG4jIFJlZmluZWQgc3VtbWFyeSBvdmVydmlld1xuc3VtbWFyeSguLi4uW2MoXCJQZXRhbC5XaWR0aFwiLCBcIlNlcGFsLldpZHRoXCIpXSkiLCJzb2x1dGlvbiI6IiMgU3VtbWFyeSBvdmVydmlldyBvZiBgaXJpc2BcbnN1bW1hcnkoaXJpcykgXG5cbiMgUmVmaW5lZCBzdW1tYXJ5IG92ZXJ2aWV3XG5zdW1tYXJ5KGlyaXNbYyhcIlBldGFsLldpZHRoXCIsIFwiU2VwYWwuV2lkdGhcIildKSIsInNjdCI6InRlc3RfZnVuY3Rpb24oXCJzdW1tYXJ5XCIsYXJncz1cIm9iamVjdFwiLCBpbmRleD0xKVxudGVzdF9mdW5jdGlvbihcInN1bW1hcnlcIiwgYXJncz1cIm9iamVjdFwiLCBpbmRleD0yKVxuc3VjY2Vzc19tc2coXCJHcmVhdCBqb2IhXCIpIn0=

Comme vous le voyez, la fonction c() est ajoutée à la commande : on concatène les colonnes petal width et sepal width, puis on demande un résumé sur ces deux colonnes du jeu Iris.

Étape 3. Quelle suite donner ?

Une fois vos données bien comprises, identifiez des cas d’usage pertinents. En d’autres termes, déterminez ce que vous pouvez apprendre de vos données et quels résultats vous souhaitez obtenir. À partir de là, choisissez les algorithmes adaptés pour y parvenir.

Astuce : plus vous connaissez vos données, plus il sera facile de définir des cas d’usage pertinents et de sélectionner l’algorithme adéquat.

Dans ce tutoriel, Iris sera utilisé pour de la classification, un cas de modélisation prédictive. Le dernier attribut, Species, sera la variable cible, c’est‑à‑dire celle que vous souhaitez prédire.

Remarque : vous pouvez aussi choisir une variable numérique comme cible si vous souhaitez utiliser KNN en régression.

Étape 4. Préparer votre environnement

Beaucoup d’algorithmes d’apprentissage automatique ne sont pas inclus par défaut dans R. Vous devrez probablement installer les packages nécessaires avant de vous lancer.


Astuce : vous avez une idée de l’algorithme à utiliser, mais pas du package ? Retrouvez une vue d’ensemble assez complète des packages R dédiés ici.

Pour illustrer KNN, ce tutoriel utilise le package class :

eyJsYW5ndWFnZSI6InIiLCJzYW1wbGUiOiJsaWJyYXJ5KC4uLi4uKSIsInNvbHV0aW9uIjoibGlicmFyeShjbGFzcykiLCJzY3QiOiJ0ZXN0X2Z1bmN0aW9uKFwibGlicmFyeVwiLCBhcmdzPVwicGFja2FnZVwiKVxuc3VjY2Vzc19tc2coXCJBd2Vzb21lIGpvYiFcIikifQ==

Si vous ne l’avez pas encore, installez‑le simplement avec :

install.packages("<package name>")

Mémo geek : si vous n’êtes pas sûr de l’avoir, exécutez la commande suivante pour vérifier !

any(grepl("<name of your package>", installed.packages()))

Étape 5. Préparer vos données

Après l’exploration des données et la préparation de l’environnement, revenons à l’objectif : construire un modèle d’apprentissage automatique. Avant cela, préparez aussi les données. Deux étapes sont détaillées ci‑dessous : normaliser (si nécessaire) et scinder en ensembles d’entraînement et de test.

Normalisation

Dans votre préparation, il peut être nécessaire de normaliser les données pour les rendre cohérentes. Pour cette introduction, retenez que la normalisation facilite l’apprentissage de KNN. Il existe deux types de normalisation :

  • la normalisation par exemple, où chaque observation est ajustée individuellement ;
  • la normalisation par variable (feature), où chaque variable est ajustée de la même manière pour toutes les observations.

Quand faut‑il normaliser ?

En bref : lorsque vous suspectez une incohérence d’échelle.

Repérez‑la dans les résultats de summary(). Comparez les min/max des attributs numériques. Si l’un d’eux présente une plage très large, normalisez, sinon la distance sera dominée par cette variable.

Exemple : si votre jeu n’a que deux attributs, X et Y, avec X variant de 1 à 1000 et Y de 1 à 100, l’influence de Y sur la distance sera généralement écrasée par celle de X.

La normalisation ajuste l’échelle des variables, afin que les distances ne surpondèrent pas les variables à grande amplitude.

Astuce : revenez au résultat de summary(iris) pour juger si une normalisation s’impose.

Le jeu Iris n’a pas besoin d’être normalisé : Sepal.Length va de 4,3 à 7,9 ; Sepal.Width de 2 à 4,4 ; Petal.Length de 1 à 6,9 ; Petal.Width de 0,1 à 2,5. Toutes les valeurs sont comprises entre 0,1 et 7,9 ; c’est acceptable.

Il reste néanmoins utile d’étudier la normalisation et ses effets, surtout si vous débutez. Vous pouvez, par exemple, réaliser une normalisation par variable en commençant par écrire votre propre fonction normalize().

Vous pourrez ensuite l’appliquer et stocker les résultats dans un data frame via as.data.frame() après que lapply() a renvoyé une liste de même longueur que votre jeu d’entrée. Chaque élément de cette liste est le résultat de l’application de la fonction normalize au jeu fourni :

YourNormalizedDataSet <- as.data.frame(lapply(YourDataSet, normalize))

Testez‑le dans le bloc DataCamp Light ci‑dessous !

eyJsYW5ndWFnZSI6InIiLCJzYW1wbGUiOiIjIEJ1aWxkIHlvdXIgb3duIGBub3JtYWxpemUoKWAgZnVuY3Rpb25cbm9ybWFsaXplIDwtIGZ1bmN0aW9uKHgpIHtcbm51bSA8LSB4IC0gbWluKHgpXG5kZW5vbSA8LSBtYXgoeCkgLSBtaW4oeClcbnJldHVybiAobnVtL2Rlbm9tKVxufVxuXG4jIE5vcm1hbGl6ZSB0aGUgYGlyaXNgIGRhdGFcbmlyaXNfbm9ybSA8LSAuLi4uLi4uLi4uLi4uLiguLi4uLi4oaXJpc1sxOjRdLCBub3JtYWxpemUpKVxuXG4jIFN1bW1hcml6ZSBgaXJpc19ub3JtYFxuc3VtbWFyeSguLi4uLi4uLi4pIiwic29sdXRpb24iOiIjIEJ1aWxkIHlvdXIgb3duIGBub3JtYWxpemUoKWAgZnVuY3Rpb25cbm9ybWFsaXplIDwtIGZ1bmN0aW9uKHgpIHtcbm51bSA8LSB4IC0gbWluKHgpXG5kZW5vbSA8LSBtYXgoeCkgLSBtaW4oeClcbnJldHVybiAobnVtL2Rlbm9tKVxufVxuXG4jIE5vcm1hbGl6ZSB0aGUgYGlyaXNgIGRhdGFcbmlyaXNfbm9ybSA8LSBhc2QuZGF0YS5mcmFtZShsYXBwbHkoaXJpc1sxOjRdLCBub3JtYWxpemUpKVxuXG4jIFN1bW1hcml6ZSBgaXJpc19ub3JtYFxuc3VtbWFyeShpcmlzX25vcm0pIiwic2N0IjoidGVzdF9vYmplY3QoXCJub3JtYWxpemVcIilcbnRlc3Rfb2JqZWN0KFwiaXJpc19ub3JtXCIpXG50ZXN0X2Z1bmN0aW9uKFwic3VtbWFyeVwiLCBhcmdzPVwib2JqZWN0XCIpIn0=

Avec Iris, vous auriez appliqué normalize aux quatre attributs numériques (Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) et placé les résultats dans un data frame.

Astuce : pour illustrer l’effet de la normalisation, comparez le résultat obtenu avec le résumé d’Iris donné à l’étape 2.

Ensembles d’entraînement et de test

Pour évaluer la performance du modèle, divisez le jeu de données en deux : un ensemble d’entraînement et un ensemble de test.

Le premier sert à entraîner le système, le second à l’évaluer. En pratique, on choisit souvent une division disjointe 2/3 pour l’entraînement et 1/3 pour le test.

Un dernier coup d’œil au jeu montre que si vous scindiez tel quel, vous pourriez obtenir un ensemble d’entraînement avec seulement des espèces « Setosa » et « Versicolor », mais aucune « Virginica ». Le modèle classerait alors toutes les instances inconnues en « Setosa » ou « Versicolor », ignorant la troisième espèce.

En bref, vous obtiendriez des prédictions erronées sur le test.

Vous devez donc vous assurer que les trois classes sont présentes dans l’ensemble d’entraînement et, autant que possible, en proportions équilibrées pour éviter de favoriser une classe.

Pour créer vos ensembles, commencez par fixer une graine aléatoire, c’est‑à‑dire la valeur du générateur de nombres aléatoires de R. L’avantage : avec la même graine, vous obtenez la même séquence de nombres à chaque exécution.

set.seed(1234)

Ensuite, mélangez le jeu Iris et assurez‑vous d’avoir des proportions équivalentes d’espèces dans l’entraînement et le test.

Utilisez sample() pour tirer un échantillon de taille égale au nombre de lignes d’Iris, soit 150. Vous échantillonnez avec remise : à partir d’un vecteur de 2 éléments, vous assignez 1 ou 2 aux 150 lignes, avec des probabilités 0,67 et 0,33.

ind <- sample(2, nrow(iris), replace=TRUE, prob=c(0.67, 0.33))

Remarque : l’argument replace est à TRUE : après chaque tirage (1 ou 2), le vecteur est réinitialisé. La probabilité d’obtenir 1 ou 2 à chaque ligne est donc fixée par les poids spécifiés. Notez aussi que, même si cela n’apparaît pas dans le bloc, la graine reste 1234.

Rappel : l’ensemble d’entraînement doit représenter 2/3 du total ; c’est pourquoi vous assignez « 1 » avec une probabilité de 0,67 et « 2 » avec 0,33.

Vous pouvez ensuite utiliser l’échantillon stocké dans ind pour définir vos ensembles d’entraînement et de test :

eyJsYW5ndWFnZSI6InIiLCJwcmVfZXhlcmNpc2VfY29kZSI6InNldC5zZWVkKDEyMzQpXG5pbmQgPC0gc2FtcGxlKDIsIG5yb3coaXJpcyksIHJlcGxhY2U9VFJVRSwgcHJvYj1jKDAuNjcsIDAuMzMpKSIsInNhbXBsZSI6IiMgQ29tcG9zZSB0cmFpbmluZyBzZXRcbmlyaXMudHJhaW5pbmcgPC0gLi4uLltpbmQ9PTEsIDE6NF1cblxuIyBJbnNwZWN0IHRyYWluaW5nIHNldFxuaGVhZCguLi4uLi4uLi4uLi4uLi4uKVxuXG4jIENvbXBvc2UgdGVzdCBzZXRcbmlyaXMudGVzdCA8LSAuLi4uW2luZD09MiwgMTo0XVxuXG4jIEluc3BlY3QgdGVzdCBzZXRcbmhlYWQoLi4uLi4uLi4uLi4pIiwic29sdXRpb24iOiIjIENvbXBvc2UgdHJhaW5pbmcgc2V0XG5pcmlzLnRyYWluaW5nIDwtIGlyaXNbaW5kPT0xLCAxOjRdXG5cbiMgSW5zcGVjdCB0cmFpbmluZyBzZXRcbmhlYWQoaXJpcy50cmFpbmluZylcblxuIyBDb21wb3NlIHRlc3Qgc2V0XG5pcmlzLnRlc3QgPC0gaXJpc1tpbmQ9PTIsIDE6NF1cblxuIyBJbnNwZWN0IHRlc3Qgc2V0XG5oZWFkKGlyaXMudGVzdCkiLCJzY3QiOiJ0ZXN0X29iamVjdChcImlyaXMudHJhaW5pbmdcIilcbnRlc3RfZnVuY3Rpb24oXCJoZWFkXCIsIGFyZ3M9XCJ4XCIsIGluZGV4PTEpXG50ZXN0X29iamVjdChcImlyaXMudGVzdFwiKVxudGVzdF9mdW5jdGlvbihcImhlYWRcIiwgYXJncz1cInhcIiwgaW5kZXg9MikifQ==

Remarque : en plus des proportions 2/3–1/3, vous n’utilisez pas tous les attributs pour former les ensembles. Vous ne prenez que Sepal.Length, Sepal.Width, Petal.Length et Petal.Width. En effet, vous souhaitez prédire le cinquième attribut, Species : c’est votre cible. Vous l’inclurez bien sûr dans KNN pour permettre la prédiction.

Stockez donc les étiquettes de classe dans des vecteurs facteurs et répartissez‑les sur entraînement et test :

eyJsYW5ndWFnZSI6InIiLCJwcmVfZXhlcmNpc2VfY29kZSI6InNldC5zZWVkKDEyMzQpXG5pbmQgPC0gc2FtcGxlKDIsIG5yb3coaXJpcyksIHJlcGxhY2U9VFJVRSwgcHJvYj1jKDAuNjcsIDAuMzMpKSIsInNhbXBsZSI6IiMgQ29tcG9zZSBgaXJpc2AgdHJhaW5pbmcgbGFiZWxzXG5pcmlzLnRyYWluTGFiZWxzIDwtIGlyaXNbaW5kPT0xLDVdXG5cbiMgSW5zcGVjdCByZXN1bHRcbnByaW50KGlyaXMudHJhaW5MYWJlbHMpXG5cbiMgQ29tcG9zZSBgaXJpc2AgdGVzdCBsYWJlbHNcbmlyaXMudGVzdExhYmVscyA8LSBpcmlzW2luZD09MiwgNV1cblxuIyBJbnNwZWN0IHJlc3VsdFxucHJpbnQoaXJpcy50ZXN0TGFiZWxzKSIsInNvbHV0aW9uIjoiIyBDb21wb3NlIGBpcmlzYCB0cmFpbmluZyBsYWJlbHNcbmlyaXMudHJhaW5MYWJlbHMgPC0gaXJpc1tpbmQ9PTEsNV1cblxuIyBJbnNwZWN0IHJlc3VsdFxucHJpbnQoaXJpcy50cmFpbkxhYmVscylcblxuIyBDb21wb3NlIGBpcmlzYCB0ZXN0IGxhYmVsc1xuaXJpcy50ZXN0TGFiZWxzIDwtIGlyaXNbaW5kPT0yLCA1XVxuXG4jIEluc3BlY3QgcmVzdWx0XG5wcmludChpcmlzLnRlc3RMYWJlbHMpIiwic2N0IjoidGVzdF9vYmplY3QoXCJpcmlzLnRyaW5MYWJlbHNcIilcbnRlc3RfZnVuY3Rpb24oXCJwcmludFwiLCBhcmdzPVwieFwiLCBpbmRleD0xKVxudGVzdF9vYmplY3QoXCJpcmlzLnRlc3RMYWJlbHNcIilcbnRlc3RfZnVuY3Rpb24oXCJwcmludFwiLCBhcmdzPVwieFwiLCBpbmRleD0yKSJ9

Étape 6. Construire le modèle KNN

Construction du classifieur

Après la préparation, toutes vos données d’entraînement sont prêtes. Aucun apprentissage n’a encore été réalisé. Vous allez maintenant rechercher les k plus proches voisins pour votre ensemble d’entraînement.

Une façon simple d’effectuer ces deux étapes est d’utiliser la fonction knn(), qui exploite la distance euclidienne pour trouver les k plus proches voisins d’une nouvelle instance inconnue. Le paramètre k est à définir par vous‑même.

Comme indiqué plus haut, les nouvelles instances sont classées via un vote majoritaire ou pondéré. En classification, le point ayant le score le plus élevé « l’emporte » et l’instance inconnue reçoit son étiquette. En cas d’égalité, la classification est aléatoire.

Remarque : on choisit souvent un k impair pour éviter les ex æquo.

Pour construire votre classifieur, utilisez knn() avec les bons arguments, comme dans cet exemple :

eyJsYW5ndWFnZSI6InIiLCJwcmVfZXhlcmNpc2VfY29kZSI6ImxpYnJhcnkoY2xhc3MpXG5zZXQuc2VlZCgxMjM0KVxuaW5kIDwtIHNhbXBsZSgyLCBucm93KGlyaXMpLCByZXBsYWNlPVRSVUUsIHByb2I9YygwLjY3LCAwLjMzKSlcbmlyaXMudHJhaW5pbmcgPC0gaXJpc1tpbmQ9PTEsIDE6NF1cbmlyaXMudGVzdCA8LSBpcmlzW2luZD09MiwgMTo0XVxuaXJpcy50cmFpbkxhYmVscyA8LSBpcmlzW2luZD09MSw1XSIsInNhbXBsZSI6IiMgQnVpbGQgdGhlIG1vZGVsXG5pcmlzX3ByZWQgPC0gLi4uKHRyYWluID0gaXJpcy50cmFpbmluZywgdGVzdCA9IGlyaXMudGVzdCwgY2wgPSBpcmlzLnRyYWluTGFiZWxzLCBrPTMpXG5cbiMgSW5zcGVjdCBgaXJpc19wcmVkYFxuLi4uLi4uLi4uIiwic29sdXRpb24iOiIjIEJ1aWxkIHRoZSBtb2RlbFxuaXJpc19wcmVkIDwtIGtubih0cmFpbiA9IGlyaXMudHJhaW5pbmcsIHRlc3QgPSBpcmlzLnRlc3QsIGNsID0gaXJpcy50cmFpbkxhYmVscywgaz0zKVxuXG4jIEluc3BlY3QgYGlyaXNfcHJlZGBcbmlyaXNfcHJlZCIsInNjdCI6InRlc3RfZnVuY3Rpb24oXCJrbm5cIiwgYXJncz1jKFwidHJhaW5cIiwgXCJ0ZXN0XCIsIFwiY2xcIiwgXCJrXCIpKVxudGVzdF9vdXRwdXRfY29udGFpbnMoXCJpcmlzX3ByZWRcIiwgaW5jb3JyZWN0X21zZz1cIkRpZCB5b3UgaW5zcGVjdCBgaXJpc19wcmVkYD9cIilcbnN1Y2Nlc3NfbXNnKFwiQ29uZ3JhdHMhIFlvdSd2ZSBzdWNjZXNzZnVsbHkgYnVpbHQgeW91ciBmaXJzdCBtYWNoaW5lIGxlYXJuaW5nIG1vZGVsIVwiKSJ9

Vous stockez dans iris_pred l’appel à knn() qui prend en arguments l’ensemble d’entraînement, l’ensemble de test, les étiquettes d’entraînement et le nombre de voisins k. Le résultat est un vecteur facteur avec la classe prédite pour chaque ligne du test.

Remarque : n’indiquez pas les étiquettes du test ; elles serviront à évaluer la qualité de vos prédictions.

En inspectant iris_pred, vous retrouvez bien les classes prédites pour chaque ligne du test.

Étape 7. Évaluer votre modèle

Évaluer la performance est essentiel. En d’autres termes, vous mesurez la justesse des prédictions du modèle.

Pour une première vue, comparez les résultats de iris_pred aux étiquettes de test définies plus tôt :

eyJsYW5ndWFnZSI6InIiLCJwcmVfZXhlcmNpc2VfY29kZSI6ImxpYnJhcnkoY2xhc3MpXG5zZXQuc2VlZCgxMjM0KVxuaW5kIDwtIHNhbXBsZSgyLCBucm93KGlyaXMpLCByZXBsYWNlPVRSVUUsIHByb2I9YygwLjY3LCAwLjMzKSlcbmlyaXMudHJhaW5pbmcgPC0gaXJpc1tpbmQ9PTEsIDE6NF1cbmlyaXMudGVzdCA8LSBpcmlzW2luZD09MiwgMTo0XVxuaXJpcy50cmFpbkxhYmVscyA8LSBpcmlzW2luZD09MSw1XVxuaXJpcy50ZXN0TGFiZWxzID0gIGlyaXNbaW5kPT0yLCA1XVxuaXJpc19wcmVkIDwtIGtubih0cmFpbiA9IGlyaXMudHJhaW5pbmcsIHRlc3QgPSBpcmlzLnRlc3QsIGNsID0gaXJpcy50cmFpbkxhYmVscywgaz0zKSIsInNhbXBsZSI6IiMgUHV0IGBpcmlzLnRlc3RMYWJlbHNgIGluIGEgZGF0YSBmcmFtZVxuaXJpc1Rlc3RMYWJlbHMgPC0gZGF0YS5mcmFtZSguLi4uLi4uLi4uLi4uLi4uKVxuXG4jIE1lcmdlIGBpcmlzX3ByZWRgIGFuZCBgaXJpcy50ZXN0TGFiZWxzYCBcbm1lcmdlIDwtIGRhdGEuZnJhbWUoLi4uLi4uLi4uLCAuLi4uLi4uLi4uLi4uLi4pXG5cbiMgU3BlY2lmeSBjb2x1bW4gbmFtZXMgZm9yIGBtZXJnZWBcbm5hbWVzKC4uLi4uKSA8LSBjKFwiUHJlZGljdGVkIFNwZWNpZXNcIiwgXCJPYnNlcnZlZCBTcGVjaWVzXCIpXG5cbiMgSW5zcGVjdCBgbWVyZ2VgIFxubWVyZ2UiLCJzb2x1dGlvbiI6IiMgUHV0IGBpcmlzLnRlc3RMYWJlbHNgIGluIGEgZGF0YSBmcmFtZVxuaXJpc1Rlc3RMYWJlbHMgPC0gZGF0YS5mcmFtZShpcmlzLnRlc3RMYWJlbHMpXG5cbiMgTWVyZ2UgYGlyaXNfcHJlZGAgYW5kIGBpcmlzLnRlc3RMYWJlbHNgIFxubWVyZ2UgPC0gZGF0YS5mcmFtZShpcmlzX3ByZWQsIGlyaXMudGVzdExhYmVscylcblxuIyBTcGVjaWZ5IGNvbHVtbiBuYW1lcyBmb3IgYG1lcmdlYFxubmFtZXMobWVyZ2UpIDwtIGMoXCJQcmVkaWN0ZWQgU3BlY2llc1wiLCBcIk9ic2VydmVkIFNwZWNpZXNcIilcblxuIyBJbnNwZWN0IGBtZXJnZWAgXG5tZXJnZSIsInNjdCI6InRlc3Rfb2JqZWN0KFwiaXJpc1Rlc3RMYWJlbHNcIilcbnRlc3RfZGF0YV9mcmFtZShcIm1lcmdlXCIsIGNvbHVtbnM9YyhcIlByZWRpY3RlZCBTcGVjaWVzXCIsIFwiT2JzZXJ2ZWQgU3BlY2llc1wiKSwgdW5kZWZpbmVkX21zZz1cIkRpZCB5b3UgY3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIGBpcmlzX3ByZWRgIGFuZCBgaXJpcy50ZXN0TGFiZWxzYCBhcyBkYXRhP1wiLCB1bmRlZmluZWRfY29sc19tc2c9XCJEaWQgeW91IGRlZmluZSB0aGUgY29sdW1ucyBgUHJlZGljdGVkIFNwZWNpZXNgIGFuZCBgT2JzZXJ2ZWQgU3BlY2llc2A/XCIsIGluY29ycmVjdF9tc2c9XCJTb21ldGhpbmcgaXNuJ3QgcmlnaHQgd2l0aCB0aGUgYG1lcmdlYCBkYXRhIGZyYW1lLiBBcmUgeW91IHN1cmUgeW91IGRlZmluZWQgdGhlIGNvcnJlY3QgZGF0YSBhbmQgY29sdW1uIG5hbWVzP1wiKVxudGVzdF9vdXRwdXRfY29udGFpbnMoXCJtZXJnZVwiKSJ9

Le modèle fournit des prédictions globalement correctes, à l’exception d’une mauvaise classification à la ligne 29, où « Versicolor » est prédit alors que l’étiquette réelle est « Virginica ».

Cela donne déjà une indication de performance, mais vous pouvez aller plus loin. Pour cela, importez le package gmodels :

install.packages("package name")

Si le package est déjà installé, exécutez simplement

library(gmodels)

Puis créez un tableau croisé (contingence) pour analyser la relation entre deux variables. Ici, vous souhaitez comprendre comment les classes de votre test, stockées dans iris.testLabels, se comparent aux prédictions de iris_pred :

CrossTable(x = iris.testLabels, y = iris_pred, prop.chisq=FALSE)

Crosstable iris knn

Remarque : l’argument prop.chisq indique si la contribution au chi‑deux de chaque cellule est incluse. La statistique du chi‑deux, somme des contributions cellule par cellule, permet de juger si l’écart entre valeurs observées et attendues est significatif.

À partir de ce tableau, vous déduisez le nombre de prédictions correctes et incorrectes : une instance de l’ensemble de test a été étiquetée Versicolor par le modèle alors qu’il s’agissait d’une fleur Virginica. Vous le voyez dans la première ligne de l’espèce « Virginica » dans la colonne iris.testLabels. Dans tous les autres cas, les prédictions sont correctes. Vous pouvez conclure que la performance du modèle est satisfaisante et qu’il n’est pas nécessaire de l’améliorer !

Learn Python for Data Science With DataCamp

Apprentissage automatique en R avec caret

Dans les sections précédentes, vous avez abordé l’apprentissage supervisé en R via KNN. Comme vous avez pu le deviner, le machine learning en R peut vite se complexifier : multiples algorithmes, syntaxes et paramètres… Se souvenir de chaque package pour chaque algorithme peut devenir difficile, et appliquer la syntaxe propre à chacun l’est tout autant.

C’est là que le package caret est utile : « Classification and Regression Training », il fournit une interface unifiée couvrant une multitude d’algorithmes pour résoudre vos problèmes d’apprentissage supervisé. Si vous connaissez un peu le machine learning en Python, vous y verrez des similitudes avec scikit-learn !

Nous allons reprendre les étapes vues ci‑dessus, mais cette fois avec caret pour classifier les données. Si vous avez suivi jusqu’ici, vous avez déjà bien avancé : compréhension des données, exploration, préparation de l’environnement, etc. Passons maintenant au prétraitement avec caret !

Comme précédemment, vous pourrez étudier l’effet de la normalisation ; cela viendra un peu plus loin.

Vous connaissez la suite ! Scindons les données en entraînement et test. Cette fois, on procède légèrement différemment : on sépare en fonction des étiquettes iris$Species, et on adopte un ratio 75–25.

eyJsYW5ndWFnZSI6InIiLCJwcmVfZXhlcmNpc2VfY29kZSI6ImxpYnJhcnkoY2FyZXQpXG5zZXQuc2VlZCgxMjM0KSIsInNhbXBsZSI6IiMgQ3JlYXRlIGluZGV4IHRvIHNwbGl0IGJhc2VkIG9uIGxhYmVscyAgXG5pbmRleCA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKGlyaXMkU3BlY2llcywgcD0wLjc1LCBsaXN0PUZBTFNFKVxuXG4jIFN1YnNldCB0cmFpbmluZyBzZXQgd2l0aCBpbmRleFxuaXJpcy50cmFpbmluZyA8LSBpcmlzWy4uLi4uLi4sXVxuXG4jIFN1YnNldCB0ZXN0IHNldCB3aXRoIGluZGV4XG5pcmlzLnRlc3QgPC0gaXJpc1stLi4uLi4uLi4uLF0iLCJzb2x1dGlvbiI6IiMgQ3JlYXRlIGluZGV4IHRvIHNwbGl0IGJhc2VkIG9uIGxhYmVscyAgXG5pbmRleCA8LSBjcmVhdGVEYXRhUGFydGl0aW9uKGlyaXMkU3BlY2llcywgcD0wLjc1LCBsaXN0PUZBTFNFKVxuXG4jIFN1YnNldCB0cmFpbmluZyBzZXQgd2l0aCBpbmRleFxuaXJpcy50cmFpbmluZyA8LSBpcmlzW2luZGV4LF1cblxuIyBTdWJzZXQgdGVzdCBzZXQgd2l0aCBpbmRleFxuaXJpcy50ZXN0IDwtIGlyaXNbLWluZGV4LF0iLCJzY3QiOiJ0ZXN0X29iamVjdChcImluZGV4XCIpXG50ZXN0X29iamVjdChcImlyaXMudHJhaW5pbmdcIilcbnRlc3Rfb2JqZWN0KFwiaXJpcy50ZXN0XCIpXG5zdWNjZXNzX21zZyhcIkF3ZXNvbWUhIFdlbGwgZG9uZSFcIikifQ==

Vous êtes prêt à entraîner des modèles ! Mais souvenez‑vous : caret est un projet très vaste couvrant un grand nombre d’algorithmes. En cas de doute, listez‑les avec names(getModelInfo()), comme ci‑dessous. Choisissez ensuite un algorithme et entraînez un modèle avec train() :

eyJsYW5ndWFnZSI6InIiLCJwcmVfZXhlcmNpc2VfY29kZSI6ImxpYnJhcnkoY2FyZXQpXG5zZXQuc2VlZCgxMjM0KVxuaW5kZXggPC0gY3JlYXRlRGF0YVBhcnRpdGlvbihpcmlzJFNwZWNpZXMsIHA9MC43NSwgbGlzdD1GQUxTRSlcbmlyaXMudHJhaW5pbmcgPC0gaXJpc1tpbmRleCxdXG5pcmlzLnRlc3QgPC0gaXJpc1staW5kZXgsXSIsInNhbXBsZSI6IiMgT3ZlcnZpZXcgb2YgYWxnb3Mgc3VwcG9ydGVkIGJ5IGNhcmV0XG5uYW1lcyhnZXRNb2RlbEluZm8oKSlcblxuIyBUcmFpbiBhIG1vZGVsXG5tb2RlbF9rbm4gPC0gdHJhaW4oaXJpcy50cmFpbmluZ1ssIDE6NF0sIGlyaXMudHJhaW5pbmdbLCA1XSwgbWV0aG9kPSdrbm4nKSJ9

Créer d’autres modèles devient alors trivial : changez simplement l’argument method, comme ici :

model_cart <- train(iris.training[, 1:4], iris.training[, 5], method='rpart2')

Une fois le modèle entraîné, prédisez les étiquettes de l’ensemble de test et évaluez ses performances :

eyJsYW5ndWFnZSI6InIiLCJwcmVfZXhlcmNpc2VfY29kZSI6ImxpYnJhcnkoY2FyZXQpXG5zZXQuc2VlZCgxMjM0KVxuaW5kZXggPC0gY3JlYXRlRGF0YVBhcnRpdGlvbihpcmlzJFNwZWNpZXMsIHA9MC43NSwgbGlzdD1GQUxTRSlcbmlyaXMudHJhaW5pbmcgPC0gaXJpc1tpbmRleCxdXG5pcmlzLnRlc3QgPC0gaXJpc1staW5kZXgsXVxubW9kZWxfa25uIDwtIHRyYWluKGlyaXMudHJhaW5pbmdbLCAxOjRdLCBpcmlzLnRyYWluaW5nWywgNV0sIG1ldGhvZD0na25uJykiLCJzYW1wbGUiOiIjIFByZWRpY3QgdGhlIGxhYmVscyBvZiB0aGUgdGVzdCBzZXRcbnByZWRpY3Rpb25zPC1wcmVkaWN0KG9iamVjdD1tb2RlbF9rbm4saXJpcy50ZXN0WywxOjRdKVxuXG4jIEV2YWx1YXRlIHRoZSBwcmVkaWN0aW9uc1xudGFibGUocHJlZGljdGlvbnMpXG5cbiMgQ29uZnVzaW9uIG1hdHJpeCBcbmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9ucyxpcmlzLnRlc3RbLDVdKSIsInNvbHV0aW9uIjoiIyBQcmVkaWN0IHRoZSBsYWJlbHMgb2YgdGhlIHRlc3Qgc2V0XG5wcmVkaWN0aW9uczwtcHJlZGljdC50cmFpbihvYmplY3Q9bW9kZWxfa25uLGlyaXMudGVzdFssMTo0XSwgdHlwZT1cInJhd1wiKVxuXG4jIEV2YWx1YXRlIHRoZSBwcmVkaWN0aW9uc1xudGFibGUocHJlZGljdGlvbnMpXG5cbiMgQ29uZnVzaW9uIG1hdHJpeCBcbmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9ucyxpcmlzLnRlc3RbLDVdKSIsInNjdCI6InRlc3Rfb2JqZWN0KFwicHJlZGljdGlvbnNcIilcbnRlc3RfZnVuY3Rpb24oXCJ0YWJsZVwiKVxudGVzdF9mdW5jdGlvbihcImNvbmZ1c2lvbk1hdHJpeFwiKVxuc3VjY2Vzc19tc2coXCJXZWxsIGRvbmUhXCIpIn0=

Vous pouvez également reproduire le test précédent pour mesurer l’effet du prétraitement (centrage et mise à l’échelle) sur votre modèle. Exécutez le bloc suivant :

eyJsYW5ndWFnZSI6InIiLCJwcmVfZXhlcmNpc2VfY29kZSI6ImxpYnJhcnkoY2FyZXQpXG5zZXQuc2VlZCgxMjM0KVxuaW5kZXggPC0gY3JlYXRlRGF0YVBhcnRpdGlvbihpcmlzJFNwZWNpZXMsIHA9MC43NSwgbGlzdD1GQUxTRSlcbmlyaXMudHJhaW5pbmcgPC0gaXJpc1tpbmRleCxdXG5pcmlzLnRlc3QgPC0gaXJpc1staW5kZXgsXSIsInNhbXBsZSI6IiMgVHJhaW4gdGhlIG1vZGVsIHdpdGggcHJlcHJvY2Vzc2luZ1xubW9kZWxfa25uIDwtIHRyYWluKGlyaXMudHJhaW5pbmdbLCAxOjRdLCBpcmlzLnRyYWluaW5nWywgNV0sIG1ldGhvZD0na25uJywgcHJlUHJvY2Vzcz1jKFwiY2VudGVyXCIsIFwic2NhbGVcIikpXG5cbiMgUHJlZGljdCB2YWx1ZXNcbnByZWRpY3Rpb25zPC1wcmVkaWN0LnRyYWluKG9iamVjdD1tb2RlbF9rbm4saXJpcy50ZXN0WywxOjRdLCB0eXBlPVwicmF3XCIpXG5cbiMgQ29uZnVzaW9uIG1hdHJpeFxuY29uZnVzaW9uTWF0cml4KHByZWRpY3Rpb25zLGlyaXMudGVzdFssNV0pIiwic29sdXRpb24iOiIjIFRyYWluIHRoZSBtb2RlbCB3aXRoIHByZXByb2Nlc3Npbmdcbm1vZGVsX2tubiA8LSB0cmFpbihpcmlzLnRyYWluaW5nWywgMTo0XSwgaXJpcy50cmFpbmluZ1ssIDVdLCBtZXRob2Q9J2tubicsIHByZVByb2Nlc3M9YyhcImNlbnRlclwiLCBcInNjYWxlXCIpKVxuXG4jIFByZWRpY3QgdmFsdWVzXG5wcmVkaWN0aW9ucz0tcHJlZGljdC50cmFpbihvYmplY3Q9bW9kZWxfa25uLGlyaXMudGVzdFssMTo0XSwgdHlwZT1cInJhd1wiKVxuXG4jIENvbmZ1c2lvbiBtYXRyaXhcbmNvbmZ1c2lvbk1hdHJpeChwcmVkaWN0aW9ucyxpcmlzLnRlc3RbLDVdKSIsInNjdCI6InRlc3Rfb2JqZWN0KFwibW9kZWxfa25uXCIsIGV2YWw9RkFMU0UpXG50ZXN0X29iamVjdChcInByZWRpY3Rpb25zXCIpXG50ZXN0X2Z1bmN0aW9uKFwiY29uZnVzaW9uTWF0cml4XCIsIGFyZ3M9YyhcImRhdGFcIiwgXCJyZWZlcmVuY2VcIikpXG5zdWNjZXNzX21zZyhcIkNvbmdyYXR1bGF0aW9ucyEgWW91IGhhdmUgc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCB0aGUgdHV0b3JpYWwhXCIpIn0=

Cap sur le big data

Félicitations ! Vous êtes arrivé au bout de ce tutoriel !

Nous nous sommes concentrés sur la mise en œuvre de KNN en R. Le jeu de données Iris étant petit et facile à explorer, vous avez vu comment enchaîner les étapes manuellement, puis comment accélérer avec une interface unifiée comme celle de caret.

Mais vous pouvez aller bien plus loin !

Après avoir expérimenté les bases présentées ici et d’autres algorithmes, vous aurez sans doute envie d’approfondir R et l’analyse de données.

Sujets
R
Science des données
Apprentissage automatique

Cours R

Cours

Introduction à R

4 h
3.1M
Maîtrisez les bases de l’analyse de données en R et pratiquez les vecteurs, listes et data frames avec des données réelles.
Afficher les détailsRight Arrow
Commencer Le Cours
Voir plusRight Arrow