Introduction
Dans ce laboratoire, nous explorerons l'algorithme de clustering K-Means à l'aide de la bibliothèque scikit-learn en Python. Nous utiliserons l'ensemble de données de chiffres manuscrits, qui contient 64 caractéristiques représentant une image 8x8 d'un chiffre, et nous essaierons de regrouper les images ensemble en fonction du chiffre qu'elles représentent. Nous comparerons les différentes méthodes d'initialisation pour K-Means et évaluerons les performances du clustering à l'aide de diverses métriques.
Conseils sur la VM
Une fois le démarrage de la VM terminé, cliquez dans le coin supérieur gauche pour basculer vers l'onglet Notebook pour accéder à Jupyter Notebook pour la pratique.
Parfois, vous devrez peut-être attendre quelques secondes pour que Jupyter Notebook ait fini de charger. La validation des opérations ne peut pas être automatisée en raison des limitations de Jupyter Notebook.
Si vous rencontrez des problèmes pendant l'apprentissage, n'hésitez pas à demander à Labby. Donnez des commentaires après la session, et nous résoudrons rapidement le problème pour vous.
Charger l'ensemble de données
Nous commencerons par charger l'ensemble de données de chiffres à l'aide de la fonction load_digits() de scikit-learn. Cette fonction renvoie les caractéristiques et les étiquettes pour l'ensemble de données.
import numpy as np
from sklearn.datasets import load_digits
data, labels = load_digits(return_X_y=True)
(n_samples, n_features), n_digits = data.shape, np.unique(labels).size
Définir le critère d'évaluation
Nous allons définir un critère d'évaluation pour comparer les différentes méthodes d'initialisation pour K-Means. Notre critère d'évaluation va :
- créer un pipeline qui mettra à l'échelle les données à l'aide d'un
StandardScaler - entraîner et mesurer le temps d'ajustement du pipeline
- mesurer les performances du clustering obtenu via différentes métriques
from time import time
from sklearn import metrics
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
def bench_k_means(kmeans, name, data, labels):
"""Benchmark to evaluate the KMeans initialization methods.
Paramètres
----------
kmeans : instance de KMeans
Une instance de `KMeans` avec l'initialisation déjà définie.
name : str
Nom donné à la stratégie. Il sera utilisé pour afficher les résultats dans un tableau.
data : ndarray de forme (n_samples, n_features)
Les données à regrouper.
labels : ndarray de forme (n_samples,)
Les étiquettes utilisées pour calculer les métriques de clustering qui nécessitent une certaine supervision.
"""
t0 = time()
estimator = make_pipeline(StandardScaler(), kmeans).fit(data)
fit_time = time() - t0
results = [name, fit_time, estimator[-1].inertia_]
## Définir les métriques qui ne nécessitent que les vraies étiquettes et les étiquettes de l'estimateur
clustering_metrics = [
metrics.homogeneity_score,
metrics.completeness_score,
metrics.v_measure_score,
metrics.adjusted_rand_score,
metrics.adjusted_mutual_info_score,
]
results += [m(labels, estimator[-1].labels_) for m in clustering_metrics]
## Le score silhouette nécessite l'ensemble de données complet
results += [
metrics.silhouette_score(
data,
estimator[-1].labels_,
metric="euclidean",
sample_size=300,
)
]
## Afficher les résultats
formatter_result = (
"{:9s}\t{:.3f}s\t{:.0f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}\t{:.3f}"
)
print(formatter_result.format(*results))
Exécuter le critère d'évaluation
Nous allons comparer trois approches pour initialiser K-Means :
- une initialisation utilisant
k-means++. Cette méthode est stochastique et nous exécuterons l'initialisation 4 fois ; - une initialisation aléatoire. Cette méthode est également stochastique et nous exécuterons l'initialisation 4 fois ;
- une initialisation basée sur une projection PCA. Nous utiliserons les composantes de la PCA pour initialiser K-Means. Cette méthode est déterministe et une seule initialisation suffit.
from sklearn.cluster import KMeans
from sklearn.decomposition import PCA
print(82 * "_")
print("init\t\ttime\tinertia\thomo\tcompl\tv-meas\tARI\tAMI\tsilhouette")
kmeans = KMeans(init="k-means++", n_clusters=n_digits, n_init=4, random_state=0)
bench_k_means(kmeans=kmeans, name="k-means++", data=data, labels=labels)
kmeans = KMeans(init="random", n_clusters=n_digits, n_init=4, random_state=0)
bench_k_means(kmeans=kmeans, name="random", data=data, labels=labels)
pca = PCA(n_components=n_digits).fit(data)
kmeans = KMeans(init=pca.components_, n_clusters=n_digits, n_init=1)
bench_k_means(kmeans=kmeans, name="PCA-based", data=data, labels=labels)
print(82 * "_")
Visualiser les résultats sur les données réduites par PCA
Nous utiliserons la PCA pour réduire l'ensemble de données à 2 dimensions et tracer les données et les clusters dans cet espace nouveau.
import matplotlib.pyplot as plt
reduced_data = PCA(n_components=2).fit_transform(data)
kmeans = KMeans(init="k-means++", n_clusters=n_digits, n_init=4)
kmeans.fit(reduced_data)
## Taille d'étape de la grille. Diminuer pour augmenter la qualité de la VQ.
h = 0.02 ## point dans la grille [x_min, x_max]x[y_min, y_max].
## Tracer la frontière de décision. Pour cela, nous allons attribuer une couleur à chaque
x_min, x_max = reduced_data[:, 0].min() - 1, reduced_data[:, 0].max() + 1
y_min, y_max = reduced_data[:, 1].min() - 1, reduced_data[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
## Obtenir les étiquettes pour chaque point de la grille. Utiliser le dernier modèle entraîné.
Z = kmeans.predict(np.c_[xx.ravel(), yy.ravel()])
## Mettre le résultat dans un graphique en couleur
Z = Z.reshape(xx.shape)
plt.figure(1)
plt.clf()
plt.imshow(
Z,
interpolation="nearest",
extent=(xx.min(), xx.max(), yy.min(), yy.max()),
cmap=plt.cm.Paired,
aspect="auto",
origin="lower",
)
plt.plot(reduced_data[:, 0], reduced_data[:, 1], "k.", markersize=2)
## Tracer les centroïdes comme une croix blanche
centroids = kmeans.cluster_centers_
plt.scatter(
centroids[:, 0],
centroids[:, 1],
marker="x",
s=169,
linewidths=3,
color="w",
zorder=10,
)
plt.title(
"K-means clustering on the digits dataset (PCA-reduced data)\n"
"Centroids are marked with white cross"
)
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.xticks(())
plt.yticks(())
plt.show()
Sommaire
Dans ce laboratoire, nous avons exploré l'algorithme de clustering K-Means et l'avons appliqué à l'ensemble de données de chiffres manuscrits. Nous avons comparé différentes méthodes d'initialisation et évalué les performances du clustering à l'aide de diverses métriques. Nous avons également visualisé les résultats dans un espace bidimensionnel à l'aide de la PCA.