Segmentation par les k-moyennes

L'objectif de ce TD est de manipuler l'algorithme des k-moyennes disponible dans R.

Les k-moyennes en R

La fonction kmeans()

L'algorithme des k-moyennes est disponible au travers de la fonction kmeans() de R. L'utilisation en est très simple :

kmeans (iris [,1:4], 3)

exécute l'algorithme des k-moyennes sur le jeu de données iris en utilisant les quatre attributs longueur et largeur des sépales et des pétales, en utilisant 3 centres.
À l'issue de son exécution, kmeans() a associé chaque donnée à un groupe ; les groupes sont numérotés de 1 à K.

kmeans() fournit une liste d'objets (on sait cela en tapant la commande help("kmeans") :

On peut exécuter plusieurs segmentations et considérer la meilleure en utilisant l'argument nstart :

kmeans (iris [,-5], 3, nstart = 30)

Par défaut, kmeans() effectue 10 itérations ; cela peut être insuffisant pour que l'algorithme converge ; dans ce cas, le message :

Warning message:
did not converge in 10 iterations

est affiché. On peut augmenter le nombre d'itérations avec le paramètre iter.max=nn est le nombre d'itérations à effectuer (50 par exemple).

Visualisation de la segmentation

On peut visualiser le résultat de la segmentation à l'aide de couleurs. Ainsi, supposons que vous ayez segmenté en trois segments les iris et placé le résultat dans iris.3means.

  plot (iris$Petal.Length, iris$Petal.Width)

représente chacun des iris dans le plan longueur des pétales x largeur des pétales.

  1. faites en sorte que chaque donnée soit colorée en fonction de sa classe. Vous obtiendrez par exemple : les iris
  2. faites en sorte que chaque donnée soit colorée en fonction du groupe dans lequel kmeans() l'a placé ;
  3. en utilisant la fonction table(), faites une table de contingence entre classe des iris et classe trouvée par kmeans() (matrice de confusion). Qu'en pensez-vous ?

Trouver K optimal

On s'intéresse maintenant à trouver le nombre de groupes. Pour cela, on va essayer plusieurs valeurs de K qui semblent raisonnables. Par exemple, on essaie toutes les valeurs entre 2 et 10.

Pour cela, on fera une boucle :

  for (k in 2:10)
    ...

Chacune des segmentations (pour chacune des valeurs de k) est placée dans une liste :

  iris.kmeans <- list()
  for (k in 2:10)
    iris.kmeans [[k]] <- kmeans (iris [, -5], k, nstart = 30)

iris.kmeans [[2]] contiendra le résultat de kmeans() pour k = 2 (attention, ce sont des doubles crochets car iris.kmeans est une liste, pas un vecteur), iris.kmeans [[3]] contiendra le résultat de kmeans() pour k = 3, ... iris.kmeans [[10]] contiendra le résultat de kmeans() pour k = 10.

  1. calculer l'inertie intraclasse de ces 9 segmentations ;
  2. faites-en un graphe ;
  3. quelle segmentation est la meilleure ?

Activités exploratoires

  1. sur les iris, comparez les segmentations à 3 et à 4 groupes (visuellement en utilisant un graphe comme plus haut, et via leur matrice de confusion).
  2. Faites une segmentation des iris en utilisant uniquement les attributs longueur et largeur des pétales. Le résultat est-il le même qu'en utilisant les 4 attributs ?
    1. déterminez le nombre de groupes et les groupes dans le jeu de données disponibles à l'url https://philippe-preux.github.io/ensg/miashs/fouilleDeDonneesII/tp/k-moyennes/jeu1.txt et visualisez la segmentation optimale avec des couleurs.
      Pour charger ce jeu de données et les suivants (sauf exception indiquée) dans R, vous utiliserez la commande read.table (url, header = T). (Ces fichiers ne sont pas au format CSV.)
    2. mêmes questions pour ce fichier : https://philippe-preux.github.io/ensg/miashs/fouilleDeDonneesII/tp/k-moyennes/jeu2.txt (dans ce cas, pour la visualisation, ne prendre en compte que les deux premiers attributs)
    3. et celui-là : https://philippe-preux.github.io/ensg/miashs/fouilleDeDonneesII/tp/k-moyennes/jeu3.txt (même remarque pour la visualisation)
  3. on considère le jeu de données disponible à l'url https://philippe-preux.github.io/ensg/miashs/fouilleDeDonneesII/tp/k-moyennes/jeu4.txt.
    Pour charger ce jeu de données, vous utiliserez la commande read.table (url).
    1. faites en une segmentation en 3 groupes
    2. visualisez le jeu de données (par un plot() tout simple sur les deux premiers attributs)
    3. visualisez le jeu de données en colorant chaque point par une couleur différente en fonction du groupe auquel kmeans() l'a associé. Qu'en pensez-vous ?
    4. chercher le K optimal. Faites une représentation graphique de cette segmentation « optimale » ; qu'en pensez-vous ?
  4. on considère le jeu de données disponible à l'url https://philippe-preux.github.io/ensg/miashs/fouilleDeDonneesII/tp/k-moyennes/jeu5.txt.
    Pour charger ce jeu de données, vous utiliserez la commande read.table (url).
    1. Répondre aux mêmes questions que précédemment.
    2. Pensez-vous qu'une transformation des données permettrait à kmeans() de trouver les groupes attendus ?
    3. Mettez en œuvre cette idée.
  5. on considère le jeu de données disponible à l'url https://philippe-preux.github.io/ensg/miashs/fouilleDeDonneesII/tp/k-moyennes/jeu11.txt.
    1. Visualisez le jeu de données (par un plot() tout simple sur les deux premiers attributs)
    2. Faites des kmeans() pour k variant de 2 à 10
    3. Quel est le k optimal ? Faites une représentation graphique de cette segmentation « optimale » ; qu'en pensez-vous ? kmeans() fait n'importe quoi ou bien... ?