데이터 분석 초보자를 위한 k-means clustering (with Scikit-Learn)

Gayeon Kim·2020년 9월 25일
5

데이터 분석

목록 보기
4/9

1. 컴퓨터도 학습을 한답니다.


컴퓨터로 할 수 있는 일이 점점 많아지고 있다. 요즘 컴퓨터는 사람과 대화도 하고, 작곡도 하고, 또 미래에 있을 일을 예측도 해준다. 그러나 이러한 일들은 처음부터 가능했던 건 아니다. 예전에는 엄청나게 큰 계산기에 불과했던 컴퓨터가 이렇게 똑똑해진 이유는 컴퓨터가 많은 것을 배웠기 때문이다. 컴퓨터가 사람도 아닌데 뭘 배우냐고? 물론 컴퓨터가 사람처럼 학교에 가고, 수업을 듣는 건 아니지만 컴퓨터도 학습을 한다. 당신이 여태까지 한 번쯤은 들어봤을 '머신러닝'이 바로 컴퓨터를 학습키는 방법을 연구하는 분야이다.

머신러닝은 학습의 목적과 주어지는 데이터의 특징에 따라 지도 학습과 비지도 학습으로 나뉘며, 각각의 대표적인 예로는 Classification과 Clustering이 있다. 먼저, Classification에 대해서 얘기해보자. 당신은 5살짜리 조카에게 강아지와 고양이 사진을 각각 10장씩 보여주면서 "얘는 강아지야.", "얘는 고양이야." 하고 답을 말해주었다. 그럼 그 사진을 보고 있는 아이는 '고양이는 귀가 세모 모양이야!', '강아지는 귀가 내려와 있네?' 하면서 강아지와 고양이를 구분할 수 있는 특징들을 파악할 것이다. 그 결과 이제 아이에게 강아지인지 고양이인지 말하지 않은 채 사진만 보여주어도 아이는 그 사진 속 동물이 강아지인지 고양이인지 대답을 할 수 있게 된다. 이 과정이 바로 지도학습 중 하나인 Classification이다. Classification은 새로운 데이터가 주어졌을 때 그 데이터의 답을 예측하는 것을 목표로 하며, 답이 있는 데이터를 가지고 학습을 한다. 반면 Clustering은 답이 없는 데이터가 주어지며, 비슷한 것끼리 묶어 그룹을 만든다. 이번에는 당신이 조카에게 단풍나무 잎과 은행나무 잎 총 20개를 주면서 답은 말해주지 않고 "비슷한 것끼리 나눠보자!"라고 말했다. 그럼 아이는 무엇이 단풍나무 잎이고 무엇이 은행나무 잎인지 모르지만, 당신으로부터 받은 나뭇잎의 색깔과 모양을 관찰하며 비슷한 것끼리 두 그룹으로 나눌 것이다. 이 과정이 바로 Clustering이다. 컴퓨터에게 답을 모르는 데이터를 주면 컴퓨터는 유사한 것끼리 묶어 데이터들을 그룹1, 그룹2, ..., 그룹n으로 나눈다. 컴퓨터는 그룹1이 무엇인지 모르고 그룹2가 무엇인지 모른다. 단지 그룹1과 그룹2가 다르다는 결과만 내놓는다.

사람을 학습시키는 데에도 다양한 방법이 있듯이, Classification과 Clustering에도 다양한 방법이 있다. 오늘은 Clustering의 방법 중 하나인 k-means clustering의 과정을 알아보자.



2. k-means clustering


데이터 준비

  • 필요한 패키지 및 라이브러리 import
from sklearn.datasets import make_blobs
import pandas as pd
import numpy as np
import math
import scipy as sp
import seaborn as sns
import matplotlib.pyplot as plt

sns.set_palette("Set2")
  • 데이터 생성

Scikit-Learn은 머신러닝을 위한 파이썬 패키지이며, clustering을 할 수 있는 가상의 데이터셋을 만들어주는 함수들을 제공한다. 오늘은 그 중 하나인 make_blobs()를 사용해서 데이터셋을 만들어보자.

x, y = make_blobs(n_samples=100, centers=4, n_features=2, random_state=6)
points = pd.DataFrame(x, y).reset_index(drop=True)
points.columns = ["x", "y"]
points.head()

[Out]

xy
00.276181-2.21705
17.92737-9.76153
28.49143-2.54975
3-11.53712.43488
44.29226-8.9922

make_blobs()를 사용해서 위와 같이 200개의 점들의 x, y좌표 데이터셋을 생성하였다.


1) 직접 해보는 k-means clustering

Step 1. k값 정하기

k-means clustering이란 이름에서 알 수 있듯이 주어진 데이터셋을 k개의 중심점을 기준으로 하여 그룹짓는 방법이다. 따라서, 중심점을 몇 개로 할 것인지를 미리 정해줘야 한다.

sns.scatterplot(x="x", y="y", data=points, palette="Set2");

위 그래프는 우리가 만든 데이터셋을 scatter plot으로 그려본 것이다. 데이터의 분포를 보니 k값이 4 정도면 적당한 cluster들을 얻을 수 있을 것 같다. 따라서, k=4로 해보자.


Step 2. 중심점(Centroid) 구하기

k값을 정했으니 이제 중심점을 구해야 한다. 중심점이란 말 그대로 각 cluster의 중심 좌표를 말한다. 2차원 데이터를 예로 들면 각 cluster의 중심점은 각 cluster의 x좌표의 평균과 y좌표의 평균이 된다. 단, clustering을 시작할 때는 아직 cluster가 생성되지 않았고 따라서 cluster의 중심점을 구할 수 없기 때문에 전체 데이터 중에서 랜덤한 k개의 데이터를 중심점으로 사용한다.

centroids = points.sample(4, random_state=1)
centroids

[Out]

xy
836.95292-8.22624
308.98427-4.8745
567.52132-2.12267
247.4817-2.96404

위와 같이 전체 데이터 중에서 4개를 랜덤하게 골라 첫번째 중심점으로 삼았다.

각 중심점의 위치는 위 그림에서 빨간 점으로 표시하였다.


Step3. 각 중심점으로부터의 거리를 구하여 가까운 중심점의 cluster로 할당하기

각 데이터에 대해서 4개의 중심점과의 거리를 계산한다. 그 후 값을 비교하여 가장 가까운 중심점의 cluster로 해당 데이터를 할당한다.

# 각 데이터에 대하여, 각 중심점과의 유클리드 거리 계산
distance = sp.spatial.distance.cdist(points, centroids, "euclidean")

# 가장 거리가 짧은 중심점의 cluster로 할당
cluster_num = np.argmin(distance, axis=1)

# 결과 확인
result = points.copy()
result["cluster"] = np.array(cluster_num)
result.head()

[Out]

xycluster
00.276181-2.217053
17.92737-9.761530
28.49143-2.549752
3-11.53712.434882
44.29226-8.99220

위와 같이 각 데이터에 대하여 해당하는 cluster 번호를 구했다. 이를 cluster 별로 색을 다르게 해서 scatter plot으로 그려보면 아래와 같다.

sns.scatterplot(x="x", y="y", hue="cluster", data=result, palette="Set2");

언뜻 보기에도 잘 분류된 cluster도 있는 반면, 그렇지 않은 cluster도 있다는 걸 알 수 있다.


Step 4. 변경된 cluster에 대해서 중심점 구하기

각 cluster에 대해서 중심점을 구해보자. 위에서 언급했듯이, 2차원 데이터셋일 때 cluster의 중심점은 x좌표의 평균과 y좌표의 평균이다.

# cluster별로 묶어서 평균 계산
centroids_2 = result.groupby("cluster").mean()
centroids_2

[Out]

clusterxy
06.48446-9.14955
18.87126-4.20368
2-2.592790.186325
34.91947-3.23962

Step 5. 각 중심점으로부터의 거리를 구하여 가까운 중심점의 cluster로 할당하기

새로 구한 중심점에 대하여, Step 3에서 했던 과정을 반복한다. 그 결과를 scatter plot으로 그려보면 아래와 같다.

아까보다 조금 더 의미있는 cluster를 얻었다.

Step 6. Step 4, 5 반복하기

각 cluster에 의미있는 변화가 없을 때까지 Step 4와 Step 5를 반복해서 시행한다.

  • 3번째 실행 결과

  • 4번째 실행 결과

  • 5번째 실행 결과

4번째 실행 결과와 5번째 실행 결과는 유의미한 차이가 없어보인다. 따라서 실행을 종료한다.

위의 그림은 k-means clustsering을 시작하기 전이며, 아래 그림은 k-means clustering을 한 결과이다. 두 그림을 비교해보면 알 수 있듯이, 우리는 k-means clustering을 통해서 데이터를 적절하게 4개의 cluster로 그룹화하였다.


2) Scikit-Learn을 이용해보자

그렇다면 위 과정을 매번 하나하나 반복해야 할까? 다행히도 우리에게는 Scikit-Learn이라는 마법의 도구가 있다. Scikit-Learn은 k-means clustering을 보다 편하게 수행할 수 있도록 관련 함수를 제공한다.

from sklearn.cluster import KMeans 

# k-means clustering 실행
kmeans = KMeans(n_clusters=4)
kmeans.fit(points)

# 결과 확인
result_by_sklearn = points.copy()
result_by_sklearn["cluster"] = kmeans.labels_
result_by_sklearn.head()

[Out]

xycluster
00.276181-2.217052
17.92737-9.761533
28.49143-2.549750
3-11.53712.434881
44.29226-8.99223

위 결과를 시각화해보면 아래와 같다.

sns.scatterplot(x="x", y="y", hue="cluster", data=result_by_sklearn, palette="Set2");



3. 이 세상에 완벽한 방법은 없다


여기까지 글을 읽고 나면 '이제 나는 k-means clustering을 할 수 있으니까 Clustering은 다 할 수 있어!'라는 생각이 들 수 있다. 하지만 안타깝게도 이 세상에 완벽한 방법은 없다.

x, y = make_circles(n_samples=200, noise=0.05)
circle = pd.DataFrame(x, y)
circle.columns = ["x", "y"]

kmeans = KMeans(n_clusters=2)
kmeans.fit(circle)
labels = kmeans.labels_

result_by_sklearn = circle.copy()
result_by_sklearn["cluster"] = kmeans.labels_
a = sns.scatterplot(x="x", y="y", hue="cluster", data=result_by_sklearn, palette="Set2")

plt.legend([],[], frameon=False);

위 그림을 잘 보면, 데이터가 큰 원이 하나 있고 그 안에 작은 원이 있는 모양으로 분포되어 있다는 것을 알 수 있다. 이런 데이터를 가지고 clustering을 한다면, 우리는 보통 원 두 개로 cluster가 생성될 것을 기대한다. 그런데 k-means clustering은 우리의 기대와 달리 좌우대칭 형태로 cluster를 만들었다.

이처럼 세상에는 k-means clustering이 잘 분류할 수 있는 데이터셋도 있는 반면, 그렇지 못한 데이터셋도 존재한다. 이는 k-means clustering 뿐만 아니라 모든 데이터 분석 방법에 동일하게 해당되는 것이다. 그러므로 우리는 다양한 데이터 분석 방법을 익혀야 하며, 데이터 분석 시 상황에 맞는 적합한 방법을 선택해야 한다.

2개의 댓글

comment-user-thumbnail
2021년 4월 15일

저혹시 몇가지 질문사항 있는데 드려두될까요?
Step3를 반복하면 된다고하셨는데 따로 변수명이나 바꿀필요없이 그대로 복사하여 반복하면될까요?

답글 달기
comment-user-thumbnail
2022년 12월 15일

Web Design is an important part of building, developing and maintaining websites. Here you visit this best roof paint nz and get more new roof painting. Web design encompasses all aspects of the creative process from strategy through to content management. Having a good understanding of web design is critical for any developer working in this space.

답글 달기