作成するクラスターの最適な数を見つけて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)
エラーは、異なる数のクラスター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)
_
ドキュメントから、
シルエット係数は、ラベルの数が2 <= n_labels <= n_samples-1の場合にのみ定義されることに注意してください
したがって、この問題を解決する1つの方法は、for k in range(1,15)
を使用する代わりに、k = 2から反復を開始することです。つまり、for k in range(2,15)
です。それは私にとってはうまくいきます。