[토픽 모델링] LSA와 LDA의 관계 (+ LDA라는 이름의 유래)

Posted by 적분 ∫2tdt=t²+c
2017.10.20 01:31 그냥 공부

Latent Dirichlet Allocation이라는 이름은 언뜻 들으면 무슨 뜻인지 이해하기가 어렵습니다. 토픽 모델링 기법 중 하나로 문헌-용어 행렬에서 문헌별 주제분포와 주제별 단어분포를 찾아주는 기술인데, 이름은 Latent Dirichlet Allocation이죠. Dirichlet는 이 기법이 디리클레 분포를 기반으로하기 때문에 붙은것이라고 유추가능하지만 Latent와 Allocation은 글쎄요?

궁금해서 이에 대해서 찾아보던 중, 사실 이 이름에는 토픽 모델링 기법의 변천사가 담겨있다는 것을 알게 되었습니다. 이 포스팅에서는 그 역사를 간략하게 소개하면서 이름의 뜻을 되짚어보도록 하겠습니다.


문헌-용어 행렬

문헌 집합을 표현하는 가장 고전적이면서도 직관적인 방법은 문헌들에 어떤 용어들이 들어있는지를 숫자로 표현하는 것입니다. 예를 들어


A: Cute kitty

B: Eat rice or cake

C: Kitty and hamster

D: Eat bread

E: Rice, bread and cake

F: Cute hamster eats bread and cake

(http://bab2min.tistory.com/569의 예시와 같은 녀석들입니다.)

위와 같이 문헌 6개가 있다고 하면, 단어의 순서를 무시해버리면(단어 주머니 모형, Bag-of-words model) 각 문헌은 문헌 내의 용어들의 빈도로 나타낼 수가 있겠죠. 불용어를 제외하면 위 문헌에는 총 7가지의 용어(cute, kitty, eat, rice, cake, hamster, bread)가 있습니다. 따라서 다음과 같이 표의 형태로 나타낼수 있겠죠.

cutekittyeatricecakehamsterbread
A1100000
B0011100
C0100010
D0010001
E0001101
F1010111


이를 문헌-용어행렬이라고 합니다. 문헌-용어 행렬은 문헌 집합을 수학적으로 처리할수 있는 방법을 제공합니다. 텍스트가 행렬이 되었으니 여기에 다양한 행렬 연산이나 분석 기법을 적용할 수 있으니까요! 단, 문헌-용어 행렬이 가지는 큰 한계는 0이 너무 많다는 것입니다. 지금은 전체 용어가 7종류, 문헌 6개였기에 이 정도이지, 실제로는 용어 종류가 굉장히 많고, 대부분의 문헌에서는 극히 일부의 용어만 출현하기에 문헌-용어 행렬은 대부분이 0인 희소행렬이 됩니다.

이게 뭐가 문제냐면, 행렬 크기는 무지 큰데, 실제로 담는 데이터는 그에 미치지 못하기에 여러 분석 기법들이 제대로 작동하지 않을 수 있다는 거죠.


PCA와 SVD

주성분분석(Principal Component Analysis)라는 개념이 있습니다. 높은 차원의 데이터들을 분석하여 그 중에서 핵심이 되는 차원을 뽑아내서 차원을 낮추는 기법입니다. 예를 들어 (1, 2, 1), (3, 6, 0), (2, 4, 5), (4, 8, 3)이라는 4개의 3차원 데이터가 있다고 합시다. 잘 살펴보면 앞의 2개는 서로 관계가 있는 값입니다. (1, 2), (3, 6), (2, 4), (4, 8)이니깐 첫번쨰 요소의 2를 곱하면 두번째 요소가 된다는 것을 알 수 있죠. 따라서 실제로 두 요소 중에서 하나만을 기술해도 나머지 하나는 알 수 있습니다. (수학적으로 어렵게 말하자면 두 차원은 서로 직교하지 않습니다) 따라서 위의 데이터는 겹치는 차원 하나를 제거해서 (1, 1), (3, 0), (2, 5), (4, 3) 과 같이 쓸 수 있겠죠.


그리고 선형대수에서는 특이값 분해(Singular Value Decomposition)이라는 개념이 있는데, 갑자기 이 얘기를 꺼내는 이유는 이 기법이 PCA와 관련이 있어서, 행렬 데이터의 차원을 축소하는데 자주 사용되기 때문입니다. 어떤 행렬 A를 UΣVT의 형태로 분해하는 기법인데, 자세한 내용은 http://darkpgmr.tistory.com/106 를 참고하시면 이해에 도움이 되실겁니다.

SVD에서 행렬을 분해할때, 일부 값이 작은 데이터를 잘라내어버릴 수도 있습니다. 그러면 원래의 크기보다 적은 크기의 행렬로 전체 행렬을 표현하는게 가능해지는데, 이 과정이 PCA와 연결되는 과정이라는 것이 이미 잘 알려져 있습니다.


SVD의 예시를 살펴봅시다. 위에서 제시했던 문헌-용어 행렬을 분해해보겠습니다.

A=

1100000
0011100
0100010
0010001
0001101
1010111

를 A = UΣVT형태로 분해하면 다음과 같습니다.


U=

0.12 0.57 -0.32 0.00 -0.71 -0.24
0.44 -0.36 -0.41 0.71 0.00 -0.08
0.12 0.57 -0.32 0.00 0.71 -0.24
0.33 -0.07 0.56 0.00 0.00 -0.75
0.44 -0.36 -0.41 -0.71 0.00 -0.08
0.69 0.30 0.37 0.00 0.00 0.55

Σ=

2.98 0.00 0.00 0.00 0.00 0.00 0.00
0.00 1.88 0.00 0.00 0.00 0.00 0.00
0.00 0.00 1.36 0.00 0.00 0.00 0.00
0.00 0.00 0.00 1.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 1.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.87 0.00

V=

0.27 0.46 0.04 0.00 -0.71 0.35 0.30
0.08 0.61 -0.47 0.00 0.00 -0.56 -0.30
0.49 -0.07 0.38 0.71 0.00 -0.33 0.00
0.30 -0.38 -0.61 0.00 0.00 -0.18 0.60
0.53 -0.22 -0.34 0.00 0.00 0.44 -0.60
0.27 0.46 0.04 0.00 0.71 0.35 0.30
0.49 -0.07 0.38 -0.71 0.00 -0.33 0.00


즉 

0.12 0.57 -0.32 0.00 -0.71 -0.24
0.44 -0.36 -0.41 0.71 0.00 -0.08
0.12 0.57 -0.32 0.00 0.71 -0.24
0.33 -0.07 0.56 0.00 0.00 -0.75
0.44 -0.36 -0.41 -0.71 0.00 -0.08
0.69 0.30 0.37 0.00 0.00 0.55
·
2.98 0.00 0.00 0.00 0.00 0.00 0.00
0.00 1.88 0.00 0.00 0.00 0.00 0.00
0.00 0.00 1.36 0.00 0.00 0.00 0.00
0.00 0.00 0.00 1.00 0.00 0.00 0.00
0.00 0.00 0.00 0.00 1.00 0.00 0.00
0.00 0.00 0.00 0.00 0.00 0.87 0.00
·
0.27 0.08 0.49 0.30 0.53 0.27 0.49
0.46 0.61 -0.07 -0.38 -0.22 0.46 -0.07
0.04 -0.47 0.38 -0.61 -0.34 0.04 0.38
0.00 0.00 0.71 0.00 0.00 0.00 -0.71
-0.71 0.00 0.00 0.00 0.00 0.71 0.00
0.35 -0.56 -0.33 -0.18 0.44 0.35 -0.33
0.30 -0.30 0.00 0.60 -0.60 0.30 0.00

를 계산하면 원 행렬 A가 나온다는 것이죠. 이제 데이터 양을 줄이기 위해 필요없는 부분을 잘라내어 봅시다. 특이값이 들어간 Σ 행렬에서 딱 2개행만 남기고 없애도록 하겠습니다. 2.98, 1.88이 제일 큰 2개이고, 나머니 값들은 없앨거에요. 마찬가지로 U에서도 왼쪽 2줄만 남기고 V에서도 왼쪽 2줄만 남기도록 하겠습니다.


U2=

0.12 0.57
0.44 -0.36
0.12 0.57
0.33 -0.07
0.44 -0.36
0.69 0.30

Σ2=

2.98 0.00
0.00 1.88

V2=

0.27 0.46
0.08 0.61
0.49 -0.07
0.30 -0.38
0.53 -0.22
0.27 0.46
0.49 -0.07


이 행렬을 가지고 U2*Σ2*V2T를 계산해볼 수 있겠죠. 이는 A의 근사치가 됩니다. 즉 우리는 SVD를 통해 6*7행렬을 2*6, 2*7 행렬과 특이값 2개로 근사해낸 것입니다.


A`=

0.59 0.68 0.10 -0.30 -0.05 0.59 0.10
0.04 -0.31 0.69 0.65 0.84 0.04 0.69
0.59 0.68 0.10 -0.30 -0.05 0.59 0.10
0.20 0.00 0.49 0.34 0.55 0.20 0.49
0.04 -0.31 0.69 0.65 0.84 0.04 0.69
0.81 0.51 0.97 0.40 0.96 0.81 0.97

원래 1인 부분을 굵게, 0인 부분은 연하게 표시했습니다. 많은 부분을 날려서 원 행렬을 정확하게 복구할수는 없었지만 대략적인 형태는 복원이 되는 것을 확인할 수 있습니다.


LSA

잠재의미분석(Latent Semantic Analysis)은 바로 윗 지점에서 출발합니다. SVD를 통해 문헌-용어 행렬을 그보다 더 작은 크기의 행렬로 표현할 수 있다고 했습니다. 위에서는 2개로 줄였죠. 그러면 U2*Σ2 와 Σ2*V2T가 의미하는 바는 무엇일까요? 앞의 행렬은 6(문헌개수) by 2 짜리 행렬이고, 뒤의 행렬은 2 by 7(용어개수)짜리 행렬입니다. 6 by 6이나 7 by 7이 아니라 6 by 2, 2 by 7로 압축된 행렬은 그 자체로 문헌에 출현하는 용어의 개수를 나타내지는 못합니다. 그 대신 뭔가 더 압축적인 어떤 것을 드러낼텐데요..! 이것을 Latent Semantic이라고 부릅니다. 함축된 의미라는 것이죠.


#1 #2
A 0.3573 1.0707
B 1.31 -0.6762
C 0.3573 1.0707
D 0.9825 -0.1315
E 1.31 -0.6762
F 2.0543 0.5635


위의 표는 U2*Σ2 행렬입니다. 굳이 의미를 찾아보자면, 각 문헌이 어떤 잠재 의미군에 속하는 용어들을 많이 포함하고 있는지, 그 비중을 보여준다고 할 수 있겠죠! 

마찬가지로 아래는 Σ2*V2행렬입니다. 각 잠재 의미군에 어떤 용어들이 속하는지 비중을 보여준다고 할 수 있겠습니다.

cute kitty eat rice cake hamster bread
#1 0.8038 0.2382 1.4588 0.8932 1.5779 0.8038 1.4588
#2 0.8641 1.1458 -0.1315 -0.7138 -0.4132 0.8641 -0.1315


이 분석의 목표는 크지 않는 N개 (이 예시에서는 2)의 잠재 의미군으로 문헌-용어 행렬을 압축함으로써 정보 검색이나 기타 텍스트 처리의 성능을 높이는 것이었습니다. cute animal라는 질의어로 검색을 수행하면 cute나 animal이 포함된 결과만 얻을 수 있겠죠. 하지만 잠재의미분석을 수행한다면 cute animal이라는 질의어가 더 낮은 차원의 행렬로 변환되고, 그 행렬값과 #1, #2 값이 유사한 문헌을 찾으면 kitty나 hamster가 포함된 문헌도 얻어낼 수 있을테니까요.


pLSA

그리고 마침내 토픽 모델링의 조상이 되는 pLSA(Probabilistic Latent Semantic Analysis)가 등장하게 됩니다. LSA와 이름이 유사한것으로 보아 비슷한 기법일거라고 예측이 가능하실 겁니다. 앞의 p는 이것이 확률 모델임을 나타냅니다. 즉 문헌-용어 행렬을 문헌 내에 특정 용어가 등장한 횟수를 기반으로 하는것이 아니라, 문헌 내에 특정 용어가 등장할 확률을 기반으로해서 구축하는 것이죠. 확률이라는 것 때문에 여러 가지가 바뀌는데요, 먼저 모든 요소의 값이 0~1사이가 되어야 합니다. 그 결과 위처럼 단순히 SVD를 이용해서 행렬 분해를 진행할 수 없게 되었습니다. SVD는 0~1 사이가 아니라 음수나 1이상의 값도 얼마든지 나오도록 행렬을 분해하기 때문이죠. 그대신 음수 미포함 행렬 분해 기법을 활용하거나 기대값 최대화 기법 등을 통해서 행렬 분해를 대신하게 구현되었습니다.


이 기법은 근본적으로 LSA에서 아이디어를 얻은것이기에, 단순히 문헌-용어 행렬만을 입력으로 받습니다. 즉 문헌 내에 주제가 어떻게 분포하고 있을지는 고려하지 않습니다. (현재 흔히 쓰이는 LDA가 문헌별 주제분포주제별 단어분포라는 2가지 분포를 고려하는것과는 대비되는 부분입니다.) 이는 pLSA의 주요 약점으로 지적되었고, 이를 개선하는 LDA가 등장한 것입니다.


LDA

LDA는 pLSA의 약점을 보완하기 위해서 등장합니다. pLSA는 새로운 문헌을 생성해내는 것을 잘 다루지 못한다는 문제가 있었는데, 이를 (문헌별 주제) 디리클레 분포를 적용하여 보완한 것이죠. 디리클레 분포를 사용했으니깐 D를 써야할텐데 그게 S 자리를 밀어내서 LDA라는 이름이 만들어지게 된 것이라 봐도 좋겠군요! LDA의 Latent는 Latent Semantic(잠재 의미=>토픽)의 Latent이기도 하고, 또한 LDA 모델에 들어가는 잠재변수들을 가리키기도 하는 것이고요. 그리고 Analysis의 A 대신 Allocation의 A를 써서, 각각의 단어가 특정 주제에 할당된다는 것을 강조한거죠. 이렇게 보면 어려워 보이던 이름이 사실은 굉장히 유서깊고, 기법의 특징을 잘 드러내는 것처럼 보이지 않나요?


참고 링크

http://darkpgmr.tistory.com/106

https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/04/06/pcasvdlsa/

Liu, L., Tang, L., Dong, W., Yao, S., & Zhou, W. (2016). An overview of topic modeling and its current applications in bioinformatics. SpringerPlus5(1), 1608.

이 댓글을 비밀 댓글로
  1. 저희 회사 서비스들도 LDA를 적용한 접근을 사용하고 있어서 더욱 관심깊게 읽게되었습니다.
    좋은 글 잘 보고 갑니다.