Data Analysis & ML/Machine Learning

[Machine Learning][머신러닝] 군집(Clustering) / K-Means Clustering

YSY^ 2020. 9. 7. 18:55

군집 (Clustering)

비지도 학습으로 비슷한 특성을 가지는 데이터들끼리 그룹으로 묶는다.

적용

  • 고객 분류
    • 고객 데이터를 바탕으로 비슷한 특징의 고객들을 묶어 성향을 파악할 수 있다.
  • 이상치 탐지
    • 모든 군집에 묶이지 않는 데이터는 이상치일 가능성이 높다
  • 준지도학습
    • 레이블이 없는 데이터셋에 군집을 이용해 Label을 생성해 분류 지도학습을 할 수 있다. 또는 레이블을 좀더 세분화 할 수 있다.

 

k-mean (K-평균)

  • 가장 널리 사용되는 군집 알고리즘 중 하나.
  • 데이터셋을 K의 군집으로 나눈다. K는 하이퍼파라미터로 사용자가 지정한다.
  • 군집의 중심이 될 것 같은 임의의 지점(Centroid)을 선택해 해당 중심에 가장 가까운 포인드들을 선택하는 기법.

알고리즘 이해

출처 : http://ai-times.tistory.com/158

특징

  • K-mean은 군집을 원 모양으로 간주 한다.
  • 모든 특성은 동일한 Scale을 가져야 한다.
  • 이상치에 취약하다.

iris데이터 군집화

import numpy as np
import pandas as pd
from sklearn.datasets import load_iris

iris = load_iris()
X = iris.data
y = iris.target

# k-mean => feature scaling
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

from sklearn.cluster import KMeans
# 하이퍼파라미터 : 몇개의 그룹으로 묶을지 지정 - n_clusters
kmeans = KMeans(n_clusters = 3)
# 학습
kmeans.fit(X_scaled)
#==> KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,
       n_clusters=3, n_init=10, n_jobs=None, precompute_distances='auto',
       random_state=None, tol=0.0001, verbose=0)
#각각의 feature들이 어떤 그룹을 묶였는 조회
cluster = kmeans.labels_
cluster

np.unique(cluster, return_counts=True)
# (array([0, 1, 2]), array([47, 50, 53], dtype=int64))

df = pd.DataFrame(X, columns=iris.feature_names)
df['label'] = cluster
df.head()

 

Inertia value를 이용한 적정 군집수 판단

  • inertia
    • 군집내 데이터들과 중심간의 거리의 합으로 군집의 응집도를 나타내는 값이다.
    • 값이 작을 수록 응집도가 높게 군집화가 잘되었다고 평가할 수 있다
    • KMean의 inertia_ 속성으로 조회할 수 있다.
    • 군집 단위 별로 inertia 값을 조회한 후 급격히 떨어지는 지점이 적정 군집수라 판단 할 수 있다.
# inertia 값 조회
kmeans.inertia_  => 139.82049635974982

inertia_list = []
k_list = range(2,10) #그룹 2 ~ 9 
for k in k_list:
    model = KMeans(n_clusters=k)
    model.fit(X_scaled)
    inertia_list.append(model.inertia_)

import matplotlib.pyplot as plt
plt.figure(figsize=(7,6))
plt.plot(k_list, inertia_list)
plt.xlabel('그룹 수')
plt.ylabel('Inertia 값')
plt.show()

 

평가 : 실루엣 지표

  • 실루엣 계수 (silhouette coefficient)
    • 개별 관측치가 해당 군집 내의 데이터와 얼마나 가깝고 가장 가까운 다른 군집과 얼마나 먼지를 나타내는 지표
    • -1 ~ 1 사이의 값을 가지며 1에 가까울 수록 좋은 지표이다.
      • 1에 가까우면 자신이 속한 군집에 잘 속해있다는 의미 (중심에 가까이 있다.)
      • 0에 가까우면 군집의 경계에 위치한다는 의미
      • -1에 가까우면 잘못된 클러스터에 할당되어 있다는 의미
  • silhouette_samples()
    • 개별 관측치의 실루엣 계수 반환
  • silhouette_score()
    • 실루엣 계수들을의 평균
  • 좋은 군집화의 지표
    • 실루엣 계수 평균이 1에 가까울수록 좋다.
    • 실루엣 계수 평균과 개별 군집의 실루엣 계수 평균의 편차가 크지 않아야 한다.
from sklearn.metrics import silhouette_samples, silhouette_score
s_coefs = silhouette_samples(X_scaled, cluster) #X, label

s_mean = silhouette_score(X_scaled, cluster)
s_mean #=> 0.45994823920518635


df['silhouette'] = s_coefs
df.head()

 

df.groupby('label')['silhouette'].mean()

0 0.347392
1 0.636316
2 0.393377

728x90
반응형