web-dev-qa-db-fra.com

Scikit Learn - K-Means - Elbow - critère

Aujourd'hui, j'essaie d'apprendre quelque chose sur K-means. J'ai compris l'algorithme et je sais comment il fonctionne. Maintenant je cherche le bon k ... J'ai trouvé le critère du coude comme méthode pour détecter le bon k mais je ne comprends pas comment l'utiliser avec scikit learn ?! Dans Scikit, j'applique les choses de cette façon

kmeans = KMeans(init='k-means++', n_clusters=n_clusters, n_init=10) 
kmeans.fit(data)

Alors dois-je faire cela plusieurs fois pour n_clusters = 1 ... n et regarder le taux d'erreur pour obtenir le bon k? pensez que ce serait stupide et prendrait beaucoup de temps?!

32
Linda

Le critère du coude est une méthode visuelle. Je n'en ai pas encore vu de définition mathématique solide. Mais k-means est aussi une heuristique assez grossière.

Alors oui, vous devrez exécuter k-means avec k=1...kmax, puis tracer le SSQ résultant et décider d'un k "optimal".

Il existe des versions avancées de k-means comme X-means qui commenceront par k=2 puis l'augmenter jusqu'à ce qu'un critère secondaire (AIC/BIC) ne s'améliore plus. La bissection des k-moyennes est une approche qui commence également par k = 2, puis divise à plusieurs reprises les grappes jusqu'à k = kmax. Vous pourriez probablement en extraire les SSQ provisoires.

Quoi qu'il en soit, j'ai l'impression que dans tous cas d'utilisation réels où k-mean est vraiment bon, vous connaissez en fait le k dont vous avez besoin au préalable. Dans ces cas, k-means n'est pas tellement un algorithme de "clustering", mais un algorithme quantification vectorielle . Par exemple. réduire le nombre de couleurs d'une image à k. (où souvent vous choisiriez k pour être par exemple 32, car c'est alors une profondeur de couleur de 5 bits et peut être stocké de manière un peu compressée). Ou par ex. dans les approches sac de mots visuels, où vous choisiriez la taille du vocabulaire manuellement. Une valeur populaire semble être k = 1000. Vous ne vous souciez alors pas vraiment de la qualité des "clusters", mais le point principal est de pouvoir réduire une image à un vecteur clairsemé de 1000 dimensions. Les performances d'une représentation dimensionnelle 900 ou 1100 ne seront pas sensiblement différentes.

Pour les tâches de clustering réelles, c'est-à-dire lorsque vous souhaitez analyser manuellement les clusters résultants , les gens utilisent généralement des méthodes plus avancées que k-means. K-means est plus une technique de simplification des données.

23
Anony-Mousse

Si la véritable étiquette n'est pas connue à l'avance (comme dans votre cas), alors K-Means clustering peut être évalué à l'aide du critère de coude ou du coefficient de silhouette.

Méthode du critère du coude:

L'idée derrière la méthode du coude est d'exécuter le clustering k-means sur un ensemble de données donné pour une plage de valeurs de k (num_clusters, par exemple k = 1 à 10), et pour chaque valeur de k, calculer la somme des erreurs quadratiques (SSE).

Après cela, tracez un graphique linéaire du SSE pour chaque valeur de k. Si le graphique linéaire ressemble à un bras - un cercle rouge dans le graphique linéaire inférieur (comme l'angle), le "coude" sur le bras est la valeur de k optimal (nombre de grappe). Ici, nous voulons minimiser SSE. SSE tend à diminuer vers 0 lorsque nous augmentons k (et SSE est 0 lorsque k est égal au nombre de points de données dans l'ensemble de données, car alors chaque point de données est son propre cluster, et il n'y a aucune erreur entre lui et le centre de son cluster).

L'objectif est donc de choisir un small value of k qui a encore une petite SSE, et le coude représente généralement où nous commençons à avoir des rendements décroissants en augmentant k.

Prenons les jeux de données iris,

import pandas as pd
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

iris = load_iris()
X = pd.DataFrame(iris.data, columns=iris['feature_names'])
#print(X)
data = X[['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)']]

sse = {}
for k in range(1, 10):
    kmeans = KMeans(n_clusters=k, max_iter=1000).fit(data)
    data["clusters"] = kmeans.labels_
    #print(data["clusters"])
    sse[k] = kmeans.inertia_ # Inertia: Sum of distances of samples to their closest cluster center
plt.figure()
plt.plot(list(sse.keys()), list(sse.values()))
plt.xlabel("Number of cluster")
plt.ylabel("SSE")
plt.show()

Tracer pour le code ci-dessus: enter image description here

Nous pouvons voir dans le graphique, 3 est le nombre optimal de clusters (encerclé en rouge) pour l'ensemble de données iris, ce qui est en effet correct.



Méthode du coefficient de silhouette:

De documentation sklearn ,

Un score de coefficient de silhouette plus élevé se rapporte à un modèle avec des clusters mieux définis. Le coefficient de silhouette est défini pour chaque échantillon et se compose de deux scores: `

a: La distance moyenne entre un échantillon et tous les autres points de la même classe.

b: la distance moyenne entre un échantillon et tous les autres points du groupe le plus proche suivant.

Le coefficient de silhouette est pour un seul échantillon est alors donné comme:

s=b-a/max(a,b)

Maintenant, pour trouver la valeur optimale de k pour KMeans, parcourez 1..n pour n_clusters dans KMeans et calculez le coefficient de silhouette pour chaque échantillon.

Un coefficient de silhouette plus élevé indique que l'objet est bien adapté à son propre cluster et mal adapté aux clusters voisins.

from sklearn.metrics import silhouette_score
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans

X = load_iris().data
y = load_iris().target

for n_cluster in range(2, 11):
    kmeans = KMeans(n_clusters=n_cluster).fit(X)
    label = kmeans.labels_
    sil_coeff = silhouette_score(X, label, metric='euclidean')
    print("For n_clusters={}, The Silhouette Coefficient is {}".format(n_cluster, sil_coeff))

Sortie -

Pour n_clusters = 2, le coefficient de silhouette est de 0,680813620271
Pour n_clusters = 3, le coefficient de silhouette est 0,552591944521
Pour n_clusters = 4, le coefficient de silhouette est de 0,496992849949
Pour n_clusters = 5, le coefficient de silhouette est de 0,4888517550854
Pour n_clusters = 6, le coefficient de silhouette est de 0,370380309351
Pour n_clusters = 7, le coefficient de silhouette est de 0,356303270516
Pour n_clusters = 8, le coefficient de silhouette est de 0,365164535737
Pour n_clusters = 9, le coefficient de silhouette est de 0,346583642095
Pour n_clusters = 10, le coefficient de silhouette est de 0,328266088778

Comme nous pouvons le voir, n_clusters = 2 a le coefficient de silhouette le plus élevé. Cela signifie que 2 devrait être le nombre optimal de cluster, non?

Mais voici le hic.

Le jeu de données Iris comprend 3 espèces de fleurs, ce qui contredit les 2 en tant que nombre optimal de grappes. Donc, malgré n_clusters = 2 ayant le coefficient de silhouette le plus élevé, nous considérerions n_clusters = 3 comme le nombre optimal de cluster en raison de -

  1. L'ensemble de données Iris comprend 3 espèces. (Le plus important)
  2. n_clusters = 2 a une 2e valeur de coefficient de silhouette la plus élevée.

Donc, choisir n_clusters = 3 est le no optimal. du cluster pour l'ensemble de données iris.

Choisir le n ° optimal. du cluster dépendra du type de jeux de données et du problème que nous essayons de résoudre. Mais la plupart des cas, la prise du coefficient de silhouette le plus élevé produira un nombre optimal de grappes.

J'espère que cela aide!

55
Om Prakash