Main Content

k-means クラスタリング

このトピックでは k-means クラスタリングを紹介し、Statistics and Machine Learning Toolbox™ の関数 kmeans を使用してデータ セットに最適なクラスタリング ソリューションを見つける例について説明します。

k-means クラスタリングの紹介

k-means クラスタリングは、分割を行うための方法です。関数 kmeans は、データを互いに排他的な k 個のクラスターに分割し、各観測値が割り当てられたクラスターのインデックスを返します。kmeans は、データ内の各観測値を、空間内のある位置をもつオブジェクトとして処理します。この関数は、各クラスター内のオブジェクトができるだけ互いに近くにあり、他のクラスターのオブジェクトからはできるだけ遠くにあるような分割を探します。距離計量を選択して、データの属性に基づいて kmeans と一緒に使用することができます。多くのクラスタリング手法と同じように、k-means クラスタリングでもクラスタリングを行う前にクラスター数 k を指定しなければなりません。

階層クラスタリングと異なり、k-means クラスタリングは、データ内の観測値の各ペア間の非類似度ではなく、実際の観測値で動作します。また、k-means クラスタリングでは、クラスターの多重レベルの階層ではなく、単一レベルのクラスターを作成します。そのため、k-means クラスタリングは、大量のデータを処理する場合に階層クラスタリングより適していることが多くあります。

k-means の分割内の各クラスターは、メンバー オブジェクトと重心 (または中心) で構成されます。各クラスター内で、kmeans は、重心とクラスターのすべてのメンバー オブジェクトの間の合計距離を最小化します。kmeans は、サポートされている距離計量の重心クラスターを異なる方法で計算します。詳細については、'Distance'を参照してください。

kmeans で使用可能な名前と値のペアの引数を使用して、最小化の詳細を制御できます。たとえば、クラスターの重心の初期値や、アルゴリズムの最大反復回数を指定できます。既定では、kmeans はクラスターの重心を初期化するために k-means++ アルゴリズムを使用し、距離を決定するために 2 乗ユークリッド距離計量を使用します。

k-means クラスタリングを実行するときは、次のベストプラクティスに従ってください。

  • k のさまざまな値について k-means クラスタリングの解を比較して、自分のデータにとって最適なクラスター数を決定する。

  • シルエット プロットとシルエット値を調べることでクラスタリングの解を評価する。また、関数 evalclusters を使用して、ギャップ値、シルエット値、Davies-Bouldin インデックス値、Calinski-Harabasz インデックス値などの基準に基づいてクラスタリングの解を評価することもできます。

  • 無作為に選択したさまざまな重心からのクラスタリングを複製し、すべての複製の中で距離の総和が最小である解を返す。

k-means クラスタリングを対話的に実行するには、[データのクラスタリング] ライブ エディター タスクを使用します。

k-means クラスタリングの解の比較

この例では、4 次元のデータ セットに対する k-means クラスタリングについて確認します。この例では、シルエット プロットやシルエット値を使用することでデータ セットに適切なクラスター数を決定して、さまざまな k-means クラスタリングの解の結果を分析する方法を示します。また、名前と値のペアの引数 'Replicates' を使用して、可能性のある解を指定された数だけテストして、距離の総和が最小である解を返す方法も示します。

データ セットの読み込み

kmeansdata データ セットを読み込みます。

rng('default')  % For reproducibility
load('kmeansdata.mat')
size(X)
ans = 1×2

   560     4

データ セットは 4 次元であり、可視化は容易ではありません。ただし、kmeans を使用してデータ中にグループ構造があるかどうかを調べることができます。

クラスターの作成と間隔の確認

k-means クラスタリングを使用して、データ セットを 3 つのクラスターに分割します。尺度として市街地距離を指定し、既定の k-means++ アルゴリズムをクラスター中心の初期化に使用します。'Display' 名前と値のペアの引数を使用して、その解に最終的な距離の合計を表示します。

[idx3,C,sumdist3] = kmeans(X,3,'Distance','cityblock', ...
    'Display','final');
Replicate 1, 7 iterations, total sum of distances = 2459.98.
Best total sum of distances = 2459.98

idx3 には、X の各行に対するクラスター割り当てを示すクラスター インデックスが含まれています。生成されたクラスターが十分に分離されているかどうかを確認するには、シルエット プロットを作成できます。

シルエット プロットは、1 個のクラスター中の各点が近隣のクラスター中の点にどれくらい接近しているかについて基準を表示します。この尺度の範囲は、(隣接するクラスターから非常に遠い点を示す) 1 から、(いずれかのクラスター内に含まれているかどうかがあいまいな点を示す) 0 を通り、(適切でないクラスターに割り当てられた確率が高い点を示す) –1 までです。silhouetteは、その 1 番目の出力でこれらの値を返します。

idx3 からシルエット プロットを作成します。k-means クラスタリングが差の絶対値の総和に基づくことを指示するために、距離計量に対して 'cityblock' を指定します。

[silh3,h] = silhouette(X,idx3,'cityblock');
xlabel('Silhouette Value')
ylabel('Cluster')

Figure contains an axes object. The axes object with xlabel Silhouette Value, ylabel Cluster contains an object of type bar.

シルエット プロットは、2 番目のクラスターの大部分の点が (0.6 よりも大きい) 大きなシルエット値をもっており、そのクラスターが近隣のクラスターからある程度分離されていることを示しています。一方、3 番目のクラスターにはシルエット値の低い点が多く含まれており、また 1 番目と 3 番目のクラスターには負の値をもつ点がいくつか含まれていることから、これら 2 つのクラスターが十分には分離されていないことがわかります。

kmeans がデータのより適切なグループ化を見つけることができるかどうか確認するには、クラスターの数を 4 に増やします。'Display' 名前と値のペアの引数を使用して、各反復に関する情報を表示します。

idx4 = kmeans(X,4,'Distance','cityblock','Display','iter');
  iter	 phase	     num	         sum
     1	     1	     560	     1792.72
     2	     1	       6	      1771.1
Best total sum of distances = 1771.1

4 つのクラスターのシルエット プロットを作成します。

[silh4,h] = silhouette(X,idx4,'cityblock');
xlabel('Silhouette Value')
ylabel('Cluster')

Figure contains an axes object. The axes object with xlabel Silhouette Value, ylabel Cluster contains an object of type bar.

シルエット プロットは、これら 4 つのクラスターが、前の解の 3 つのクラスターよりも、より適切に分離されていることを示します。2 つの場合については、平均のシルエット値を計算することで、2 つの解をより定量的に比較できます。

平均のシルエット値を計算します。

cluster3 = mean(silh3)
cluster3 = 
0.5352
cluster4 = mean(silh4)
cluster4 = 
0.6400

4 つのクラスターの平均シルエット値は、3 つのクラスターの平均値よりも高くなります。こうした値は、シルエット プロットに示された結果を立証しています。

最後に、データ内で 5 つのクラスターを見つけます。シルエット プロットを作成し、5 つのクラスターの平均シルエット値を計算します。

idx5 = kmeans(X,5,'Distance','cityblock','Display','final');
Replicate 1, 7 iterations, total sum of distances = 1647.26.
Best total sum of distances = 1647.26
[silh5,h] = silhouette(X,idx5,'cityblock');
xlabel('Silhouette Value')
ylabel('Cluster')

Figure contains an axes object. The axes object with xlabel Silhouette Value, ylabel Cluster contains an object of type bar.

mean(silh5)
ans = 
0.5721

このシルエット プロットは、2 つのクラスターにはほとんど低いシルエット値をもつ点が含まれ、5 番目のクラスターには負の値をもつ点がいくつか含まれているため、5 がおそらくクラスターの正しい数ではないことを示しています。また、5 つのクラスターの平均シルエット値は 4 つのクラスターの値よりも低くなります。どれだけ多くのクラスターがデータ内にあるかについて分からない場合、ある範囲内の複数の k の値 (クラスターの数) を使用して実験することをお勧めします。

クラスターの数が増加すると、距離の合計が減少することに注意してください。たとえば、クラスターの数が 3 から 4、そして 5 に増加すると、距離の合計は 2459.98 から 1771.1、そして 1647.26 に減少します。そのため、距離の合計は最適なクラスター数を決定するのに役立ちません。

ローカルな最小値の回避

既定の設定では、関数 kmeans は無作為に選択された初期の重心位置の集合を使用して処理を開始します。kmeans アルゴリズムは、ローカルな (グローバルではない) 最小値である解に収束する可能性があります。つまり、kmeans は、任意の 1 点を異なるクラスターに移動すると距離の総和が大きくなるようにデータを分割する可能性があります。ただし、他の多くのタイプの数値的最小化と同様に、kmeans によって到達する解は、開始点に依存する場合があります。したがって、そのデータについて、距離の総和がより小さい他の解 (ローカルな最小値) が存在する可能性があります。'Replicates' 名前と値のペアの引数を使用して異なる解をテストできます。複数の複製を指定すると、kmeans は、無作為に選択した重心から始まるクラスタリング プロセスを各複製について繰り返し、すべての複製の中で距離の総和が最小である解を返します。

データ内の 4 つのクラスターを見つけて、クラスタリングを 5 回複製します。また、尺度として市街地距離を指定し、'Display' 名前と値のペアの引数を使用して、それぞれの解に最終的な距離の合計を表示します。

[idx4,cent4,sumdist] = kmeans(X,4,'Distance','cityblock', ...
    'Display','final','Replicates',5);               
Replicate 1, 2 iterations, total sum of distances = 1771.1.
Replicate 2, 3 iterations, total sum of distances = 1771.1.
Replicate 3, 3 iterations, total sum of distances = 1771.1.
Replicate 4, 6 iterations, total sum of distances = 2300.23.
Replicate 5, 2 iterations, total sum of distances = 1771.1.
Best total sum of distances = 1771.1

複製 4 で、kmeans はローカルな最小値を見つけます。複製はそれぞれ無作為に選択した異なる重心の初期値から始まっているため、kmeans は 2 つ以上のローカルな最小値を見つける場合があります。しかし、kmeans によって返される最終的な解は、すべての複製のうちで距離の総和が最小値となる解になります。

kmeans によって返される最終的な解に対して、点と重心間の距離のクラスター内合計の総和を求めます。

sum(sumdist)
ans = 
1.7711e+03

参考

| |

関連するトピック