본문 바로가기

ML with SckitLearn

실루엣 분석(Silhouette Analysis) : Clustering 적절성 분석

반응형

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

 

사이킷런은 실루엣 분석을 위한 메소드를 제공하며 좋은 군집화가 되려면 다음 기준 조건을 만족해야 합니다.

  • 전체 실루엣 계수의 평균값, 즉 사이킷런의 shihoutte_score()값은 0~1사이의 값을 가지며, 1에 가까울수록 좋습니다.
  • 하지만 전체 실루엣 계수의 평균값과 더불어 개별 군집의 평균값의 편차가 크지 않아야 합니다. 즉, 개별 군집의 실루엣 계수 평균값이 전체 실루엣 계수의 평균값에서 크게 벗어나지 않는 것이 중요합니다. 만약 전체 실루엣 계수의 평균값은 높지만, 특정 군집의 실루엣 계수 평균값만 유난히 높고 다른 군집들의 실루엣 계수 평균값은 낮으면 좋은 군집화 조건이 아닙니다.

 

1. 사이킷런의 실루엣 분석 메서드

  • silhouette_samples(X, labels, metric='euclidean', **kwds) : X feature 데이터 세트와 각 feature데이터 세트가 속한 군집 레이블 값인 labels데이터를 입력해주면 각 데이터 포인트의 실루엣 계수를 계산해 반환합니다.
  • silhouette_score(X, labels, metric='euclidean', sample_size=None, **kwds): 인자로 X feature데이터 세트와 각 feature 데이터 세트가 속한 레이블 값인 labels데이터를 입력해주면 전체 데이터의 실루엣 계수 값을 평균해 반환합니다. 즉 np.mean(silhouette_samples())입니다. 일반저으로 이 값이 높을수록 군집화가 어느 정도 잘 됐다고 판단할 수 있습니다. 하지만 무조건 이 값이 높다고 해서 군집화가 잘 됐다고 판단할 수는 없습니다.

 

2. Silhourtte Example

from sklearn.preprocessing import scale
from sklearn.datasets import load_iris
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

iris_data = load_iris()

irisDF = pd.DataFrame(data=iris_data.data, columns=['sepal_length','sepal_width','petal_length','petal_width'])
kmeans = KMeans(n_clusters=3, init='k-means++', max_iter=300, random_state=0)
kmeans.fit(irisDF)
irisDF['cluster'] = kmeans.labels_

score_samples = silhouette_samples(iris_data.data, irisDF['cluster'])
print(score_samples.shape)
print(score_samples)
irisDF['silhoutte_coeff'] = score_samples

average_score = silhouette_score(iris_data.data, irisDF['cluster'])
print(average_score)
print(irisDF.groupby('cluster')['silhoutte_coeff'].mean())

 

#print(average_score)
0.5528190123564091

#print(irisDF.groupby('cluster')['silhoutte_coeff'].mean())
cluster
0    0.451105
1    0.798140
2    0.417320
반응형