K-means:効率的な初期重心のセットを選択する良い方法は何ですか?


17

重心のランダムな初期化が使用される場合、K平均の異なる実行は異なる合計SSEを生成します。そして、それはアルゴリズムのパフォーマンスにおいて重要です。この問題を解決するための効果的なアプローチは何ですか?最近のアプローチは高く評価されています。

回答:


12

より一貫した結果が得られるアプローチはK-means ++です。このアプローチは、おそらく単純なランダムな割り当てよりも初期の重心位置のより良い選択があることを認めています。具体的には、K-meansは、空間内で重心がまとまらないような方法で重心がシードされると、パフォーマンスが向上する傾向があります。

要するに、方法は次のとおりです。

  1. 初期重心としてランダムにデータポイントの1つを選択します。
  2. 計算します。これは、初期重心と他のすべてのデータポイント間の距離です。xD(x)x
  3. 比例する確率で、残りのデータポイントから次の重心を選択しますD(x)2
  4. すべての重心が割り当てられるまで繰り返します。

注:重心が追加されると、を更新する必要があります。データ点と最も近い重心の間の距離に設定する必要があります。D(x)

また、この方法を提案し、全体的な期待されるパフォーマンスを説明するこのペーパーを読むこともできます。


5

私はあなたの質問を誤解しているかもしれませんが、通常、k-meansは設定したクラスターの数(つまりk)に応じてランダムに重心を選択します。kの数を選択することは主観的な運動になる傾向があります。始めるのに適した場所は、ここにあるエルボ/スクリードプロットです。

http://en.wikipedia.org/wiki/Determining_the_number_of_clusters_in_a_data_set#The_Elbow_Method


私は質問がドキュメントページ上の{「k平均++」、「ランダム」やndarray}ある重心の初期化、についてだと思うscikit-learn.org/stable/modules/generated/...
イタチ

4

この問題への通常のアプローチは、重心の異なるランダムな初期化を使用してK-meansアルゴリズムを数回再実行し、最適なソリューションを維持することです。そのためには、トレーニングデータの結果を評価するか、相互検証を行います。

重心を初期化する方法は他にもたくさんありますが、すべての問題に対して最高の性能を発揮するものはありません。これらのアプローチを、特定の問題に対するランダムな初期化とともに評価できます。


0

エルボー/スクリードのプロットに同意します。ランダムシードよりも直感的に賢明だと感じました。これを試すためのサンプルコードを次に示します。

Ks=30
mean_acc=np.zeros((Ks-1))
std_acc=np.zeros((Ks-1))
ConfustionMx=[];
for n in range(1,Ks):    
    #Train Model and Predict  
    kNN_model = KNeighborsClassifier(n_neighbors=n).fit(X_train,y_train)
    yhat = kNN_model.predict(X_test)
    mean_acc[n-1]=np.mean(yhat==y_test);
    std_acc[n-1]=np.std(yhat==y_test)/np.sqrt(yhat.shape[0])

plt.plot(range(1,Ks),mean_acc,'g')
plt.fill_between(range(1,Ks),mean_acc - 1 * std_acc,mean_acc + 1 * std_acc, alpha=0.10)
plt.legend(('Accuracy ', '+/- 3xstd'))
plt.ylabel('Accuracy ')
plt.xlabel('Number of Nabors (K)')
plt.tight_layout()
plt.show()

print( "The best accuracy was with", mean_acc.max(), "with k=", mean_acc.argmax()+1)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.