본문 바로가기
Machine-Learning/Basic

[ML] 군집 평가 (Cluster Evaluation) - 실루엣 분석 (Silhouette Analysis)

by AteN 2022. 12. 8.

군집 평가 (Cluster Evaluation)

군집화는 분류와 유사해 보일 수 있으나 성격이 많이 다르다. 데이터 내에 숨어 있는 별도의 그룹을 찾아서 의미를 부여하거나 동일한 분류 값에 속하더라도 그 안에서 더 세분화된 군집화를 추구하거나 서로 다른 분류 값의 데이터도 더 넓은 군집화 레벨화 등의 영역을 가지고 있다.

그렇다면 군집화가 효율적으로 잘 됐는지 평가할 수 있는 지표에는 어떤 것이 있을까? 비지도 학습의 특성상 어더한 지표라도 정확하게 성능을 평가하기는 어렵다. 그럼에도 불구하고 군집화의 성능을 평하는 대표적인 방법으로 실루엣 분석을 이용한다 

 

실루엣 분석의 개요 

군집화 평가 방법으로 실루엣 분석 (silhouette analysis)이 있다. 실루엣 분석은 각 군집 간의 거리가 얼마나 효율적으로 분리되어 있는지를 나타낸다. 효율적으로 잘 분리 됐다는 것은 다른 군집과의 거리는 떨어져 있고 동일 군집끼리의 데이터는 서로 가깝게 잘 뭉쳐 있다는 의미이다. 군집화가 잘 될수록 개별 군집은 비슷한 정도의 여유 공간을 가지고 떨어져 있을 것이다. 

 

실루엣 분석은 실루엣 계수 (silhouette coefficient)를 기반으로 한다.  실루엣 계수는 개별 데이터가 가지는 군집화 지표이다. 

개별 데이터가 가지는 실루엣 계수는 해당 데이터가 같은 군집 내의 데이터가 얼마나 가깝게 군집화돼 있고, 다른 군집에 있는 데이터와는 얼마나 멀리 분리돼 잇는지를 나타내는 지표이다 

 

특정 데이터 포인트의 실루엣 계수 값은 해당 데이터 포인트와 같은 군집 내에 잇는 다른 데이터 포인트와의 거리를 평균한 값 a(i), 해당 데이터 포인트가 속하지 않는 군집 중 가장 가까운 군집과의 평군 거리 b(i)를 기반으로 계산된다. 

두 군집 간의 거리가 얼마나 덜어져 있는가의 값은 b(i) - a(i)이며, 이 값을 정규화하기 위해 MAX(a(i), b(i))  값으로 나눈다. 따라서 i번째 데이터 포인트의 실루엣 계수 값 s(i)는 다음과 같이 정의한다

 

$$ s(i) = \frac{(b(i) - a(i))}{(max(a(i), b(i)))} $$

 

실루엣 계수는 -1에서 1 사이의 값을 가지며, 1로 가까워 질수록 큰처의 군집과 더 멀리 떨어져 있다는 것이고 0에 가까울수록 근처의 군집과 가까워진다는 것이다. 음수 값은 아예 다른 군집에 데이터 포인트가 할당됐음을 뜻한다. 

 

좋은 군집화가 되려면 다음의 기준 조건 

- 전체 실루엣 계수의 평균값, 즉 사이킷런의 silhouette_score() 값은 0~1사이의 값을 가지며, 1에 가까울수록 좋다 

- 하지만 전체 실루엣 계수의 평균값과 더불어 개별 군집의 평균값의 편차가 크지 않아야 한다. 즉, 개별 군집의 실루엣 계수 평균값이 전체 실루엣 계수의 평균값에서 크게 벗어나지 않는 것이 중요하다. 만약 전체 실루엣 계수의 평균값은 높지만, 특정 군집의 실루엣 계수 평균값만 유난히 높고 다른 군집들의 실루엣 계수 평균값은 낮으면 좋은 군집화 조건이 아니다. 

 

불꽃 데이터 세트의 군집화 결과에 대한 실루엣 분석 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

from sklearn.preprocessing import scale
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score

%matplotlib inline

# iris 데이터
iris = load_iris()
feature_names = ['sepal_length','sepal_width','petal_length','petal_width']
irisDF = pd.DataFrame(data=iris.data, columns=feature_names)

# KMeans
kmeans = KMeans(n_clusters=3, init="k-means++", max_iter=300, random_state=0).fit(irisDF)

# 데이터 프레임에 cluster 추가
irisDF["cluster"] = kmeans.labels_

# 개별 데이터 실루엣 계수
score_samples = silhouette_samples(iris.data, iris_df.cluster)
print(f'silhouette_samples( ) return 값의 shape: {score_samples.shape}')

# 데이터 프레임에 실루엣 계수 추가
irisDF['silhouette_coeff'] = score_samples

# 모든 데이터의 평균 실루엣 계수
average_score = silhouette_score(iris.data, iris_df.cluster)
print(f'붓꽃 데이터셋 Silhouette Analysis Score: {average_score:.3f}')
irisDF.head(3)
silhouette_samples( ) return 값의 shape: (150,)
붓꽃 데이터셋 Silhouette Analysis Score: 0.553

평균 실루엣 계수 값이 약 0.553이다. 1번 군집의 경우 0.8 이상의 높은 실루엣 계수 값을 나타내고 있다. 1번 군집이 아닌 다른 군집의 경우 실루엣 계수 값이 평균보다 낮기 때문일 것이다. 군집별 평균 실루엣 계수 값을 알아보겠다. irisDF에서 군집 별로 silhouette_coeff 칼럼의 평균값을 구하면 된다. 

irisDF.groupby('cluster')['silhouette_coeff'].mean()
cluster
0    0.417320
1    0.798140
2    0.451105

1번 군집은 실루엣 계수 평균 값이 약 0.79 인데 반해, 0번 약 0.41, 2번 0.45로 상대적으로 평균값이 1번에 비해 낮다 

 

군집별 평균 실루엣 계수의 시각화를 통한 군집 개수 최적화 방법 

전체 데이터의 평균 실루엣 계수 값이 높다고 해서 반드시 최적의 군집 개수로 군집화가 잘 됐다고 볼 수는 없다. 특정 군집 내의 실루엣 계수 값만 너무 높고, 다른 군집은 내부 데이터끼리의 거리가 너무 떨어져 있어 실루엣 계수 값이 낮아져도 평균적으로 높은 값을 가질 수 있다. 개별 군집별로 적당히 분리된 거리를 유지하면서도 군집 내의 데이터가 서로 뭉쳐 있는 경우 K-평균의 적절한 군집 개수가 설정됐다고 판단할 수 있다 

 

군집 개수를 최적화하는 방법 

첫번째 경우, 주어진 데이터에 대해서 군집의 개수 2개를 정했을 때이다. 이때 평균 실루엣 계수, 즉 silhouette_score는 약 0.704로 매우 높게 나타났다. 하지만 이렇게 2개로 군집화하는 것이 최적화 방법일까? 

다음 그림에서 왼쪽 부분은 개별 군집에 속하는 데이터의 실루엣 계수를 2차원으로 나타낸 것이다. X축은 실루엣 계수 값이고, Y축은 개별 군집과 이에 속하는 데이터이다. 개별 군집은 Y축에 숫자 값으로 0, 1로 표시돼 있다. 이에 해당하는 데이터는 일일이 숫자 값으로 표시되지 않았지만, Y축 높이로 추축할 수 있다. 그리고 점선으로 표시된 선은 전체 평균 실루엣 계수 값을 나타낸다. 이로 판단해 볼 때 1번 군집의 모든 데이터는 평균 실루엣 계수 값이 이상이지만, 2번 군집의 경우는 평균보다 적은 데이터 값이 매우 많다. 

 

오늘쪽에 있는 그림으로 그 이유를 보통해서 설명할 수 있다. 1번 군집의 경우 0번 군집과 멀리 떨어져 있고, 내부데이터끼리도 잘 뭉쳐 있다. 하지만 0번 군집의 경우 내부데이터끼리 많이 떨어져 있는 모습니다. 

다음 그림은 군집의 개수가 3개일 경우이다. 

전체 데이터의 평균 실루엣 계수 값은 약 0.588이다. 1번, 2번 군집의 경우 평균보다 높은 실루엣 계수 값을 가지고 있지만, 0번의 경우 모두 평균보다 낮다. 오른쪽 그림을 보면 0번의 경우 내부 데이터 강의 거리도 멀지만, 2번 군집과도 가깝게 위치하고 있기 때문이다. 

다음으로 군집이 4개인 경우이다. 이때 평균 실루엣 계수 값은 약 0.65이다. 외쪽 그림에서 보듯이 개별 군집의 평균 실루엣 계수 값이 비교적 균일하게 위치하고 있다. 1번 군집의 경우 모든 데이터가 평균보다 높은 계수 값을 가지고 있으며, 0번, 2번의 경우는 절반 이상이 평균보다 높은 계수 값을, 3번 군집의 경우만 약 1/3정도가 평균보다 높은 계수 값을 가지고 있다. 군집이 2개인 경우보다는 평균 실루엣 계수 값이 작지만 4개인 경우가 가장 이상적인 군집화 개수로 판단할 수 있을 것이다. 

 

Reference 

- 파이썬 머신러닝 완벽 가이드 

- https://scikit-learn.org/stable/auto_examples/cluster/plot_kmeans_silhouette_analysis.html

 

 

 

'Machine-Learning > Basic' 카테고리의 다른 글

[ML] 차원 축소 (Dimension Reduction)  (0) 2023.01.11
[ML] 메타 러닝과 퓨샷 러닝  (0) 2022.12.17
[ML] GirdSearchCV  (0) 2022.11.30
[ML] k-최근접 이웃 (K-Nearest Neighbor)  (0) 2022.11.19
[ML] SVM(Support Vertor Machine)  (0) 2022.09.26

댓글