クラスタリングの評価指標(シルエットスコア、ダビーズ・ボウルディン指数)
クラスタリングは、正解ラベルのないデータを似たもの同士のグループに分ける教師なし学習の手法です。ただし、クラスタリングでは「正解」があらかじめ用意されていないことが多いため、分類問題のように単純に正解率で評価することができません。
そこで、クラスタリングの結果を評価するために、いくつかの評価指標が使われます。代表的な指標として、シルエットスコアとダビーズ・ボウルディン指数があります。
この記事では、クラスタリングの評価指標であるシルエットスコアとダビーズ・ボウルディン指数について、それぞれの考え方、値の見方、Pythonでの実装方法を解説します。
クラスタリング評価指標の考え方を図で理解する

シルエットスコアとは?
シルエットスコア(Silhouette Score)は、各データ点が「自分のクラスタにどれだけ適切に属しているか」を評価する指標です。
この指標では、次の2つの観点からクラスタリングの良さを評価します。
- 同じクラスタ内のデータ点同士が近いか
- 他のクラスタとは十分に離れているか
つまり、シルエットスコアはクラスタ内のまとまりとクラスタ間の分離を同時に見る指標です。
シルエットスコアは、-1から1までの範囲を取ります。値が1に近いほど、クラスタリングの結果が良いと判断できます。
| 値の目安 | 意味 |
|---|---|
| 1に近い | 同じクラスタ内では近く、他のクラスタとはよく離れている |
| 0に近い | クラスタの境界付近にあり、どちらのクラスタに属するか曖昧 |
| 負の値 | 本来は別のクラスタに属した方がよい可能性がある |
シルエットスコアの計算方法
シルエットスコアでは、各データ点について次の値を計算します。
- a(i):データ点iと、同じクラスタ内の他の点との平均距離
- b(i):データ点iと、最も近い別クラスタ内の点との平均距離
シルエットスコアは次の式で計算されます。
score(i) = (b(i) - a(i)) / max(a(i), b(i))
a(i)が小さく、b(i)が大きいほど、そのデータ点は自分のクラスタにうまく分類されていると考えられます。
Pythonによるシルエットスコアの実装
以下のコードは、scikit-learnを使用してシルエットスコアを計算する例です。
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from sklearn.datasets import make_blobs
# サンプルデータの生成
X, _ = make_blobs(
n_samples=300,
centers=4,
cluster_std=0.60,
random_state=0
)
# K-meansクラスタリングの実行
kmeans = KMeans(
n_clusters=4,
random_state=0,
n_init=10
)
labels = kmeans.fit_predict(X)
# シルエットスコアの計算
silhouette_avg = silhouette_score(X, labels)
print(f'シルエットスコア: {silhouette_avg}')
この例では、make_blobs()でサンプルデータを作成し、KMeansでクラスタリングを行っています。その後、silhouette_score()関数を使って、クラスタリング結果を評価しています。
ダビーズ・ボウルディン指数とは?
ダビーズ・ボウルディン指数(Davies-Bouldin Index)は、クラスタ内のばらつきとクラスタ間の距離をもとに、クラスタリングの質を評価する指標です。
この指標では、次のようなクラスタリングを良い結果と考えます。
- 各クラスタの中のデータがよくまとまっている
- クラスタ同士が十分に離れている
シルエットスコアとは異なり、ダビーズ・ボウルディン指数は値が低いほど良いクラスタリングであることを示します。
| 値の目安 | 意味 |
|---|---|
| 低い値 | クラスタ内のばらつきが小さく、クラスタ同士がよく離れている |
| 高い値 | クラスタ内のばらつきが大きい、またはクラスタ同士が近い |
ダビーズ・ボウルディン指数の考え方
ダビーズ・ボウルディン指数では、各クラスタについて、他のクラスタとの「似てしまっている度合い」を計算します。
クラスタ内のばらつきが大きく、他のクラスタとの距離が近い場合、そのクラスタはうまく分離できていないと判断されます。
反対に、クラスタ内のばらつきが小さく、他のクラスタと十分に離れていれば、良いクラスタリングと評価されます。
Pythonによるダビーズ・ボウルディン指数の実装
scikit-learnでは、davies_bouldin_score()関数を使ってダビーズ・ボウルディン指数を計算できます。
from sklearn.cluster import KMeans
from sklearn.metrics import davies_bouldin_score
from sklearn.datasets import make_blobs
# サンプルデータの生成
X, _ = make_blobs(
n_samples=300,
centers=4,
cluster_std=0.60,
random_state=0
)
# K-meansクラスタリングの実行
kmeans = KMeans(
n_clusters=4,
random_state=0,
n_init=10
)
labels = kmeans.fit_predict(X)
# ダビーズ・ボウルディン指数の計算
db_score = davies_bouldin_score(X, labels)
print(f'ダビーズ・ボウルディン指数: {db_score}')
この例では、K-meansでクラスタリングを行った後、davies_bouldin_score()関数を使ってクラスタリング結果を評価しています。
シルエットスコアとダビーズ・ボウルディン指数の比較
シルエットスコアとダビーズ・ボウルディン指数は、どちらもクラスタリング結果を評価するための指標ですが、値の見方が異なります。
| 指標 | 値の範囲 | 良い値 | 評価の考え方 |
|---|---|---|---|
| シルエットスコア | -1〜1 | 1に近いほど良い | 同じクラスタ内の近さと、他クラスタとの離れ具合を見る |
| ダビーズ・ボウルディン指数 | 0以上 | 低いほど良い | クラスタ内のばらつきと、クラスタ間の分離度を見る |
シルエットスコアは直感的に理解しやすく、クラスタ数の比較にも使いやすい指標です。一方、ダビーズ・ボウルディン指数は、クラスタ内のばらつきとクラスタ同士の距離をもとに、クラスタ全体の分離状態を評価します。
評価指標を使うときの注意点
クラスタリングの評価指標は便利ですが、数値だけで機械的に判断するのは危険です。
指標だけで最適なクラスタ数が決まるとは限らない
シルエットスコアやダビーズ・ボウルディン指数を使うと、複数のクラスタ数を比較できます。しかし、数値上もっとも良い結果が、必ずしも業務や分析目的に合っているとは限りません。
たとえば、顧客を分類する場合、指標上は2クラスタが良くても、実務上は「初心者・中級者・上級者」のように3クラスタに分けた方が使いやすいこともあります。
データの前処理が結果に影響する
クラスタリングは距離をもとに分類することが多いため、特徴量のスケールが結果に大きく影響します。
たとえば、年齢と年収をそのまま使うと、値の大きい年収の影響が強く出る可能性があります。そのため、必要に応じて標準化や正規化を行うことが重要です。
可視化と組み合わせて確認する
評価指標は数値でクラスタリング結果を確認できる便利な方法ですが、可能であれば散布図などによる可視化も行うと、クラスタの分かれ方をより理解しやすくなります。
まとめ
シルエットスコアとダビーズ・ボウルディン指数は、クラスタリング結果を評価するための代表的な指標です。
- シルエットスコアは、1に近いほど良い
- ダビーズ・ボウルディン指数は、低いほど良い
- どちらもクラスタ内のまとまりとクラスタ間の分離を評価する
- 評価指標だけでなく、分析目的や可視化結果もあわせて判断する
- クラスタリングでは、データの前処理や特徴量の選び方も重要になる
クラスタリングの評価では、1つの指標だけに頼るのではなく、複数の指標や可視化結果を組み合わせて判断することが大切です。シルエットスコアとダビーズ・ボウルディン指数を使い分けることで、より妥当なクラスタリング結果を選びやすくなります。