Classification non supervisée : partitionnement d'un jeu de données

Dans ce TP, nous abordons la classification non supervisée, en particulier les méthodes de partitionnement, ou segmentation, de données, clustering en anglais. On pourra consulter mes notes de cours de fouille de données pour une présentation de la classification non supervisée (chapitre 10).

À l'issue de ce TP, vous m'envoyez par email un compte-rendu (format pdf) indiquant la réponse aux questions qui sont posées. Vous m'envoyez également un fichier python réalisant toutes les manipulations de ce TP : je dois pouvoir exécuter ce fichier en tapant python3 nom-de-votre-fichier.py et reproduire vos résultats. Cette exécution ne doit pas provoquer d'erreur de python. Remarque : un notebook ne convient pas.

Introduction

Nous allons étudier la méthode probablement la plus connue, les k-moyennes (k-means en anglais) qui a été décrite en cours. Au besoin, se référer à mon polycopié concernant cette méthode.
Par rapport à la classification supervisée, la classification non supervisée a ceci de particulier que l'on ne connait pas le résultat attendu. Aussi, juger de la qualité d'un partitionnement est-il quelque chose qui est difficile.
Là encore, à chaque fois que cela est possible, une exploration visuelle des données est essentielle que ce soit avant d'appliquer un algorithme de partitionnement de données pour essayer de voir ce qu'il semble raisonnable que l'algorithme produise et ensuite, pour juger le résultat produit par l'algorithme. Comme tous les algorithmes, ceux de partitionnement font toujours quelque chose, il calcule toujours un résultat. Ils sont incapables de juger si ce qu'ils ont fait est pertinent : seul l'humain peut le déterminer en anticipant sur le résultat que devrait produire l'algorithme et en jugeant le résultat produit par l'algorithme.

K-moyennes

Description de la méthode KMeans () de scikit_learn

On utilise la méthode KMeans () de scikit_learn. Pour y avoir accès, on doit faire :
from sklearn.cluster import KMeans
Sous sa forme la plus simple, on l'utilise comme suit. On commence par créer un objet Kmeans :
partitionneur = sklearn.cluster.KMeans (nombre_de_parties, random_state)
que l'on peut ensuite appliquer à un jeu de données contenu dans une matrice X :
partition = partitionneur. fit (X)
L'objet partition contient différentes informations :

Les deux paramètres de KMeans () indiqués plus haut sont :

Mise en application

On va mettre en application la méthode KMeans () sur ce jeu de données.
Pour cela :

  1. Lire le jeu de données dans un tableau de données.
  2. Visualiser ce jeu de données : que voyez-vous ? Que va faire faire l'algorithme des k-moyennes ?
  3. Partitionner le jeu de données avec la méthode KMeans ()
  4. Visualiser le résultat en utilisant une couleur différente pour chacune des partie. Le résultat est-il conforme à vos attentes ?

Allons plus loin : déterminer le nombre de parties

L'une des difficultés rencontrées en partitionnement de données concerne la détermination du nombre de parties. Sur l'exemple que nous venons de traiter, ce nombre est évident, il saute aux yeux. Sur des données réelles, c'est rarement le cas. On va utiliser ce jeu de données très simple pour voir comment déterminer ce nombre de parties vraisemblablement le meilleur. On va voir deux méthodes, l'une basée sur l'inertie, l'autre sur le score de silhouette.
Dans les deux cas, l'idée est simple : on calcule des partitions avec des nombres de parties variant par exemple de 2 à 10 et on utilise un score pour déterminer le « bon » nombre de parties.

Déterminer le nombre de groupes avec l'inertie
Effectuer des partitionnements pour un nombre de parties variant de 2 à 10. Pour chaque partitionnement, stocker son inertie dans une liste. Ensuite, visualiser l'inertie en fonction du nombre de groupes et déterminer le coude.
Que trouvez-vous ?

Déterminer le nombre de groupes par le score de silhouette
Le principe est le même mais avant cela, je dois expliquer comment on calcule le coefficient de silhouette.
On utilise la méthode sklearn.metrics.silhouette_score (X, cluster_labels)X est le jeu de données à partitionner et cluster_labels est le numéro de partie assigné à chaque donnée.
Effectuer des partitionnements pour un nombre de parties variant de 2 à 10. Pour chaque partitionnement, calculer son coefficient de silhouette et stocker le dans une liste. Ensuite, déterminer le nombre de parties qui maximise ce score. Il est intéressant également de visualiser ce coefficient en fonction du nombre de parties.
Que trouvez-vous ? La même chose qu'avec l'inertie ?

Allons encore plus loin : initialisation des centroïdes

Dans la méthode des k-moyennes, l'initialisation des centroïdes détermine l'issue de la partition puisque l'algorithme est déterministe. Aussi cette initialisation est-elle très importante : une mauvaise initialisation peut entraîner de mauvais résultats.
Tel qu'utilisée jusqu'ici, la méthode KMeans () initialise automatiquement les centroïdes en utilisant un algorithme qui généralement donne de bons résultats. Néanmoins, il peut arriver que cet algorithme initialise mal les centroïdes. Aussi, il est toujours prudent de comparer les résultats obtenus avec cette initialisation et d'autres, par exemple une initialisation au hasard. Pour cela, il faut ajouter le paramètre init = "random" lors de l'appel de KMeans ().
On peut aussi réaliser un certain nombre d'exécutions de l'algorithme des k moyennes en initialisant aléatoirement les centroïdes. Pour cela, on indique n_init = 20 si on veut réaliser 20 exécutions. KMeans () renvoie alors le meilleur résultat parmi les 20 (meilleur au sens de l'inertie intraclasse).
Tester cette initialisation aléatoire  effectuer par exemple 10 exécutions de KMeans () avec une initialisation aléatoire. On mesure la qualité du partitionnement à l'aide de l'inertie intraclasse et du coefficient de silhouette. Trouvez-vous de meilleurs partitionnements ?

Activités en autonomie

Appliquer tout ce qui vient d'être expliqué aux jeux de données suivants :

  1. ce fichier.
  2. Les iris : c'est un jeu de données célèbre souvent utilisé en classification supervisée. Il est constitué de 150 individus, chacun décrivant une fleur d'iris. Chaque individu est décrit par 4 attributs qui sont la longueur et la largeur des sépales (attributs 0 et 1 respectivement), la longueur et la largeur des pétales (attributs 2 et 3 respectivement). Chaque individu est d'une certaine espèce parmi 3, ce qui constitue la classe de la donnée. Les trois classes sont Setosa, Versicolor et Virginica.
    Le jeu de données des iris est disponible en faisant :
    from sklearn.datasets import load_iris
    iris = load_iris (). data
    classe = load_iris (). target
    iris et target sont des tableaux numpy (pas des data.frames pandas). iris est donc un tableau de 150 lignes sur 4 colonnes.
    Dans le contexte de ce TP, on applique la méthode des k moyennes sur les attributs des iris. La classe permettra de juger la qualité du partitionnement obtenu par rapport au partitionnement attendu. Une table de contingence permet de juger le résultat.
    Il est très facile d'écrire quelques lignes de python pour calculer une table de contingence. Sinon, on pourra utiliser la fonction contigency_matrix(). On doit l'importer avec :
    from sklearn.metrics.cluster import contingency_matrix
    et ensuite, on peut l'utiliser pour comparer la classe des iris avec le résultat du partitionnement comme suit :
    contingency_matrix (classe, partitionIris. labels_)
    en supportant que partitionIris contient le résultat du partitionnement du jeu de données.
  3. ce fichier
  4. ce fichier
  5. ce fichier
  6. Appliquer les k-moyennes à ce jeu de données. Ce jeu de données (utilisé lors du premier contrôle de SD 2) contient la description d'insectes. Comme pour les iris, chaque donnée possède une classe (attribut species) et 6 attributs qui spécifient certaines caractéristiques physiques de chaque individu.
    Comme pour les iris, vous comparez le résultat des k-moyennes avec la partition corespondant à la classe définissant ce jeu de données.
  7. ce dernier jeu de données. Faites comme ci-dessus.Le résultat est-il conforme à vos attentes ? Si non, déterminez la cause et remédiez-y.

Dans chaque cas, il faut essayer de déterminer le nombre de groupes. Comme d'habitude et rappelé en début de TP, il faut visualiser les données avant d'essayer de les partitionner afin d'essayer de voir ce que l'on aimerait obtenir et ce que l'algorithme des k-moyennes devrait calculer, et ensuite, visualiser le résultat et constater l'accord ou le désaccord entre ce que l'on attendait et ce que l'on a obtenu. En cas de désaccord, comprendre son origine.