web-dev-qa-db-ja.com

ValueError:ラベルの数は1です。silhouette_scoreを使用する場合、有効な値は2〜n_samples-1(両端を含む)です。

作成するクラスターの最適な数を見つけてsilhouette scoreを計算しようとしていますが、次のエラーが表示されます。

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

その理由がわかりません。これは、silhouette scoreをクラスタ化して計算するために使用しているコードです。

クラスター化するテキストを含むcsvを読み取り、nクラスター値に対してK-Meansを実行します。このエラーが発生する理由は何ですか?

  #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

エラーは、異なる数のクラスターnのループがあるために生成されます。最初の反復の間、_n_clusters_は_1_であり、これによりall(km.labels_ == 0)True。になります。

言い換えると、ラベル0のクラスターは1つしかありません(したがって、np.unique(km.labels_)array([0], dtype=int32)を出力します)。


_silhouette_score_ 複数のクラスターラベルが必要。これによりエラーが発生します。エラーメッセージは明確です。


例:

_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)
_

3つの異なるクラスター/クラスターラベルがあります。

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

関数は正常に動作します。


今、エラーを引き起こしましょう:

_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

ドキュメントから、

シルエット係数は、ラベルの数が2 <= n_labels <= n_samples-1の場合にのみ定義されることに注意してください

したがって、この問題を解決する1つの方法は、for k in range(1,15)を使用する代わりに、k = 2から反復を開始することです。つまり、for k in range(2,15)です。それは私にとってはうまくいきます。

2
Yuan