brunch

You can make anything
by writing

C.S.Lewis

by FameLee Feb 24. 2022

데이터 클러스터링, 이제 포스트잇이 아닌 코딩으로(3)

손하나 까닥 안하고 클러스터링 해보기

목차  
1. 클러스터링, 도대체 원리가 뭐야?  
2. 비개발자가 직접 해보는 클러스터링  
3. 마지막 최종 정리!


클러스터링, 도대체 원리가 뭐야?

1. 사전 작업, 벡터화

 이전 단계에서 전처리 데이터를 컴퓨터가 분석 가능한 벡터 형식으로 변환시켰다. 이제 데이터 분석만이 남았다. 벡터 데이터를 활용해 클러스터링을 진행하고, 어떤 주제로 브런치에 글을 써왔는지 알아내보자!

이전 글은 아래에서 확인 가능하다


 클러스터링에 들어가기 전, 다시 한 번 벡터화를 마친 데이터를 봐보자. sklearn 라이브러리의 TfidfVectorizer를 활용해, 전처리 데이터를 TF-idf 벡터로 아래와 같이 변환시켰다. 칼럼명을 보면 각각의 글을 구성한 단어가 리스팅된 걸 볼 수 있고, 데이터는 각 글에서 해당 단어의 TF-idf 값임을 알 수 있다.  벡터 데이터를 얻었으니 이제 클러스터링을 진행할 수 있다. 

 데이터 클러스터링도 벡터화와 마찬가지로 sklearn 라이브러리를 사용한다. 해당 라이브러리에 DBSCAN, KMEANS 등 다양한 클러스터링 알고리즘이 있고, 이 중에서 AgglomerativeClustering  함수를 사용할 것이다. AgglomerativeClustering, 번역하면 병합 군집을 뜻하는데, 군집을 병합해가면서 클러스터링을 진행하는 방식이다.


2. 문과생도 이해하는 벡터 개념

 해당 알고리즘의 원리를 확실히 이해하기 위해, 잠시 벡터를 짚고 넘어가자. 벡터는 n차원에서 크기와 방향을 갖는 값이다. 크기? 방향? 차원? 너무 복잡하고 공대스러워 보이는데, 예시로 보면 그리 어려운 개념이 아니다. 예시로, [2, 3]이란 벡터가 있다고 해보자. 여기서 요소의 갯수(2와 3)는 차원의 갯수를 의미한다. 따라서, 해당 벡터는 아래와 같이 2차원의 공간에 위치한다. 그렇다면, [2, 3, 4] 벡터는? 요소가 3개이므로, 3차원의 공간에 다음과 같이 위치한다. 


 벡터화를 통해 얻은 TF-idf 벡터도 위와 같이 n 차원의 공간에 위치한다. TF-idf 벡터는 본문에서 구성 단어의 TF-idf 값을 보여주는 벡터이다. 자세한 개념은 이전 글을 참고하자 즉, 칼럼을 구성하는 단어의 수만큼 차원이 존재하고, 각각의 데이터가 해당 차원의 어느 곳에 위치(크기와 방향)하는지를 칼럼 값이 나타낸다.

3. 벡터로 보는 군집화 원리

 위 벡터의 기초 개념사실 야매 수준을 이해하면, 병합 군집(AgglomerativeClustering)도 쉽게 이해할 수 있다. 앞서 언급했듯, '병합 군집'은 군집을 병합시켜서 클러스터를 찾는 방법이다. 아래 그림과 같이 다양한 데이터가 있다고 해보자. 특정 데이터 포인트 1개를 잡은 후에, 1개의 군집으로 라벨링한다. 이 후에 인근에서 가장 가까운 데이터와 연결시키고, 같은 군집으로 라벨링한다.


 이번에 다른 데이터 포인트 1개를 잡고, 앞선 과정을 따라한다. 이렇게 되면, 독립적인 2개의 군집이 생성된다. 이 과정을 반복하면, 여러 군집이 생성된다.  그러다가, 서로 다른 군집에 속한 포인트끼리 이어지는 상황이 발생한다. 이런 경우, 서로 다른 군집은 하나의  군집으로 합쳐진다. 최종적으로 하나의 군집만이 남게 된다. 


 sklearn의  AgglomerativeClustering 방법은 군집을 몇 개로 나눌지 처음부터 설정을 한다. 위와 같은 데이터 포인트 사이의 병합 과정을 진행하다가, 설정한 군집 갯수에 도달하면 병합을 멈춘다. 그리고, 각 군집에 속한 데이터를 같은 클러스터에 속한다고 본다.


4. 최적의 군집 수를 제가 찾으라고요?

 여기서, "군집을 몇개로 나눌지 처음부터 설정을 한다."라는 문구를 보고 이상함을 느낀다. 아무 것도 모르는 상태에서 설정해야 하는 군집이 몇 개인지 어떻게 알 수 있을까? 컴퓨터가 해주는 건 유사한 특징을 가진 데이터끼리 묶어주기만 할 뿐, 얼마나 묶어야 할지는 우리가 직접 결정해야 한다. 참고로 모든 클러스터링 알고리즘이 그런 건 아니다. 예시로 DBSCAN 방법은 알아서 군집 갯수를 도출한다.


 최적의 군집 갯수를 빠르게 파악하기 위해선, 덴드로그램(dendrogram)을 사용하면 된다. 덴드로그램은 각 데이터 포인트 사이의 유사성을 나타낸 트리 다이어그램이다. 축에는 각 데이터 포인트가 있고, 인접한 포인트끼리 군집을 어떻게 맺는지 확인할 수 있다. 여기서, 포인트 사이의 거리를 참고해 몇 개의 군집을 설정해야 하는지 유추할 수 있다. 



비개발자가 직접 해보는 군집화

1. 덴드로그램으로 군집 수 찾기

 개념을 이해했으니 직접 클러스터링을 진행해보자. 우선 최적의 군집 갯수를 알기 위해 scipy 라이브러리에서 dendrogram와 linkage 함수를 호출한다. 아래와 같이, 벡터화시킨 TF-idf 데이터를 linkage 함수에 입력한 후, 여기서 얻은 값을 dendrogram 함수를 이용해 덴드로그램을 그린다. 그 결과, Tf-idf를 활용해 약 50개개 브런치 글 사이의 병합 군집 과정을 확인할 수 있다. 


 위 코드에서 method 변수에 'ward'라는 문자열을 입력한 걸 볼 수 있다. method 변수를 어떻게 설정하느냐에 따라서, 군집 사이의 거리 측정 방식을 결정할 수 있다. 군집 병합 과정은 군집에서 가장 인접한 데이터 포인트끼리 연결시켜서 군집을 병합해가는 과정이다. 즉, '데이터 포인트와 군집 사이의 거리'를 어떻게 측정하느냐에 따라서, 가장 인접한 데이터 포인트가 달라질 수 있다. 'ward' 를 입력하면 분산치를 이용해서 거리를 측정하며, 그 외에도 'single', 'complete', 'average' 등이 있다.


2. 클러스터링 진행하기

 덴드로그램을 통해 군집 갯수로 12개를 설정하면, 적절하게 클러스터링이 된다고 판단했다. 설정할 군집 갯수를 정했으니, sklearn의 AgglomerativeClustering 함수를 이용해 클러스터링이 진행해보자. sklearn 라이브러리에서 AgglomerativeClustering 함수를 불러온 후, 클러스터링할 군집 갯수로 12개를 설정하면 된다. 아래와 같이 코드를 입력하면, 12개의 군집으로 클러스터링이 완료된다. [그룹 id] 칼럼을 보면, 각 글이 어떤 군집에 속하는지 확인할 수 있다.


 이제 각 그룹별로 단어의 빈도수를 측정해 핵심 키워드를 알아내고, 주제를 파악할 수 있다. 이전 글에 잠시 다룬 TF 벡터를 이용하면 된다. 앞선 과정을 통해 그룹 id가 0인 클러스터를 한 번 분석해보자. 아래를 보면, 총 11개의 글이 하나의 군집(그룹 id = 0)으로 묶여있음을 볼 수 있다.


3. 각 클러스터에서 주제 찾기

 sklearn 라이브러리의 CountVectorizer 함수를 이용해서 단어 빈도수를 분석할 수 있다. 아래 코드를 입력하면, 다음과 같이 각 본문마다 단어별 빈도수를 확인할 수 있다. 각 본문별 단어의 빈도 수를 분산 값을 활용해 핵심 키워드를 추출해봤다. 그 결과, 첫 번 째 클러스터인 11개의 글을 관통하는 주제는 "문제에서 기회를 찾고 솔루션 도출하기"임을 짐작할 수 있다.


 동일한 방법으로 모든 클러스터링에서 아래와 같이 핵심 키워드를 추출할 수 있다.



마지막 최종 정리!

 지금까지 너무 먼 여정을 거쳐왔다. 다시 한 번 여정을 차근차근 되짚어보자! (1) 브런치에서 주로 어떤 주제로 글을 쓰는지 알아내는 걸 분석 목적으로 설정했고, (2) 이를 위해 브런치에 적힌 글을 크롤링했다. (3) 이 후, 모든 글을 전처리를 진행해 필요한 단어만 추출했고 (4) 벡터화를 통해 TF-idf 벡터로 변환시켰다. (5) 이 벡터 값을 병합 군집 방법으로 클러스터링을 진행했고 (6) 마지막으로, 각 클러스터별 키워드를 분석해 핵심 키워드와 주제를 분석했다. 




 이전 글을 봐보고 싶다면 아래 링크 클릭!

1. 웹 크롤링과 전처리가 궁금하다면?

2. 전처리 데이터의 벡터화가 궁금하다면?


브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari