web-dev-qa-db-fra.com

ValueError: le nombre d'étiquettes est 1. Les valeurs valides sont comprises entre 2 et n_samples - 1 (inclus) lors de l'utilisation de silhouette_score

J'essaie de calculer silhouette score car je trouve le nombre optimal de clusters à créer, mais j'obtiens une erreur qui dit:

ValueError: Number of labels is 1. Valid values are 2 to n_samples - 1 (inclusive)

Je n'arrive pas à comprendre la raison de cela. Voici le code que j'utilise pour regrouper et calculer silhouette score.

J'ai lu le csv qui contient le texte à regrouper et j'exécute K-Means sur les valeurs du cluster n. Quelle pourrait être la raison pour laquelle j'obtiens cette erreur?

  #Create cluster using K-Means
#Only creates graph
import matplotlib
#matplotlib.use('Agg')
import re
import os
import nltk, math, codecs
import csv
from nltk.corpus import stopwords
from gensim.models import Doc2Vec
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.metrics import silhouette_score

model_name = checkpoint_save_path
loaded_model = Doc2Vec.load(model_name)

#Load the test csv file
data = pd.read_csv(test_filename)
overview = data['overview'].astype('str').tolist()
overview = filter(bool, overview)
vectors = []

def split_words(text):
  return ''.join([x if x.isalnum() or x.isspace() else " " for x in text ]).split()

def preprocess_document(text):
  sp_words = split_words(text)
  return sp_words

for i, t in enumerate(overview):
  vectors.append(loaded_model.infer_vector(preprocess_document(t)))

sse = {}
silhouette = {}


for k in range(1,15):
  km = KMeans(n_clusters=k, max_iter=1000, verbose = 0).fit(vectors)
  sse[k] = km.inertia_
  #FOLLOWING LINE CAUSES ERROR
  silhouette[k] = silhouette_score(vectors, km.labels_, metric='euclidean')

best_cluster_size = 1
min_error = float("inf")

for cluster_size in sse:
    if sse[cluster_size] < min_error:
        min_error = sse[cluster_size]
        best_cluster_size = cluster_size

print(sse)
print("====")
print(silhouette)
10
Suhail Gupta

L'erreur est produite parce que vous avez une boucle pour un nombre différent de clusters n. Lors de la première itération, n_clusters Est 1 et cela conduit à all(km.labels_ == 0) à True. =

En d'autres termes, vous n'avez qu'un seul cluster avec l'étiquette (ainsi, np.unique(km.labels_) imprime array([0], dtype=int32)).


silhouette_scorenécessite plus de 1 étiquettes de cluster. Cela provoque l'erreur. Le message d'erreur est clair.


Exemple:

from sklearn import datasets
from sklearn.cluster import KMeans
import numpy as np

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

km = KMeans(n_clusters=3)
km.fit(X,y)

# check how many unique labels do you have
np.unique(km.labels_)
#array([0, 1, 2], dtype=int32)

Nous avons 3 clusters/labels de cluster différents.

silhouette_score(X, km.labels_, metric='euclidean')
0.38788915189699597

La fonction fonctionne bien.


Maintenant, causons l'erreur:

km2 = KMeans(n_clusters=1)
km2.fit(X,y)

silhouette_score(X, km2.labels_, metric='euclidean')
ValueError: Number of labels is 1. Valid values are 2 to n_samples - 1 (inclusive)
19
makis

De la documentation,

Notez que le coefficient de silhouette n'est défini que si le nombre d'étiquettes est 2 <= n_labels <= n_samples - 1

Donc, une façon de résoudre ce problème est au lieu d'utiliser for k in range(1,15), essayez de démarrer l'itération à partir de k = 2, qui est for k in range(2,15). Ça marche pour moi.

2
Yuan