web-dev-qa-db-ja.com

Scikit Learn-K-平均-肘-基準

今日、私はK-meansについて何かを学ぼうとしています。私はアルゴリズムを理解しており、その仕組みを知っています。今、正しいkを探しています...正しいkを検出する方法として肘基準を見つけましたが、scikit Learnでそれを使用する方法がわかりませんか?! scikitでは、このように物事をクラスタリングしていることを学びます

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

したがって、n_clusters = 1 ... nに対してこれを数回行い、正しいkを取得するためにエラー率を監視する必要がありますか?これは愚かだと思うし、時間がかかるだろう!?

32
Linda

肘の基準は視覚的な方法です。堅牢な数学的定義はまだ見ていません。ただし、k-meansもかなり粗雑なヒューリスティックです。

そのため、k=1...kmaxでk-meansを実行してから、結果のSSQをplotして、「最適な」kを決定する必要があります。

k=2で始まり、二次基準(AIC/BIC)が改善されなくなるまで増加させるX-meansなどのk-meansの高度なバージョンが存在します。 k平均の二分法は、k = 2で始まり、k = kmaxまでクラスターを繰り返し分割するアプローチです。おそらく暫定SSQをそこから抽出できます。

いずれにせよ、k-meanが本当に良い実際のユースケースでは、事前に必要なkを知っているという印象があります。これらの場合、k-meansは実際には「クラスタリング」アルゴリズムではなく、 ベクトル量子化 アルゴリズムです。例えば。画像の色数をkに減らします。 (多くの場合、kを選択すると、たとえば32になります。これは、色深度が5ビットであり、ビット圧縮された方法で保存できるためです)。または例えばビジュアルワードバッグアプローチでは、語彙サイズを手動で選択します。一般的な値はk = 1000のようです。その場合、「クラスター」の品質についてはあまり気にしませんが、主なポイントは、画像を1000次元のスパースベクトルに縮小できることです。 900次元または1100次元の表示のパフォーマンスは実質的に異なりません。

実際のクラスタリングタスクの場合、つまり、結果のクラスターを手動で分析したい場合、人々は通常k-meansよりも高度な方法を使用します。 K-meansは、データを単純化する手法です。

23
Anony-Mousse

(あなたの場合のように)真のラベルが事前にわからない場合、K-Means clusteringは、エルボ基準またはシルエット係数のいずれかを使用して評価できます。

エルボ基準法:

エルボー法の背後にある考え方は、kの値の範囲(num_clusters、たとえばk = 1から10)に対して特定のデータセットでk平均クラスタリングを実行し、kの各値について平方誤差の合計を計算することです。 (SSE)。

その後、SSEの線グラフをプロットします。線グラフが腕のように見える場合-線グラフの下の赤い円(角度のような)、 "肘"アーム上の最適なk(クラスターの数)の値です。ここでは、SSEを最小化したいと思います。SSE kを増やすと、0に向かって減少する傾向があります(およびSSEは0です。これは、各データポイントが独自のクラスターであり、クラスターとクラスターの中心の間にエラーがないためです)。

したがって、目標は、SSEがまだ低いsmall value of kを選択することであり、通常、エルボはkを増やすことでリターンが減少し始める場所を表します。

アイリスデータセットを考えてみましょう。

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

上記のコードのプロット: enter image description here

プロットでわかるように、3は虹彩データセットに最適なクラスターの数(赤で囲まれています)です。これは実際に正しいです。



シルエット係数法:

sklearn documentation から、

シルエット係数スコアが高いほど、クラスターがより明確に定義されているモデルに関連しています。シルエット係数は各サンプルに対して定義され、2つのスコアで構成されています: `

a:サンプルと同じクラスの他のすべてのポイントとの間の平均距離。

b:サンプルと次に近いクラスター内の他のすべてのポイントとの間の平均距離。

単一サンプルのシルエット係数は、次のように与えられます。

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

kKMeansの最適値を見つけるには、KMeansのn_clustersの1..nをループし、各サンプルのシルエット係数を計算します。

シルエット係数が高いほど、オブジェクトは自身のクラスターとよく一致し、隣接するクラスターとはあまり一致していません。

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

出力-

N_clusters = 2の場合、シルエット係数は0.680813620271です
n_clusters = 3の場合、シルエット係数は0.552591944521です
n_clusters = 4の場合、シルエット係数は0.496992849949です
n_clusters = 5の場合、シルエット係数は0.488517550854です
n_clusters = 6の場合、シルエット係数は0.370380309351です
n_clusters = 7の場合、シルエット係数は0.356303270516です
n_clusters = 8の場合、シルエット係数は0.365164535737です
n_clusters = 9の場合、シルエット係数は0.346583642095です
n_clusters = 10の場合、シルエット係数は0.328266088778です

ご覧のとおり、n_clusters = 2は最高のシルエット係数を持っています。これは、2が最適なクラスター数であることを意味します。

しかし、ここに問題があります。

アイリスデータセットには3種の花がありますが、これはクラスターの最適数として2と矛盾しています。 n_clusters = 2が最高のシルエット係数を持っているにもかかわらず、n_clusters = 3を最適なクラスター数と見なします-

  1. アイリスデータセットには3つの種があります。 (最も重要)
  2. n_clusters = 2には、シルエット係数の2番目に高い値があります。

n_clusters = 3を選択するのが最適です。アイリスデータセットのクラスターの。

最適な番号を選択するクラスタのサイズは、データセットのタイプと解決しようとしている問題に依存します。ただし、ほとんどの場合、最高のSilhouette Coefficientを使用すると、最適な数のクラスターが生成されます。

それが役に立てば幸い!

55
Om Prakash