for textmining

Cohesion Probability

|

이번 글에서는 말뭉치 내 빈도로 단어를 추출하는 기법인 Cohesion Probabilty(이하 CP)에 대해 살펴보도록 하겠습니다. CP는 Kim&Cho(2013)가 제안한 모델인데요, 이 글은 모델 원저자인 김현중 서울대 박사과정이 진행한 2017 패스트캠퍼스 강의와 코드를 참고하였음을 먼저 밝힙니다. 그럼 시작하겠습니다.

기법 개요

CP는 연속된 글자의 연관성이 높을 수록 단어일 가능성이 높다는 가정 하에 구축된 모델입니다. $c_1$, $c_2$, …, $c_{n-1}$ 다음에 $n$번째 글자인 $c_n$이 많이 나오면 $n$개 문자열로 이뤄진 $c_1$, $c_2$, …, $c_{n-1}$, $c_n$은 단어일 것이라는 이야기입니다. 글자별로 조건부 확률을 구하여 모두 곱한 뒤 $1/n$승을 해서 구합니다. 아래 식과 같습니다.

\[\begin{align*} cohesion({ c }_{ 1 },{ c }_{ 2 },...,{ c }_{ n })&=\sqrt [ n ]{ \prod _{ i=1 }^{ n-1 }{ P({ c }_{ 1 },...,{ c }_{ i+1 }|{ c }_{ 1 },...,{ c }_{ i }) } }\\&=\sqrt [ n ]{ \frac { Freq({ c }_{ 1 },{ c }_{ 2 },...{ c }_{ n }) }{ Freq({ c }_{ 1 }) } } \end{align*}\]

분석 예시

예를 들어보겠습니다. $cohesion(박태환)$은 아래와 같이 ‘박태환’ 빈도수를 ‘박’의 개수로 나눈 뒤 세제곱을 취해 구합니다. 아래 식에서 $N$은 말뭉치에 등장하는 단어 빈도수의 총합인데, 분자 분모에 동시에 있으므로 계산상 가능합니다. CP는 빈도만으로도 얼마든지 구할 수 있습니다.

\[\begin{align*} cohesion(박태환)&=\sqrt [ 3 ]{ P(박태|박)P(박태환|박태) } \\ &=\sqrt [ 3 ]{\frac { P(박태) }{ P(박) } \frac { P(박태환) }{ P(박태) } } \\ &=\sqrt [ 3 ]{ \frac { P(박태환) }{ P(박) } } \\ &=\sqrt [ 3 ]{ \frac { Freq(박태환)/N }{ Freq(박)/N } } \\ &=\sqrt [ 3 ]{ \frac { Freq(박태환) }{ Freq(박) } } \end{align*}\]

이번엔 실제 말뭉치를 가지고 예를 들어보겠습니다. 영화 리뷰 사이트 ‘왓챠’에서 655만306개의 리뷰를 수집했습니다. 우선 이를 글자 단위로 세었습니다.

구분 빈도수
14145
꿀잼 10179
꿀잼ㅋㅋ 306

위 표를 토대로 $cohesion(꿀잼)$과 $cohesion(꿀잼ㅋㅋ)$를 각각 구해보겠습니다.

\[\begin{align*} cohesion(꿀잼)&=\sqrt [ 2 ]{ \frac { Freq(꿀잼) }{ Freq(꿀) } } =\sqrt [ 3 ]{ \frac { 10179 }{ 14145 } } =0.8483\\ cohesion(꿀잼ㅋㅋ)&=\sqrt [ 4 ]{ \frac { Freq(꿀잼ㅋㅋ) }{ Freq(꿀) } } =\sqrt [ 4 ]{ \frac { 306 }{ 14145 } } =0.3835 \end{align*}\]

위 결과를 해석하면 이렇습니다.

'꿀잼'이 단어일 확률은 '꿀잼ㅋㅋ'이 단어일 확률보다 두 배 가량 높다.

이를 토대로 ‘꿀잼ㅋㅋ’이라는 문자열을 토크나이즈(tokenize)하면 아래와 같습니다.

꿀잼,ㅋㅋ

말뭉치 분석 결과

지금까지 CP는 왼쪽에서 오른쪽 방향(forward)으로 빈도수를 세어 분석하는 방법만을 설명했는데요, 사실 오른쪽에서 왼쪽(backward)으로도 분석이 가능합니다. 우선 왓챠 리뷰 655만306개 리뷰를 학습해 forward 방향 CP 상위 500개 문자열을 나열한 결과는 아래와 같습니다. (CP * 빈도수 내림차순 정렬)

영화, 너무, 생각, 사랑, 연기, 액션, 스토리, 재미, 배우, 재밌, 사람, 최고, 스토, 있는, 정말, 우리, 느낌, 아니, 작품, 장면, 마지막, 캐릭터, 현실, 캐릭, 이야기, 감독, 만들, 없는, 있다, 음악, 진짜, 보고, 마지, 대한, 매력, ㅋㅋ, 영화를, 좋았, 처음, 기대, 내가, 없다, 하지만, 하지, 그리고, 인간, 괜찮, 기억, 같은, 하는, 이야, 함께, 주인공, 표현, 그리, 것이, 역시, 결말, 필요, 긴장, 다시, 좋은, 연출, 하나, 보는, 원작, 좋아, 같다, 않는, 영화가, 모든, 배우들, 가장, 시리즈, 주인, 엔딩, 지루, 소재, 마음, 훌륭, 반전, 인생, 그래, 모르, 영화는, 이런, 행복, 많이, 세상, 감동, 최고의, 뭔가, 흥미, 재미있, 완벽, 내용, 남자, 보여, 시간, 순간, 살아, 근데, gt, 긴장감, 몰입, ㅋㅋㅋ, 코미디, 계속, 조금, 시리, 이렇게, 아름, 존재, 있었, 밖에, 언제, 그냥, 만들어, 않았, 많은, 공포, 20, 지금, 된다, 애니, 친구, 결국, 코미, 충분, 히어로, 시작, 때문, 판타, 상상, 아름다, 한국, 판타지, ㅠㅠ, 위한, 사람들, 돌아, 노래, 히어, 관객, 싶다, 만든, 누구, lt, 귀여, 뻔한, 뛰어, 얼마, 다른, 로맨, 분위기, 위해, 새로, 감정, 그래도, 자신, 좋다, 영화의, 볼만, 엄청, 되는, 여자, 봤다, 모습, 떨어, 모두, 않은, 좋았다, 얼마나, 별로, 눈물, 억지, 끝까지, 아이, 봤는데, 애니메이션, 솔직, 들어, 느껴, 아닌, th, 새로운, 찾아, 보면, 생각하, 유쾌, 풀어, 애니메이, 분위, 정도, 킬링, 드라마, 나는, 이렇, 모르겠, 전개, 나오, 봐야, 못하, 항상, 속에, 때문에, 좋아하, yo, 의미, you, 굉장, 매력적, 그런, 아니라, 봤는, 부족, 드라, 없었, 화려, 애니메, 킬링타임, 못한, 아름다운, 있을, 킬링타, 문제, 영화에, CG, ㅋㅋㅋㅋ, 등장, 만드는, 따뜻, 개인, 느낌이, 않는다, 보여주, 무엇, 싶은, 끝까, 너무나, 극장, 내내, 궁금, 디즈니, 신선, 추억, 배우들의, 남는, 어떻게, 크리스, 아쉬, 당신, 로맨스, 설정, 한다, 머리, 봐도, 명작, 멋있, 그렇, 영상, 했다, 10, 잔인, 감독의, 힘들, 취향, 솔직히, 사람이, 초반, 미국, 엄마, 크리, 가족, 세계, 부분, 개인적, 약간, 잔잔, 사랑스, 얘기, 것을, 이해, 후반, 충분히, SF, 엑스, 개인적으, 훌륭한, 스릴, 좋아하는, 디즈, 집중, 대사, 순수, 말이, 개인적으로, 것은, 무서, 따라, 선택, 강동원, 든다, 지루하, 자체, 굉장히, 언제나, 일본, 재밌게, 누군가, 하고, ㅎㅎ, 만드, 서로, 확실, 복수, 기분, 돋보, 즐거, 201, 흘러, the, 귀엽, 혼자, 천재, 훨씬, 스릴러, 완벽한, 공감, 끝나, 충격, 재밌다, 엑스맨, 멋진, 평범, 섹시, 알았, 괜찮은, 청춘, 제목, 것이다, 환상, 연기가, 나오는, 깔끔, 사랑이, 제대로, 누군, 능력, 슈퍼, 말하, 생각이, 사랑하, 믿고, 캐릭터들, 장르, 역사, 1편, 아무, 제일, 중간, 연기력, 재밌었, 사실, 한번, 과거, 유치, 특히, 성장, 상상력, 실망, 어떻, 되었, 웃음, 통해, 느끼, 죽음, 희망, ㅋㅋㅋㅋㅋ, 모르겠다, 아쉽, 스타, 포스, 어떤, B급, 않았다, 빠져, 답답, 예상, 감독이, 타란티노, 멜로, 러닝타임, 전쟁, 강동, 생각보다, 알고, 개연성, 인상, 완전, 뻔하, 없었다, 얼굴, 목소리, 인간의, 속에서, 화려한, 만들었, 미친, 동화, 이상, 결말이, 그렇게, 있었다, 되어, 아름답, 특유의, 장면이, 있어, 병맛, 벗어, 떠나, 러닝타, 추천, OS, 후반부, 놀라, 흥미로, 현실적, 단순, 킬링타임용, ost, 맘에, 보여주는, OST, 실화, 중요, 나도, 분명, 있을까, 아쉽다, 러닝, 어디, 성공, 들었, 보다, 타란티, 아니다, 시대, 소름, 포스터, 굳이, 괜찮았, 못했, 없이, 그러, 공포영화, 사랑스러, 구성, 슬프, 헐리, 연기는, 누가, 갈수록, 영상미, 스토리가, 그래서, 절대, 생각보, 마지막에, 촬영, 않고, 철학, 좀비, 캡틴, 보기, 목소, 주는, 우리는, 씁쓸, 폭력, 놀란, 광기, 바라, 예술, 기억에, 5점, 보고싶, 아직, 가슴, os, 뮤지, 듯한, 주제, 재미없, 욕망, 왠지, 운명, 설명, 지나

backward 방향 CP 상위 500개 문자열은 아래와 같습니다. (CP * 빈도수 내림차순 정렬)

지만, 으로, 에서, 는데, 적인, 하고, 하게, 하는, 지막, 화를, 처럼, ㅋㅋ, 었다, 하다, 까지, 을까, 다면, 이다, 부터, 리고, 에게, 들이, 다는, 들의, 화가, 렇게, 으면, ㅋㅋㅋ, 하지, 지는, 적으로, 보다, 이란, 만큼, 영화, 라는, 면서, 야기, 았다, 해서, 었던, 니다, 하지만, 했던, 리는, 기를, 했다, 로운, 다고, 토리, 화는, 름다운, ㅋㅋㅋㅋ, 러운, 어요, 화의, 스러운, 라고, 기가, 에겐, 수록, 리가, 니까, 다운, 리즈, 대로, ㅠㅠ, 래도, 기에, 한다, ou, 인공, ng, 는건, 니라, 기엔, 라면, 미디, 이지만, 구나, 이나, 지도, 들을, 이라, 한테, 어서, 버린, 이라는, 다가, 같은, 는게, 보단, 들은, ing, ㅋㅋㅋㅋㅋ, 하며, 었는데, er, 동안, 에도, 인데, 으나, 다니, 문에, 을때, 가는, 하여, 는다, 기도, 기는, 없이, 이고, 네요, 하면, 리를, 는지, 은데, 서도, 주는, 았던, 라도, 았는데, 으로도, 하기, 이야, 이션, 니메이션, 에선, 전히, 어야, 인가, 어낸, 일까, 이랑, 히려, 었지만, 고의, 겠다, ll, 되는, he, 메이션, 릭터, 아서, 인지, 릴러, 더라, 습니다, 했는데, 있는, 했지만, 만으로도, 나는, 였다, 로도, 러나, 어진, 이크, 세요, 로써, 어난, 우들의, 이클, 라니, 이지, 마나, 여준, 래서, 분히, 면서도, 지고, 야기를, nd, 간의, 에는, 들에게, 이었다, 화에, 도록, 번째, 는걸, 라마, ㅎㅎ, 어도, 으며, 랑스러운, 조차, 떻게, 이는, 화중, 인적으로, 는거, 오는, 토록, 나마, 스트, 이라면, 드는, 장감, 겠지만, 았지만, 었음, 무리, 이언, 이라고, 리오, 인줄, 음을, 인듯, 럭저럭, 음부터, 맨틱, 쉬운, 력적인, 기와, 저럭, 청난, 없는, 닐까, 시간, 화에서, 만한, 진다, GV, 들과, 밌게, ow, 스맨, 0년대, 적이고, 아요, 때문에, 지를, 스터, 무나, 화관에서, 동원, 아하는, 미가, 독의, 리의, 어지는, 었으면, 시절, 토리가, on, 어버린, 지컬, 형적인, 하나, 장에서, 화로, ㅠㅠㅠ, 0, ic, 함을, ㅜㅜ, 고싶다, 도로, 란티노, 으니, 거야, 지가, 간이, 직히, 리와, 여주는, 지막에, 이트, 었을까, 타임, st, 마저, 잖아, 스의, 상을, 이가, 대를, 음에, 자의, ve, 대체, 쉬움, 이첼, 치는, 력이, 저씨, 스팅, 한데, 고자, 상미, 관에서, 링타임용, 실적인, 보다는, 었다면, th, re, 지지, 을텐데, 르겠다, 하면서, 적이다, 수를, 에서도, 을듯, 티노, 음으로, 있게, 았음, 다른, 우들, 보면, 보니, 성을, 하는데, 자가, 들어, an, 반부, 제나, 년대, 당히, 나도, 서는, 니퍼, 스가, 국식, 상적인, 람이, 거나, 거운, 영화의, es, 각보다, 르는, 웠다, 타임용, 더니, 있다, 으로써, ion, 음이, 장히, 기력, 맨스, 이드, 간에, 칼렛, 감이, 는가, 야기가, 만으로, 으론, 토리는, 보고, mp, 이라니, 인공이, 이며, 함이, ck, 정을, 라서, 여운, 들어낸, 종일관, 니깐, 이자, 이빗, 함과, 미를, ST, 각이, 된다, 미있게, 억에, 시킨, 리셰, 스를, 만에, 성이, 리우드, 지의, 대한, 텐데, ed, 레딧, 실히, 간중간, E0F, tic, 니엘, 티븐, 리도, 람들이, 신의, 임용, 입니다, 아갈, 려고, 해야, 랑을, 것도, 걸까, 합니다, ㅠㅠㅠㅠ, 학교, 면이, 프닝, 하긴, 스럽다, 쉽다, 15, 까운, 미로운, 정이, 해도, 랑하는, 웠던, ver, 에서는, 감을, 인의, 해요, 야할, 리에, 구하고, 쾌한, 나서, 나리오, 야지, 물이, 럼에도, 일관, 겠지, 들어진, ㄷㄷ, 번쯤, 해지는, 무나도, 에서의, 로는, 분이, 작을, 보는, 한다면, 영화를, 15, 우드, 더라면, ay, ove, 라이언, 간을, 졌다, 인공의, 리스토퍼, 직도, 들었다, 독이, 신이, 다는걸, 사가, 주인공, 이의, 렸다, 0F, 점을, 리지, 각하게, 하면서도, 력을, stic, ly, 준다, 사를, 벽한, 아온, 어가는, 정한, 서운, 화였다, 독님, 릴때, 중에, 화다, 한듯, 설픈, 해진, 토리를, 국판, 트맨, 이라도, 면은, 르게, hing, 나고, 하고자, 764

코드

김현중 박사과정이 작성한 CP 코드를 사용했습니다. 저 역시 정리 용도로 남긴 것이니 문제되면 바로 삭제하겠습니다. 최신 코드는 김현중 박사과정의 깃헙 https://github.com/lovit/soy을 참고하시기 바랍니다.

사용법은 아래와 같습니다. 아래 코드에서 CohesionTokenizer 역시 김현중 박사과정이 만든 코드로 말뭉치에서 학습한 CP를 바탕으로 문장을 토큰으로 나눠주는 함수입니다.

import cohesion_probability as tool
cohesion = tool.CohesionProbability()
cohesion.train(reviews)
cohesiontokenizer = tool.CohesionTokenizer(cohesion)
cohesion_tokenized_reviews = [cohesiontokenizer.tokenize(review) for review in reviews]




Comments