티스토리 뷰

이 글은 책 「파이썬 머신러닝 완벽가이드」를 바탕으로 작성되었습니다.

K-평균 (K-means)란?

- 주변 데이터까지의 거리의 평균 지점으로 군집 중심점을 이동시켜 군집화를 수행하는 알고리즘

 

작동방식

1. 임의의 군집 중심점(centroid)를 설정하고 해당 지점에 가까운 데이터 포인트들을 선택

2. 선택된 데이터 포인트들의 거리 중심점으로 이동하고, 이동된 지점에서 가까운 데이터 포인트들을 선택, 다시 군집 중심점을 거리 평균 지점으로 이동

3. 더 이상 군집 중심점의 이동이 없으면 반복을 멈추고 해당 군집 중심점에 가까운 데이터 포인트들을 하나의 군집으로 라벨링

 

사이킷런 클래스 KMeans

class sklearn.cluster.KMeans(n_clusters=8, *, init='k-means++', n_init=10, max_iter=300, tol=0.0001, precompute_distances='deprecated', verbose=0, random_state=None, copy_x=True, n_jobs='deprecated', algorithm='auto')

주요 인자

- n_cluster : 군집 중심점 개수 = 군집의 개수

- init : 초기 군집 중심점을 설정 방식, default는 빠르게 수렴에 도달하는 'k-means++' (이 외에 ‘random’)

- max_iter : 반복 횟수

 

iris 데이터 셋에 KMeans 적용하기

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

from sklearn.datasets import load_iris
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans

# load_iris
iris = load_iris()
cols = ['sepal_length', 'sepal_width','petal_length','petal_width']
iris_df = pd.DataFrame(iris.data, columns = cols)
iris_df['target'] = iris.target

# PCA
pca = PCA(n_components=2)
iris_pca = pca.fit_transform(iris.data)
iris_df[['ftr1','ftr2']] = iris_pca

# KMeans
kmeans = KMeans(n_clusters=3, random_state=0)
iris_df['kmeans_label'] = kmeans.fit_predict(iris_pca)
centers = kmeans.cluster_centers_

# plot
markers = ['^','s','o']
for i, mark in enumerate(markers) :
    pca_x = iris_df[iris_df['kmeans_label']==i]['ftr1']
    pca_y = iris_df[iris_df['kmeans_label']==i]['ftr2']
    plt.scatter(pca_x, pca_y, marker=mark)
    plt.scatter(centers[i,0], centers[i,1], marker= mark, s=150, c='white', alpha=0.7, edgecolor='k')
    plt.scatter(centers[i,0], centers[i,1], marker='$%d$'%i, s=70, c='k')

plt.title('KMean Clustering with Iris Dataset')    
plt.xlabel('pca_x')
plt.ylabel('pca_y')
plt.grid()
plt.show()

KMeans with Iris Dataset

장점

- 알고리즘이 간결하고 직관적

- 원형 구조 데이터 세트에 효과적

 

단점

- 초기 군집 중심점 개수(n_cluster) 결정하기 어려움

- 속성의 개수가 많을수록/차원이 올라갈수록 군집화 정확도가 떨어짐 (→ PCA 차원 축소 적용)

- 복잡한 구조에는 한계가 있음

 

실루엣 계수(Silhouette Coefficient)란?

거리 기반의 K-평균 군집화 알고리즘의 평가 지표로, 각 군집 간의 거리가 얼마나 효율적으로 분리되어 있는지 나타낸다.

여기서 효율적이란? 동일 군집과는 가깝게 뭉쳐있고, 다른 군집과는 떨어져 있는 것을 의미함

 

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

  • s → 1 : 근처 군집과 멀리 떨어져있음
  • s → 0 : 근처 군집과 가까워짐
  • s < 0 : 다른 군집에 데이터 포인트가 할당됨

 

사이킷런 클래스 sihouette_samples, sihouette_score

1. silhouette_samples : 개별 데이터 포인트의 실루엣 계수

sklearn.metrics.silhouette_samples(X, labels, *, metric='euclidean', **kwds)

2. sihouette_score : 전체 데이터 셋의 실루엣 계수의 평균값

sklearn.metrics.silhouette_score(X, labels, *, metric='euclidean', sample_size=None, random_state=None, **kwds)

 

좋은 군집화의 조건

1. 전체 실루엣 계수의 평균값이 ∈ [0,1], 1에 가까울수록 효율적인 군집화

2. 개별 군집의 평균값의 편차가 크지 않아야함. 즉, 개별 군집의 실루엣 계수 평균값이 전체 실루엣 계수의 평균값에서 크게 벗어나지 않는 것이 중요

 

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

- 군집화 개수에 따른 군집별 실루엣 계수 (iris 데이터 세트)

- 군집 개수 3개 이상부터는 특정 군집(label=1)의 실루엣 계수가 높기 때문에 군집 개수를 2개로 하는 것이 가장 좋아보임

 

 

 

 

참고 문헌

 

 

댓글