"plt.title('dataset'); # on met un \";\" final sous Jupyter pour éviter des affichages intempestifs dans le carnet"
"plt.title('dataset')\n",
"plt.show()"
]
},
{
...
...
@@ -144,7 +145,8 @@
"maxdist=max(Z[:,2]) # hauteur du dendrogramme \n",
"plt.figure(figsize=[9,6]);\n",
"dendrogram(Z) #,truncate_mode=\"level\",p=10); # le paramètre p permet éventuellement de ne pas afficher le \"bas\" du dendrogramme, utile pour un grand jeu de données\n",
"plt.title('Single linkage dendrogram with scipy'); "
"plt.title('Single linkage dendrogram with scipy')\n",
# Introduction à l'apprentissage automatique: TP2 - Exercice 1
<br>
## Algorithmes de partitionnement et données synthétiques
Le but de ce premier exercice est d'explorer des algorithmes de partitionnement ( _clustering_ ) sur des jeux de données synthétiques 2D. On comparera les classifications hiérarchiques et l'algorithme $K$-means.
Cet exercice est inspiré en partie de [cette page de la documentation scikit-learn](https://scikit-learn.org/stable/auto_examples/cluster/plot_cluster_comparison.html#sphx-glr-auto-examples-cluster-plot-cluster-comparison-py)
Dans cet exercice (et seulement dans cet exercice), on utilisera les algorithmes de classification hiérarchique de la bibliothèque `scipy` plutôt que ceux de `scikit-learn` de manière à tracer facilement les dendrogrammes; ils sont décrits [ici](https://docs.scipy.org/doc/scipy/reference/generated/scipy.cluster.hierarchy.linkage.html)
<br>
__TRAVAIL A FAIRE (il s'agit de l'objectif des questions suivantes)__: mettez en évidence les propriétés / limites des différents algorithmes en jouant sur les paramètres. Pour chaque jeu de données synthétiques défini ci-dessous:
- pour les classifications hiérarchiques, faites le lien entre le dendrogramme et les valeurs de seuil permettant de trouver des clusters raisonnables dans chaque jeu de donnée
- quel(s) jeu(x) de données pose(nt) le problème du _chaînage_ pour la classification _single linkage_ ? Dans ce cas, que donne le critère de Ward?
- pour la méthode des $K$-moyennes, la méthode du coude permet-elle de fixer simplement la valeur de $K$?
- discutez la pertinence des résultats de chaque méthode selon le jeu de données
Exécutez les cellules de ce carnet Jupyter les unes après les autres. Attention à bien exécuter les cellules dans l'ordre, sinon vous n'allez pas travailler avec les bonnes variables (en particulier, le dendrogramme dans la variable $Z$ doit avoir été calculé juste avant de le représenter graphiquement, sinon l'affichage sera incohérent).
En cas de problème d'exécution du code Python, vous pouvez redémarrer le noyau / kernel (onglet dans la barre du carnet Jupyter en haut).
%% Cell type:markdown id: tags:
## 1. On commence par charger les bibliothèques utiles
## 3. Partitionnement des jeux de données avec différents algorithmes
%% Cell type:markdown id: tags:
### 3.1 Visualisation du jeu de données à partitionner
La première ligne de la cellule suivante permet de changer le jeu de données: commencez par _blobs_ et exécutez le carnet jusque la fin, puis ré-exécuter le carnet depuis ici avec _moons_ , _aniso_ , _varied_ .
<aid="debut"></a>
%% Cell type:code id: tags:
``` python
X,y=blobs# changer le dataset ici (commencer par blobs, puis moons, aniso, varied)
plt.figure(figsize=[9,6])
plt.scatter(X[:,0],X[:,1],s=40)
plt.title('dataset');# on met un ";" final sous Jupyter pour éviter des affichages intempestifs dans le carnet
dendrogram(Z)#,truncate_mode="level",p=10); # le paramètre p permet éventuellement de ne pas afficher le "bas" du dendrogramme, utile pour un grand jeu de données
plt.title('Single linkage dendrogram with scipy');
plt.title('Single linkage dendrogram with scipy')
plt.show()
```
%% Cell type:markdown id: tags:
La cellule suivante permet de changer la valeur du seuil (variable _seuil_ ) dans le dendrogramme de manière interactive (cela fixe donc le nombre de clusters) et affiche le partitionnement correspondant:
%% Cell type:code id: tags:
``` python
@interact(seuil=(0,maxdist,maxdist/100))# "décorateur" Jupyter, permettant une interaction avec un argument de la fonction
plt.title('Single linkage with scipy, seuil='+str(seuil)+', nombres de clusters: '+str(max(clusters)));
plt.title('Single linkage with scipy, seuil='+str(seuil)+', nombres de clusters: '+str(max(clusters)))
plt.show()
```
%% Cell type:code id: tags:
``` python
# dans certains cas (en particulier sur MacOS) @interact ne fonctionne pas
# dans certains cas, @interact ne fonctionne pas
# (si la cellule précédente fonctionne, n'exécutez pas le code de la présente cellule)
# si vous êtes dans cette situation, faites varier la valeur de seuil entre 0 et maxdist et appelez la fonction d'affichage
# si vous êtes dans cette situation, faites varier la valeur de seuil entre 0 et maxdist et appelez la fonction d'affichage,
# comme ci-dessous:
# (vous ferez de même dans les cellules ci-dessous faisant appel à @interact)
print(maxdist)
seuil=0.5
print(seuil)
graphique_clustering_single(seuil)
```
%% Cell type:markdown id: tags:
__Question 1__. Jouez avec le seuil et faites le lien entre le dendogramme et le nombre de groupes. Le partitionnement vous semble-t-il correspondre à ce qu'on aimerait obtenir? (à discuter selon le dataset)
%% Cell type:markdown id: tags:
Réciproquement, la cellule suivante permet de changer la valeur du nombre de clusters ($nc$) à trouver et "coupe" le dendrogramme à la hauteur correspondate:
plt.title('Single linkage with scipy, n_cluster='+str(nc))
plt.show()
```
%% Cell type:markdown id: tags:
<fontcolor=red>
_Votre réponse ici:_
</font>
%% Cell type:markdown id: tags:
### 3.3 Classification hiérarchique, critère de Ward
On commence par afficher le dendrogramme:
%% Cell type:code id: tags:
``` python
Z=linkage(X,method="ward")
maxdist=max(Z[:,2])
plt.figure(figsize=[9,6]);
dendrogram(Z)#,truncate_mode="level",p=5)
plt.title('Ward criterion dendrogram with scipy');# met quelques secondes à s'afficher
plt.title('Ward criterion dendrogram with scipy')
plt.show()
```
%% Cell type:markdown id: tags:
__Question 2__. Comparez l'aspect du dendrogramme avec celui obtenu avec le critère single-linkage, et les différences de comportement selon le dataset.
%% Cell type:markdown id: tags:
<fontcolor=red>
_Votre réponse ici:_
</font>
%% Cell type:markdown id: tags:
Changez la valeur du seuil (variable _seuil_ ) dans le dendrogramme (qui fixe le nombre de clusters):
plt.title('Ward linkage with scipy, n_cluster='+str(nc))
plt.show()
```
%% Cell type:markdown id: tags:
### 3.4 $K$-means
L'algorithmes des $K$-moyennes ( _$K$-means_ ) est décrit sur [cette page](http://scikit-learn.org/stable/modules/generated/sklearn.cluster.KMeans.html) et sur [celle-ci](http://scikit-learn.org/stable/modules/clustering.html#k-means)(rappel du cours).
__Question 3__. Pour quels datasets $K$-means vous semble-t-il adapté? Constatez que d'une exécution à l'autre, l'algorithme peut donner un résultat différent. Pour quelle raison?
%% Cell type:markdown id: tags:
<fontcolor=red>
_Votre réponse ici:_
</font>
%% Cell type:markdown id: tags:
On va tracer le graphique de l'inertie optimale à $K$ fixé, en fonction du nombre $K$ de clusters cherchés. La méthode du "coude" ( _elbow_ ) fixe $K$ comme le premier point du graphique où l'inertie ne baisse plus vraiment et s'infléchit (présence d'un "coude").
%% Cell type:code id: tags:
``` python
inertie=np.zeros((10))
forKinrange(1,11):
clustering=cluster.KMeans(n_clusters=K,n_init=10)
clustering.fit(X)
inertie[K-1]=clustering.inertia_
plt.figure(figsize=[9,6]);
plt.plot(np.arange(1,11),inertie);
plt.plot(np.arange(1,11),inertie)
plt.xlabel("K");
plt.ylabel("inertie");
plt.title("elbow plot");
plt.ylabel("inertie")
plt.title("elbow plot")
plt.show()
```
%% Cell type:markdown id: tags:
__Question 4__. Pour quel(s) dataset(s) la méthode du coude vous semble-t-elle adaptée?