Python/Sklearn

[Sklearn] K-means 클러스터링 (K-평균 알고리즘) 파이썬 구현 + 시각화, Elbow Method

jimmy_AI 2021. 12. 6. 15:21
반응형

이번 글에서는 비지도 학습의 대표적 알고리즘인 K-means Clustering을

파이썬 사이킷런에서 구현해보는 예제를 다루어보겠습니다.

 

클러스터링 데이터 불러오기

먼저, 데이터를 불러오도록 하겠습니다. 

 

이번 글에서는 kaggle의 Mall Customers Clustering Analysis 데이터 셋을 사용했습니다.

데이터프레임의 생김새는 아래와 같습니다.

저희는 이 중에서 Annual Income 정보와 Spending Score 정보 두 가지만을

이용하여 고객들을 클러스터링 해보도록 하겠습니다.

 

K-평균 군집화 알고리즘 전처리

먼저, 필요한 column만 골라낸 뒤에

k-means 클러스터링에 필수적인 정규화를 진행해보도록 하겠습니다.

여기서는 각 column의 최소값을 0, 최대값을 1에 매핑한 MinMaxScaler

를 사용하였습니다. (다른 스케일러도 상관 없습니다.)

from sklearn.preprocessing import MinMaxScaler

# 두 가지 feature를 대상
data = df[['Annual Income (k$)', 'Spending Score (1-100)']]

# 정규화 진행
scaler = MinMaxScaler()
data_scale = scaler.fit_transform(data)

 

파이썬 사이킷런 K-means 클러스터링 알고리즘 학습

이제, 파이썬 사이킷런으로 k-means 알고리즘을 학습시켜보도록 하겠습니다.

알고리즘 종류, 최대 iteration 횟수 등을 지정할 수 있는 기능도 Kmeans에서 지원하지만,

 

여기서는 몇 개의 그룹으로 군집화할지를 고르는 n_cluster(k 지정) 인자와,

 

K-평균 군집화는 초기 그룹 설정마다 최종 결과가 달라질 수 있어,

실행 시 마다 결과를 같게 만드는 random_state 인자만을 설정하고 학습시켜보겠습니다.

from sklearn.cluster import KMeans

k = 3

# 그룹 수, random_state 설정
model = KMeans(n_clusters = k, random_state = 10)

# 정규화된 데이터에 학습
model.fit(data_scale)

# 클러스터링 결과 각 데이터가 몇 번째 그룹에 속하는지 저장
df['cluster'] = model.fit_predict(data_scale)

 

파이썬 K-means 군집화 결과 시각화

이제 matplotlib 라이브러리를 통하여 군집화 결과를 확인해보도록 하겠습니다.

실제 데이터 분포와 비교해보며, 군집화가 언제 잘 되었는지 확인해보세요.

여기서는 k = 3, 4, 5, 10 인 경우들을 예시로 보여드리겠습니다.

반응형
import matplotlib.pyplot as plt

plt.figure(figsize = (8, 8))

for i in range(k):
    plt.scatter(df.loc[df['cluster'] == i, 'Annual Income (k$)'], df.loc[df['cluster'] == i, 'Spending Score (1-100)'], 
                label = 'cluster ' + str(i))

plt.legend()
plt.title('K = %d results'%k , size = 15)
plt.xlabel('Annual Income', size = 12)
plt.ylabel('Spending Score', size = 12)
plt.show()

데이터의 분포를 고려하였을 때, k = 5인 경우가 가장 클러스터링이

잘 된 경우라고 볼 수 있을 것 같습니다.

 

K-means 클러스터링 k 결정(Elbow Method)

위에서는 시각화 결과로 k = 5일 때, 가장 군집화가 깔끔하게 되었다 생각했는데,

더 객관적인 k 결정 방법인 Elbow Method를 구현해보겠습니다.

 

k를 결정하기 쉽게 도와주는 함수인

from yellowbrick.cluster import KElbowVisualizer

를 불러와서 실행하는 예제를 보여드리겠습니다.

from yellowbrick.cluster import KElbowVisualizer

model = KMeans()
visualizer = KElbowVisualizer(model, k=(1,10))
visualizer.fit(data_scale)

k = 1 ~ 10까지 테스트한 경우이고,

데이터는 위에서 사용했던 정규화된 data_scale 변수를 넣으시면 됩니다.

결과는 다음과 같이 나왔는데, 파란색이 각 데이터들의 군집 중심과의 평균 거리

초록색은 학습 시간을 나타낸다고 합니다.

검정색 점선의 위치를 보았을 떄, 여기서는 k = 4인 경우를 추천해주는 듯 합니다.

절대적인 정답이 있는 것은 아니니, 하나의 평가 지표로 활용하시면 좋을 듯 합니다.