실루엣 계수
IT 위키
더 많은 작업
- Silhouette Coefficient; 실루엣 지수, Silhouette Score
- 각 관측값이 자기 군집에 얼마나 잘 붙어 있고 이웃 군집과는 얼마나 떨어져 있는지를 -1~1 사이 값으로 나타내는 군집 분석 평가 지표
Rousseeuw(1987)가 군집 결과를 해석하고 검증하는 그래픽 도구로 제안했다. 정답 레이블 없이 군집 내부의 응집도와 군집 간 분리도만으로 계산하는 내부 평가 지표이며, K-Means, 계층적 군집 분석 등 어떤 군집 방법의 결과에도 쓸 수 있다. 전체 평균 실루엣이 큰 군집 수를 고르는 데 자주 쓴다.
관측값 i가 군집 A에 속할 때,
- a(i): i와 같은 군집 A의 다른 모든 점 사이 평균 거리(응집도). 작을수록 좋다.
- d(i, C): i와 다른 군집 C의 모든 점 사이 평균 거리.
- b(i): 가장 가까운 이웃 군집까지의 평균 거리 . 클수록 좋다.
- 군집에 점이 i 하나뿐이면 s(i) = 0으로 둔다.
- 전체 실루엣 계수는 모든 관측값 s(i)의 평균이다. 군집 수 k가 2 이상 n − 1 이하일 때만 정의된다.
- 거리는 보통 유클리드 거리를 쓰지만 다른 비유사도도 쓸 수 있다. 변수 단위가 다르면 미리 척도를 맞춘다.
| s(i) 값 | 뜻 |
|---|---|
| 1에 가까움 | a(i)가 b(i)보다 훨씬 작다. 자기 군집에 잘 묶여 있고 이웃 군집과 멀다 |
| 0 근처 | a(i) ≈ b(i). 두 군집의 경계에 놓여 있다 |
| 음수 | a(i) > b(i). 이웃 군집이 더 가까우므로 잘못 배정되었을 가능성이 크다 |
- 실루엣 그림(silhouette plot)은 군집별로 s(i)를 정렬해 막대로 그린 것이다. 막대가 짧거나 음수가 많은 군집, 다른 군집보다 크기가 유난히 작거나 큰 군집을 찾는 데 쓴다.
- 평균 실루엣은 볼록하고 크기가 비슷한 군집에 유리하다. 길쭉하거나 밀도가 다른 군집(DBSCAN이 찾는 모양 등)에서는 실제 구조보다 낮게 나올 수 있다.
| 지표 | 계산 | 좋은 값 | 특징 |
|---|---|---|---|
| 엘보 방법(SSE) | 군집 내 제곱합 | 감소가 꺾이는 지점 | k가 늘면 항상 줄어든다. 꺾이는 점이 뚜렷하지 않으면 판단이 주관적이다 |
| 실루엣 계수 | 위 s(i)의 평균 | 클수록(최대 1) | 관측값 단위 해석이 가능하다. 모든 점 쌍의 거리가 필요해 계산량이 n2에 비례한다 |
| Calinski-Harabasz | (군집 간 분산 대 군집 내 분산의 비) | 클수록 | 계산이 빠르다. 볼록한 군집에 유리하다 |
| Davies-Bouldin | 각 군집과 가장 비슷한 군집 사이의 (군집 내 산포 합 / 중심 간 거리) 평균 | 작을수록(최소 0) | 중심 기반이라 계산이 빠르다. 유클리드 거리 전제 |
- 정답 레이블이 있으면 조정 랜드 지수(ARI) 같은 외부 지표를 쓸 수 있지만, 실루엣·CH·DB는 레이블 없이 쓰는 내부 지표이다.
- 지표마다 고르는 k가 다를 수 있으므로 여러 지표와 업무적 해석을 함께 본다.
library(cluster)
X <- iris[, 1:4]
d <- dist(X) # 유클리드 거리
for (k in 2:6) {
km <- kmeans(X, centers = k, nstart = 10)
sil <- silhouette(km$cluster, d)
cat(k, summary(sil)$avg.width, "\n") # 평균 실루엣
}
pm <- pam(X, k = 3) # PAM 결과는 바로 실루엣 계산 가능
plot(silhouette(pm)) # 실루엣 그림
import numpy as np
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.metrics import (silhouette_score, silhouette_samples,
calinski_harabasz_score, davies_bouldin_score)
X = load_iris().data
print(" k SSE(inertia) silhouette CH DB")
for k in range(2, 7):
km = KMeans(n_clusters=k, n_init=10, random_state=0).fit(X)
lab = km.labels_
print(f"{k:2d} {km.inertia_:12.2f} {silhouette_score(X, lab):10.4f}"
f" {calinski_harabasz_score(X, lab):8.2f} {davies_bouldin_score(X, lab):7.4f}")
# k=3일 때 군집별 평균 실루엣과 음수인 관측값 수
lab3 = KMeans(n_clusters=3, n_init=10, random_state=0).fit_predict(X)
s = silhouette_samples(X, lab3)
for c in range(3):
print(f"군집 {c}: n={np.sum(lab3 == c)}, 평균 s={s[lab3 == c].mean():.4f}, 음수={np.sum(s[lab3 == c] < 0)}")
실행 결과:
k SSE(inertia) silhouette CH DB
2 152.35 0.6810 513.92 0.4043
3 78.85 0.5528 561.63 0.6620
4 57.23 0.4981 530.77 0.7803
5 46.45 0.4887 495.54 0.8060
6 39.04 0.3648 473.85 0.9142
군집 0: n=62, 평균 s=0.4173, 음수=0
군집 1: n=50, 평균 s=0.7981, 음수=0
군집 2: n=38, 평균 s=0.4511, 음수=0
- 평균 실루엣과 Davies-Bouldin은 k = 2를, Calinski-Harabasz는 k = 3을 가장 좋게 본다. SSE는 k = 2→3에서 크게 줄고(152.35 → 78.85) 그 뒤로 완만해져 엘보가 k = 3 근처에 있다.
- 붓꽃 자료의 실제 품종은 3개지만 versicolor와 virginica가 서로 겹쳐 있어, 거리만 보면 setosa와 나머지의 두 덩어리로 나누는 것이 가장 깔끔하다. 그래서 실루엣이 k = 2에서 가장 크다.
- k = 3에서 50개짜리 군집(setosa)은 평균 실루엣이 0.80으로 매우 잘 분리되고, 나머지 두 군집은 0.42~0.45로 경계가 가깝다. 음수 값은 없어 명백히 잘못 배정된 점은 없다.
- 이처럼 지표마다 결론이 다를 수 있으므로, 실기에서는 여러 지표의 결과와 군집의 업무적 의미를 함께 근거로 군집 수를 정해 서술한다.
- s(i) = (b(i) − a(i)) / max(a(i), b(i))에서 a(i)는 같은 군집 내 평균 거리, b(i)는 가장 가까운 다른 군집까지의 평균 거리이다.
- 실루엣은 -1~1 범위이고 1에 가까울수록 잘 군집된 것, 0 근처는 경계, 음수는 잘못 배정된 것으로 해석한다.
- 평균 실루엣이 가장 큰 k를 고르는 방법과 엘보 방법(SSE)의 차이를 설명할 수 있어야 한다. SSE는 k가 늘면 항상 줄어든다.
- Calinski-Harabasz는 클수록, Davies-Bouldin은 작을수록 좋다는 방향을 구분한다.
- Rousseeuw, P. J. (1987). Silhouettes: A graphical aid to the interpretation and validation of cluster analysis. Journal of Computational and Applied Mathematics 20, 53-65
- Caliński, T.; Harabasz, J. (1974). A dendrite method for cluster analysis. Communications in Statistics 3(1), 1-27
- Davies, D. L.; Bouldin, D. W. (1979). A Cluster Separation Measure. IEEE TPAMI 1(2), 224-227
- CRAN - cluster reference manual (silhouette, pam)
- scikit-learn - silhouette_score
- scikit-learn - silhouette_samples
- scikit-learn User Guide - Clustering (clustering performance evaluation)