본문 바로가기
머신러닝

[머신러닝] 클러스터링 평가지표 - 실루엣 계수(2)

by 하응 2021. 7. 21.

이전 포스팅에서 실루엣 계수를 구하는 방법과 평가지표로써의 장단점을 알아보았다. 

2021.06.15 - [머신러닝] - [머신러닝] 클러스터링 평가지표 - 실루엣 계수 (1)

 

[머신러닝] 클러스터링 평가지표 - 실루엣 계수 (1)

실루엣 계수(Silhouette Coefficient) : 각 데이터 포인트와 주위 데이터 포인트들과의 거리 계산을 통해 값을 구하며, 군집 안에 있는 데이터들은 잘 모여있는지, 군집끼리는 서로 잘 구분되는지 클러

studying-haeung.tistory.com


이 시간에는 Python 코드로 실루엣 계수를 시각화해보고, 그 의미에 대해서 알아볼 것이다. 


0. Yellowbrick 라이브러리   

  • 실루엣 계수 시각화를 위해 Yellowbrick이라는 python 라이브러리를 활용하였다. 
  • 실루엣 계수 시각화 부분은 Yellowbrick 사이트의 'Silhouette Visualizer' 부분을 참고하면 된다. 
  • 다른 라이브러리와 마찬가지로 가상환경에 아래 명령어로 설치하였다.
pip install yellowbrick​

Yellowbrick 웹사이트

 

Silhouette Visualizer 설명 부분

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

 

 

 

1. 데이터 준비 및 변수 정규화 

  • 샘플 데이터로 캐글의 iris 데이터셋을 사용하였다. 
  • iris 데이터셋의 target 값에 해당하는 'Species' 컬럼을 제거하였다. 
  • Min-Max Scaler로 4개 컬럼의 정규화를 수행하였다.
#라이브러리 불러오기
import pandas as pd 
import numpy as np

#데이터 스케일링, 모델링, 시각화 도구 라이브러리
from sklearn.preprocessing import MinMaxScaler
from sklearn.cluster import KMeans
from yellowbrick.cluster import SilhouetteVisualizer

#print 함수 없이 출력
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"

#데이터 업로드, 변수 정규화 
df = pd.read_csv('iris.csv').drop(['Id','Species'],axis=1)

#최소-최대 스케일러로 모든 변수 정규화 
scaler = MinMaxScaler()
scaled_df = pd.DataFrame(data = scaler.fit_transform(df), columns=df.columns)
scaled_df.shape
scaled_df.head(5)
정규화 후 5개의 행만 출력 (150개 행, 4개 컬럼)

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

반응형

 

2. KMeans 모델 생성 및 실루엣 계수 시각화 

  • k=2, k=4로 설정하여 KMeans 모델을 만들고 데이터 포인트들을 군집에 할당하고 실루엣 계수를 시각화한다. 

| k=2로 설정하고 KMeans 모델 생성 후 실루엣 계수 시각화 

#클러스터링 모델 생성
kmeans_2 = KMeans(n_clusters=2, random_state=111,init='random')
#visualizer 생성
visualizer_2 = SilhouetteVisualizer(kmeans_2, colors='yellowbrick')
#생성된 visualizer에 데이터 입력 
visualizer_2.fit(scaled_df)      
visualizer_2.show()
k=2일 때 KMeans 모델을 생성하고 실루엣 계수를 시각화한 모습

데이터 포인트 i의 실루엣 계수를 파란 실선으로, 실루엣 전체 평균 값을 빨간 점선으로 표현

앞선 포스팅에서 확인한 것처럼 실루엣 계수 값은 각 데이터 포인트마다 계산되며, 모든 실루엣 계수 값이 그래프에 표현되는 것을 확인할 수 있다. Y축은 클러스터 ID를, X축은 실루엣 계수를 의미한다. 또한 그래프 색으로 클러스터를 구분할 수 있으며, 빨간 점선은 실루엣 계수의 전체 평균 값을 의미한다.  

 

실루엣 계수의 전체 평균 값이 크고, 클러스터별 실루엣 계수 평균 값이 클수록 클러스터링이 잘 되었다고 판단할 수 있다. 그래프 상에서는 클러스터 내의 데이터 포인트가 1에 가까울수록, 값이 급격히 감소하지 않을수록 좋다. 

| k=2일 때 군집/전체 실루엣 계수 평균값 계산 

result_df = scaled_df.copy()

#클러스터ID 컬럼 생성 
result_df.loc[:,'clusterID'] = visualizer_2.predict(scaled_df)
#실루엣 계수 컬럼 생성
result_df.loc[:,'silhouette coefficient'] = visualizer_2.silhouette_samples_

result_df.shape
result_df.head(5)
기존 데이터프레임 scaled_df에 clusterID, silhouette coefficient 컬럼을 추가

 

우선 기존 데이터프레임에 클러스터 ID 컬럼과 실루엣 계수 값에 해당하는 컬럼을 추가해주고, 아래와 같이 평균값을 계산한다. 

print('전체 데이터의 실루엣 계수 평균')
result_df['silhouette coefficient'].mean()

print('\n군집별 실루엣 계수 평균')
result_df.groupby('clusterID')['silhouette coefficient'].mean().reset_index()
전체 데이터/군집별 실루엣 계수 평균 계산

 

평균값을 구해본 결과, 전체 데이터의 실루엣 계수 평균은 약 0.63이고, 클러스터 0은 0.57, 클러스터 1은 0.76인 것을 확인하였다.

 

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

 

 

이번에는 클러스터 개수를 4로 설정하고, 동일한 순서로 결과 값을 도출하였다. 

 

| k=4로 설정하고 KMeans 모델 생성 후 실루엣 계수 시각화 

#클러스터링 모델 생성
kmeans_4 = KMeans(n_clusters=4, random_state=111,init='random')
#visualizer 생성
visualizer_4 = SilhouetteVisualizer(kmeans_4, colors='yellowbrick')
#생성된 visualizer에 데이터 입력 
visualizer_4.fit(scaled_df)      
visualizer_4.show()
k=4일 때 KMeans 모델을 생성하고 실루엣 계수를 시각화한 모습

 

(좌) k=2 인 경우, (우) k=4인 경우

k가 2인 경우와 4인 경우를 비교해보면, 클러스터의 개수가 4일 때 실루엣 계수의 전체 평균 값이 더 작을 뿐만 아니라(빨간 점선 확인), 클러스터 3,2,0 과 클러스터 1의 실루엣 계수의 차이도 큰 것을 알 수 있다. 또한 클러스터 3,2,0 의 데이터 포인트들의 실루엣 계수 값은 가파르게 감소하는 것을 확인할 수 있다. 

 

| k=4일 때 군집/전체 실루엣 계수 평균값 계산 

result_df = scaled_df.copy()

#클러스터ID 컬럼 생성 
result_df.loc[:,'clusterID'] = visualizer_4.predict(scaled_df)
#실루엣 계수 컬럼 생성
result_df.loc[:,'silhouette coefficient'] = visualizer_4.silhouette_samples_

result_df.shape
result_df.head(5)
기존 데이터프레임 scaled_df에 clusterID, silhouette coefficient 컬럼을 추가

 

기존 데이터프레임에 클러스터 ID 컬럼과 실루엣 계수 값에 해당하는 컬럼을 추가해주고, 아래와 같이 평균값을 계산한다. 

print('전체 데이터의 실루엣 계수 평균')
result_df['silhouette coefficient'].mean()

print('\n군집별 실루엣 계수 평균')
result_df.groupby('clusterID')['silhouette coefficient'].mean().reset_index()
전체 데이터/군집별 실루엣 계수 평균 계산

 

클러스터 개수가 4인 경우에는 전체 데이터의 실루엣 계수 평균은 약 0.44이고, 클러스터 0은 0.30, 클러스터 1은 0.68, 클러스터 2는 0.32, 클러스터 3은 0.36이다. 

 

클러스터 개수가 2일 때보다, 전체 평균 값이 훨씬 작을 뿐만 아니라, 클러스터별 평균 값도 작고, 클러스터 간 편차도 크다는 것을 그래프와 수치로 확인하였으며, 이를 통해 클러스터 개수가 2일 때 KMeans 클러스터링이 더 잘 수행되었다고 판단 내릴 수 있다.

 

 


 

 

한 달동안 꾸물럭거린 글을 드디어 다 적었다. 앞으로는 조금 더 성실하게 올려보자아🏃‍♀️🏃‍♀️🏃‍♀️

반응형

댓글