본 포스팅에서는 데이터 클러스터링(군집화)로 널리 사용되는 비지도학습 알고리즘 K-Means 클러스터링에 대해 최대한 쉽게 설명해보고자 한다. 파이썬 라이브러리 scikit-learn 사용법도 간략히 소개한다.
만약 우리가 다루는 데이터에 '레이블'이 붙어 있다면 지도학습, 즉 미리 가지고 있는 데이터와 레이블을 기반으로 예측이나 분류를 수행하는 모델을 만들 수 있다. 그러나 실제로는 레이블(분류)이 없는 경우가 더 많다. 물론 이렇게 별도의 레이블이 없는 데이터 안에서 패턴과 구조를 발견하는 비지도 학습도 머신러닝의 큰 축이고, 그 중 가장 대표적인 비지도 학습 기술이 바로 Clustering(군집화)이다.
참고로 지도학습 Classification(분류)과 엄연히 다른 거다. Classification은 미리 레이블이 붙어 있는 데이터들을 학습해서 그걸 바탕으로 새로운 데이터에 대해 분류를 수행하지만, Clustering은 레이블을 모르더라도 그냥 비슷한 속성을 가진 데이터들끼리 묶어주는 역할을 하기 때문이다.
아무튼 클러스터링, 군집화를 사용하는 예로는 아래와 같은 것들을 들 수 있다.
추천 엔진 : 사용자 경험을 개인화하기 위해 비슷한 제품 묶어주기
검색 엔진 : 관련 주제나 검색 결과 묶어주기
시장 세분화(segmentation) : 지역, 인구 통계, 행동에 따라 비슷한 고객들 묶어주기
군집화의 목표는 서로 유사한 데이터들은 같은 그룹으로, 서로 유사하지 않은 데이터는 다른 그룹으로 분리하는 것이 된다.
그러면 자연스럽게 2개의 질문이 따라올 것이다.
몇 개의 그룹으로 묶을 것인가
데이터의 '유사도'를 어떻게 정의할 것인가 (유사한 데이터란 무엇인가)
이 두 질문을 해결할 수 있는 가장 유명한 전략이 바로 K-Means 알고리즘이다.
K-Means에서는 이걸 구현하기 위해 반복적인(iterative) 접근을 취한다.
일단 K개의 임의의 중심점(centroid)를 배치하고
각 데이터들을 가장 가까운 중심점으로 할당한다. (일종의 군집을 형성한다.)
군집으로 지정된 데이터들을 기반으로 해당 군집의 중심점을 업데이트한다.
2번, 3번 단계를 수렴이 될 때까지, 즉 더 이상 중심점이 업데이트 되지 않을 때까지 반복한다.
그림으로 보면 아래와 같다.
여기서 일단 k값은 2다. 그래서 (b)에서 일단 중심점 2개를 아무 데나 찍고, (c)에서는 각 데이터들을 두 개 점 중 가까운 곳으로 할당한다. (d)에서는 그렇게 군집이 지정된 상태로 중심점을 업데이트 한다. 그리고 (e)에서는 업데이트 된 중심점과 각 데이터들의 거리를 구해서 군집을 다시 할당하는 거다.
이걸 계속 반복한다.
아무튼 이렇게 군집화를 해놓으면 새로운 데이터가 들어와도 그게 어떤 군집에 속할지 할당해줄 수 있게 되는 셈이다.
만약 두 점 사이의 거리에 대해 좀 더 자세히 알고 싶다면 이 포스팅을 참고하자.
파이썬 라이브러리 scikit-learn을 사용하면 K-means를 매우 쉽게 적용해볼 수 있다.
군집화를 하기 위해서는 몇개의 군집이 적절할지 결정해야 하는데, 그러려면 일단 "좋은 군집"이란 무엇인지 정의할 수 있어야 한다.
만약 군집화가 잘 되었으면 각 군집의 샘플이 가까운 거리에서 오밀조밀하게 묶일 거다. 군집 내의 데이터들이 얼마나 퍼져 있는지 (혹은 얼마나 뭉쳐있는지) 응집도는 inertia값으로 확인한다. inertia는 각 데이터로부터 자신이 속한 군집의 중심까지의 거리를 의미하기 때문에 inertia값이 낮을수록 군집화가 더 잘됐다고 볼 수 있는 거다.
scikit-learn으로 모델을 만들었다면 이렇게 찍어보면 끝이다.
그래서 군집의 개수, 즉 k 값을 바꿔가면서 inertia를 그래프로 표시하면 보통 이런 모양새가 나온다.
k값이 증가하면 inertia 값은 감소하다가 어느정도 수준이 되면 거의 변화를 안보이게 된다. 대부분의 경우 너무 많지 않은 군집으로 분류하면서도 inertia 값이 작은 상태. 이게 그나마 최선이 될 거다. 위의 그래프를 예로 들면 최적의 클러스터 수는 3으로 보인다.