본문 바로가기
데이터 청년 캠퍼스/SQL | 군집분석 | 소셜분석

[군집분석] K-Means 군집 분석 알고리즘

by 뚱뚜루뚱 2022. 7. 11.

군집분석:

 각 객체의 유사성을 측정하고 비슷한 특성을 가진 그룹을 찾는데 사용하는 분석 방법. Euclidean Distance를 통해 구한 개체 간 거리를 기반으로 유사성을 판단한다. 정답이 없는 비지도학습으로 비즈니스 전략 수립, 화물 배송 경로 개선(투입 차량 및 이동거리 감소) 등에서 활용된다.

 

 

K-Means 군집 분석 알고리즘:

 K개의 군집으로 객체들을 분할하는 알고리즘. 주어진 K에 선택한 분할 기준을 최적화할 수 있는 군집을 찾는다. 각 군집은 중심점에 의해 표현되고 객체들이 어느 중심점에 가까운가에 따라 군집을 결정한다. 반복적으로 수많은 분할을 수행 검토.

 

  1. 모든 객체들을 K개의 그룹으로 분할
  2. 분할한 클러스터 내 객체들로부터 새로운 seed 객체 탐색. 클러스터의 중심(평균) 값을 centroid로 정함
  3. 각 객체들을 인접한 seed 객체로 할당
  4. 클러스터가 변화하지 않을 때까지 2-3 단계 반복

 

Python 실습

1. 필요한 라이브러리와 패키지 설치

from sklearn.cluster import KMeans
from sklearn import datasets
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
import matplotlib.pyplot  as plt
import seaborn as sns
import pandas as pd
import numpy as np

 

2. 사용할 데이터 불러오고 산점도로 확인하기

X = np.array([[2,0], [3,0], [4,0], [10,0], [11,0], [12,0], [20,0], [25,0], [30,0]])
plt.scatter(X[:,0], X[:,1], s=100) # plt.scatter(x, y, s=markersize, ...)

 

3. K-means 1회차

# KMeans 실행
# n_cluster=군집 개수, init=처음 중심, n_init=서로 다른 centroid seed로 알고리즘 실행할 횟수, 
# max_iter=반복횟수, fit(X)=데이터 X에 대하여 KMeans 수행
model1 = KMeans(n_clusters = 2, init = np.array([[3,0], [4,0]]), n_init = 1, max_iter =1, random_state = 1 ).fit(X) 

# 군집의 center 저장
c0, c1 = model1.cluster_centers_

print(model1.labels_) #포함되는 군집
print(c0, c1) # center의 위치 벡터
print(abs(model1.score(X))) # 객체와 중심점의 거리(분산)

 

4. 객체의 위치, center로 부터의 거리, 라벨(군집1 or 군집2)로 구성된 데이터프레임

def kmeans_df(model, c0, c1) :
  df = pd.DataFrame(np.hstack([X,
                               np.linalg.norm(X - c0, axis = 1)[:, np.newaxis], # 1번 중심과의 거리 표준화 # linalg 두 점과의 거리
                               np.linalg.norm(X - c1, axis = 1)[:, np.newaxis], # 2번 중심과의 거리 표준화
                               model.labels_[:, np.newaxis]]),
                    columns = ['x0', 'x1', 'd0', 'd1', 'c'])
  return df
  
kmeans_df(model1, c0, c1)

 

5. K-means 결과를 산점도로 표현

def plot_cluster(model, c0, c1):
  plt.scatter(X[model.labels_==0,0], X[model.labels_==0,1], s = 50, c = 'r', marker = 'v')   # 1번 군집
  plt.scatter(X[model.labels_==1,0], X[model.labels_==1,1], s = 50, c = 'b', marker = '^')   # 2번 군집
  plt.scatter(c0[0], c0[1], s = 70, c = 'r')   # 1번 중심점
  plt.scatter(c1[0], c1[1], s = 70, c = 'b')   # 2번 중심점
  plt.show()
  
plot_cluster(model1, c0, c1)

 

6. K-means 2회차

model1 = KMeans(n_clusters = 2, init = np.array([[2.5,0], [16,0]]), n_init = 1, max_iter =1, random_state = 1 ).fit(X) 
c0, c1 = model1.cluster_centers_
print(model1.labels_)
print(c0, c1)
print(abs(model1.score(X))) 

kmeans_df(model1, c0, c1)

plot_cluster(model1, c0, c1)

 

7. K-means 3회차

model1 = KMeans(n_clusters = 2, init = np.array([[3,0], [18,0]]), n_init = 1, max_iter =1, random_state = 1 ).fit(X) 
c0, c1 = model1.cluster_centers_
print(model1.labels_)
print(c0, c1)
print(abs(model1.score(X)))

kmeans_df(model1, c0, c1)

plot_cluster(model1, c0, c1)

 

8. K-means 4회차 - 군집에 변화가 없으므로 군집분석 종료

model1 = KMeans(n_clusters = 2, init = np.array([[4.75,0], [19.6,0]]), n_init = 1, max_iter =1, random_state = 1 ).fit(X) 
c0, c1 = model1.cluster_centers_
print(model1.labels_)
print(c0, c1)
print(abs(model1.score(X)))

kmeans_df(model1, c0, c1) 

plot_cluster(model1, c0, c1)

 

9. K-means 5회차

model1 = KMeans(n_clusters = 2, init = np.array([[7,0], [25,0]]), n_init = 1, max_iter =1, random_state = 1 ).fit(X) 
c0, c1 = model1.cluster_centers_
print(model1.labels_) 
print(c0, c1)
print(abs(model1.score(X)))

kmeans_df(model1, c0, c1) 

plot_cluster(model1, c0, c1)

 

 

 

 

K-means 군집 평가

1. SSE(Sum of Squared Error)

각 객체와 인접 클러스터 간의 거리 제곱의 합. 가장 보편적으로 사용한다.

SSE의 절대값이 작아지는 방향이 적절하다. 일반적으로 K가 증가하면 SSE가 감소한다.

 

2. 응집도(Cohesion)

클러스터 내 모든 거리 가중치의 합. 한 클러스터 내 객체들이 밀집된 정도

응집도가 최대화되는 방향이 적절하다

 

3. 분리도(Separation)

클러스터 외부 객체 간 모든 거리 가중치의 합. 한 클러스터가 다른 클러스터와 분리된 정도

분리도가 최대화되는 방향이 적절하다

 

4. 유사도 매트릭스

x, y축의 한 값이 각각의 데이터 객체로 표현되며, 객체가 동일한 클러스터에 위치한다면 '1'의 값, 서로 다른 클러스터에 위치한다면 '0'의 값을 부여한다. 일부 밀도기반 군집, 연속성 기반 군집, 랜덤 객체를 대상으로 한 유사성 매트릭스는 좋은 값이 나오지 않는다

'1'의 사각형 크기가 작아지는 방향이 적절하다

 

(이어서)