Python용 토픽 모델링 패키지 - tomotopy 개발

Posted by 적분 ∫2tdt=t²+c
2019. 5. 19. 20:32 프로그래밍/NLP

최근 몇 년 여 간 토픽 모델링이라는 자연언어처리 기법을 접하고 이를 통해서 다양한 실험 및 논문 작업을 진행했었는데요, 연구 목적으로 편하게 자주 사용하는 Python에는 토픽 모델링을 제공하는 패키지가 gensim을 제외하고는 크게 많지 않더라구요. Java 기반 라이브러리(Mallet 등)를 종종 이용해오다가, Java로 코딩하기가 너무 귀찮아서 Python에는 왜 이런 라이브러리가 없을까 한탄도 자주 했었습니다.

공부할 겸 깁스 샘플링 기반의 토픽 모델링 코드를 개인적으로 c++로 개발했던 적이 있습니다. 최근에 Python C API를 공부하며 겸사겸사 그 동안 개발해뒀던 토픽 모델링 툴을 Python 패키지화시키면 파이썬 유저들도 편하게 토픽 모델링을 할 수 있겠다 싶어서 용기를 내어 토픽 모델링 툴을 공개하게 되었습니다.

사실, 예전에 c#용 GUI로 개발하여 공개한 바가 있던 Tomoto GUI(https://bab2min.tistory.com/602)의 업그레이드 버전이라고 얘기할 수 있습니다. Topic Modeling Toolkit에서 따와 Tomoto이구요, 이번에는 python 패키지이기 때문에 tomotopy(토마토파이)가 되어버렸네요. github 주소는 다음과 같습니다.


https://github.com/bab2min/tomotopy


현재는 총 6가지의 토픽 모델(LDA, DMR, HDP, MG-LDA, PA, H-PA)을 제공하고 있습니다. 물론 각각의 모델을 제공하는 파이썬 패키지를 찾고자하면 찾을 수 있겠지만, 이를 한 데 묶어서 편리하게 이용할 수 있도록 제공한다는 점이 tomotopy의 기여가 아닐까 싶네요

성능

고성능에 목숨을 걸고(...) c++기반으로 개발되었기 때문에 속도는 굉장히 빠른 편입니다. 멀티코어를 지원하구요, SSE, AVX, AVX2와 같은 향상된 SIMD 명령어들 또한 지원합니다. 따라서 최신 x86-64계열의 CPU에서 빠른 속도로 실행이 가능합니다. 성능에 대해 논하자면, 유사하게 LDA 모델을 제공하는 gensim과 비교를 피할 수가 없겠는데요 결과부터 보여드리면 다음과 같습니다.

gensim은 Variational Bayesian 기법을 사용하는 반면 tomotopy는 Collapsed Gibbs Sampling을 사용하기 때문에 둘을 1대1로 비교하기는 어렵습니다. 위의 결과는 영어 위키피디아 문서 중 임의의 1000개를 추출하여(총 1,506,966개 단어, 약 10MB) 구성된 코퍼스를 대상으로 실험을 진행한 것입니다. gensim의 경우 총 10회 iteration을 실시하였고, tomotopy는 200회 iteration을 실시했습니다. VB의 경우 연산이 조금 오래걸리지만 금방 수렴한다는 특징이 있고, CGS의 경우 연산은 빠르지만 수렴이 느리기 때문에 iteration을 많이 해야한다는 특징이 있습니다.

tomotopy가 20배 더 많이 반복을 했지만, 속도면에서는 gensim보다 5~10배 가까이 빠른 것을 볼 수 있습니다. 혹시 tomotopy가 속도가 빠른대신 질 낮은 결과를 만들어내는 것일수도 있으니, 토픽 군집 결과에서 큰 차이가 있는지 확인해봅시다.

토픽 개수를 20으로 설정했을때의 결과입니다.

tomotopy가 생성한 토픽별 상위 6개 단어
#1use, acid, cell, form, also, effect
#2use, number, one, set, comput, function
#3state, use, may, court, law, person
#4state, american, nation, parti, new, elect
#5film, music, play, song, anim, album
#6art, work, design, de, build, artist
#7american, player, english, politician, footbal, author
#8appl, use, comput, system, softwar, compani
#9day, unit, de, state, german, dutch
#10team, game, first, club, leagu, play
#11church, roman, god, greek, centuri, bc
#12atom, use, star, electron, metal, element
#13alexand, king, ii, emperor, son, iii
#14languag, arab, use, word, english, form
#15speci, island, plant, famili, order, use
#16work, univers, world, book, human, theori
#17citi, area, region, popul, south, world
#18forc, war, armi, militari, jew, countri
#19year, first, would, later, time, death
#20apollo, use, aircraft, flight, mission, first
gensim이 생성한 토픽별 상위 6개 단어
#1use, acid, may, also, azerbaijan, cell
#2use, system, comput, one, also, time
#3state, citi, day, nation, year, area
#4state, lincoln, american, war, union, bell
#5anim, game, anal, atari, area, sex
#6art, use, work, also, includ, first
#7american, player, english, politician, footbal, author
#8new, american, team, season, leagu, year
#9appl, ii, martin, aston, magnitud, star
#10bc, assyrian, use, speer, also, abort
#11use, arsen, also, audi, one, first
#12algebra, use, set, ture, number, tank
#13appl, state, use, also, includ, product
#14use, languag, word, arab, also, english
#15god, work, one, also, greek, name
#16first, one, also, time, work, film
#17church, alexand, arab, also, anglican, use
#18british, american, new, war, armi, alfr
#19airlin, vote, candid, approv, footbal, air
#20apollo, mission, lunar, first, crew, land

자웅을 겨루는 결과가 나왔네요. 개인적으로는 iteration을 더 많이 돌린 tomotopy가 조금더 사람이 이해하기 쉬운 주제를 생성한 것 같습니다. 빠르고 해석이 용이한 결과를 낸다는 점에서 충분히 쓸만한 녀석이라고 말할 수 있겠습니다.


설치

Python3.5 이상에서는 다음과 같이 pip를 이용해서 쉽게 설치할 수 있습니다. 만약 리눅스 환경이라면 c++14 코드 컴파일을 위해서 gcc 5 이상의 버전이 필요합니다.

pip install tomotopy

사용법은 매우 간단합니다.


토픽 모델에 따라서 파라미터가 조금씩 달라지는데, 이에 대해서는 다음 API문서를 확인해주시면 되겠습니다.

https://bab2min.github.io/tomotopy/


이 댓글을 비밀 댓글로
    • 문의
    • 2019.11.25 21:31
    안녕하세요. 학습한 문서에 해당하는 토픽을 보는 메소드는 없나요?
    • https://bab2min.github.io/tomotopy/v0.4.0/kr/index.html#_3
      에 나와있는 코드를 보시면 mdl.docs[idx] 를 이용해 모델 내의 문헌 객체를 얻어오는 방법이 설명되어 있습니다.
      이렇게 얻은 document 인스턴스는 get_topics라는 메소드를 가지고 있는데요, 이 메소드를 호출하여서 해당 문헌에 어떤 토픽이 주로 분포하고 있는지를 확인할 수 있습니다.

      댓글로만 설명하기가 어려우니 따로 예시코드를 포함하는 포스팅을 올려드릴테니 조금만 기다려 주세요!
    • https://bab2min.tistory.com/641 에 관련 내용을 코드와 함께 올렸습니다. 이 글을 확인해주세요!
    • lhj
    • 2019.11.28 11:49
    최적의 k 값은 어떻게 찾나요??
    • 사실 이 문제에 대해서 많은 연구와 논의가 있었는데요, 명확한 해결책은 없구요 연구자가 자의로 설정해야 하는 부분이 큽니다. 단, k값에 따라서 모델의 예측력 (perplexity 혹은 log likelihood)이 달라지게 되는데, 이 값이 좋을수록 (perplexity가 낮거나 log likelihood가 높거나) 일반적으로 더 좋은 k값이라고 볼 수 있습니다.
      근데 반드시 perplexity나 log likelihood만 보기 어려운게 종종 k=1이거나 몇 백 이상일때 최적의 값을 보이기도 하거든요. 이런 경우는 분석 목적 하등 도움이 되지 않는 k값이기 때문에 목적에 따라 적절한 크기를 선택하는게 더 좋을때도 있습니다.