with Latent Dirichlet Allocation
작년에 융합과학대학원에서 열린 '소셜컴퓨팅' 수업(prof. 서봉원)에서 LDA(Latent Dirichlet Allocation)라는 데이터 모델을 배웠다. 요즘 텍스트 분석 분야에서 가장 핫한 알고리즘이다.
뉴스 기사를 읽고, 해당 내용이 정치에 대한 것인지 경제에 대한 것인지를 판단해야 한다고 해 보자. 이를 사람이 할 수도 있겠지만 그렇게 되면 많은 시간이 걸린다. 뉴스 기사가 아니라 트위터 데이터라고 해 보자. 트위터 데이터 150만 건을 사람이 읽고 각각이 어떤 내용인지 판단할 수 있을까? 정말 어려운 일이다. 이 어려운 걸 기계는 자꾸 해낸다. 이게 LDA다.
단어(word)가 모이면 토픽(topic)이 되고, 토픽이 모이면 문서(document)가 된다. 각 단어는 토픽을 대표할 수 있고, 토픽의 집합이 문서가 된다. 각 단어가 몇 번 토픽에 속하는지 알아내는 방법이 LDA다.
이렇게 생각하면 매우 간단한데, 위키피디아에서 LDA 찾아서 읽어 보면 90%가 수식이다. 겁나게 복잡하다. 정말 수식이 그렇게 많은가 궁금하시면 아래 링크를 따라가 보시길.
https://en.wikipedia.org/wiki/Latent_Dirichlet_allocation
'bank'라는 단어를 생각해 보자. 이 단어는 두 가지 의미(1. 은행, 2. 둑, 제방)를 가지고 있다. 이 단어가 독립적으로 존재하고 있으면 정확한 의미를 알기 어렵다. 확률은 반반이지만 어쨌든. 그런데 'bank'가 'money', 'loan' 같은 단어들과 함께 있다면? 이 'bank'는 은행이라는 뜻이라는 것을 알 수 있다. 마찬가지로 'bank'가 'river', 'stream' 같은 단어들과 함께 있다면 이 'bank'는 둑이나 제방을 의미한다는 것을 높은 확률로 미루어 짐작할 수 있다.
아래 그림은 LDA 분석의 결과이다. PCA처럼 PC(토픽)는 연구자가 직접 보고 판단해야 한다. 또한 토픽의 개수(k)는 k-means clustering에서처럼 연구자가 정해주어야 한다. 아래 예시를 보면, 토픽 247은 약에 대한 내용, 토픽 5는 색깔, 토픽 43은 생각이나 느낌, 토픽 56은 병원에 대한 내용이라는 것을 (사람이 직접 보고) 알 수 있는 것이다.
서두가 길었다. 이 LDA 분석을, 내가 모은 구글 장소 리뷰 데이터에 대해, R을 이용해서 적용해 보았다는 얘기를 하고 싶었다. 코드는 아래 블로그를 참고하였다(감사합니다).
http://cpsievert.github.io/LDAvis/reviews/reviews.html
일단 KoNLP 패키지를 이용하여 형태소를 분석했는데, 이때 SimplePos22를 이용하여 NC(보통명사)만을 추출한 후에 해당 NC만을 LDA 적용 대상으로 하였다. 설정값은 k: 5, G: 5000, alpha: 0.02, eta: 0.02로 하였다. 그래프를 이용한 시각화를 통해 분석 결과를 살펴보자.
처음에는 어떤 토픽도 선택되지 않은 화면을 볼 수 있다. 일단 전체 코퍼스 내에서 가장 중요한 단어(용어) 30개를 bar 그래프 형태로 볼 수 있다. '공원'에 대한 구글 장소 리뷰 데이터를 가지고 돌렸더니 '공원'이라는 명사가 가장 많은 빈도수를 보였다. 그리고 왼쪽 4분면 그래프는 내가 설정한 k개(여기서는 5개)의 토픽을 원의 형태로 보여 주고 있다. 이 그래프는 k개의 차원을 다시 2개의 차원(PC1, PC2)으로 축약하여 보여주는 것이다.
그리고 bar에서 각 단어를 클릭하면 해당 단어가 어느 토픽에 속하고, 그 비중이 어느 정도인지를 왼쪽 그래프가 보여준다.
그럼, 먼저 1번 토픽을 보자. 왼쪽 그래프를 보면, 1번 토픽과 5번 토픽은 상당히 유사한 것을 알 수 있다. 이들은 PC1과 PC2의 설명력이 모두 높은데, 특히 PC1의 설명력이 상당히 높다. 두 토픽에서 함께 출현한 빈도수 높은 단어로는 '여름', '자리'가 있다.
또한 2번 토픽과 4번 토픽도 유사성을 보였는데, 이들은 PC2의 설명력이 높은 편이다. 특히, 2번 토픽의 경우에는 PC2의 설명력이 상당히 높다. 두 토픽에서 함께 출현한 빈도수 높은 단어로는 '공원'이 있다.
반면에 3번 토픽은 PC1과 PC2의 설명력이 모두 낮았다.
형태소 분석이 잘 안 돼서 같은 의미인데도 분리되어 인식된 경우가 보인다. 예를 들면 '산책하기'는 3번 토픽에 할당되었고, '산책'은 5번 토픽에 할당되었다.
어쨌든 결과가 나왔으므로 각 토픽별로 할당된 단어들을 보고 토픽을 생각해 보았다. 그런데 4번 토픽은 도저히 모르겠다는. 그나마 1번 토픽이 다른 토픽들에 비해 공원의 특성을 잘 나타낸 것 같다. '사람(이 많다)', '다양한', '무료', '가족(들과 함께 오기 좋다)', '아이들(과 함께 오기 좋다)', '사진(찍기 좋다)', '한옥(이 있다)', '여름(에 오기 좋다)'처럼 공원의 특성과 관련된 내용이 예측된다. 3번 토픽 또한 비교적 잘 뽑힌 것 같다. '시설', '자전거', '산책하기', '운동', 이런 단어들로 보아 운동 관련 토픽일 가능성이 높아 보인다.
내가 LDA를 돌린 이유는 공간의 특성을 설명할 수 있는 속성(feature)을 자동으로 뽑아내기 위해서다. 그래서 명사만을 분석 대상으로 한 것인데, 일단 형태소 분석 과정에서 명사가 잘 분리가 안 되었다. 명사를 다시 잘 정제하여 돌려봐야겠다. 또한 형용사나 동사를 이용해서 토픽을 뽑으면 그 결과가 어떻게 나올지 궁금하다.
또한 LDA는 k, G, alpha, eta 값을 어떻게 설정하느냐에 따라 결과가 크게 달라질 수 있으며, 자신이 사용하는 데이터에 최적화된 설정값들을 찾아내는 것이 가장 중요한 부분이라고 할 수 있다.
LDA 코드 공유해 달라고 하시는 분들이 많아서 아래에 업로드해 놓았습니다. 위에서 참고했다고 얘기한 블로그에 나와 있는 코드와 크게 다르지 않다는 점을 밝힙니다. 감사합니다.
(제목 배경 이미지 출처)