단순 공기어 통계 vs Word2Vec를 이용한 관련어 추출

Posted by 적분 ∫2tdt=t²+c
2016.12.09 20:38 그냥 공부

저번에 라틴어 사전에 관련어를 추출하기 위해 공기어(cooccurence) 빈도를 지지고 볶는 작업을 했었습니다. (관련 포스팅: http://bab2min.tistory.com/533) 하지만 같은 문장에 자주 같이 등장한다고 해서 둘의 의미가 항상 같을 것이라고 기대할 수는 없습니다. 같이 등장하지만 크게 상관없는 단어도 있을수 있고... 단순 공기어 빈도를 가지고 통계적 처리를 한 결과는 여러모로 한계점이 있을수 밖에 없죠.


세상이 많이 발전해서 통계적 기법으로 언어를 처리하는 새로운 기술들이 등장했는데요, 대표적인게 Word2Vec이라는 겁니다. 단어들을 N차원 벡터 공간에 매핑함으로써(당연히 비슷한 단어일수록 가깝게, 다른 단어일수록 멀리 위치하도록 매핑해야겠죠) 단어간의 유사도나 관계를 쉽게 파악할수 있도록 하는 기법입니다. 관련 수학이론은 좀 복잡하지만 훌륭하신 거인들이 이미 많이 라이브러리화 해놓았기 때문에, 우리들은 거인의 어깨 위에서 쉽게 이것저것 가지고 놀아볼 수 있습니다.


Word2Vec 라이브러리 중 쉽게 사용할 수 있는게 Python 버전으로 나온 gensim 라이브러리일것입니다. 단어 배열(=문장)을 차례로 입력해주면 사전을 구축하고, 학습을 하여 해당 단어들을 특정 차원의 공간으로 매핑해줍니다. 관련 내용은은 http://blog.theeluwin.kr/post/146591096133/%ED%95%9C%EA%B5%AD%EC%96%B4-word2vec 를 참조하시면 됩니다. 


글을 살펴보니깐 시험삼아 사용해보기도 어렵지 않을듯하여 한 번 어떤 결과가 나오나 써보기로했습니다. 


라틴어 단어를 학습시켜보자

준비물

* 분석된 코퍼스(많으면 많을 수록 좋음)

* 시간, 인내, 끈기, 열정

* Python + gensim 패키지


수동 및 자동 태깅을 통해 분석된 약 40만 개의 라틴어 문장이 있으니 코퍼스는 해결되었고, 시간은 많은데 끈기 열정은 있는지 모르겠네요. 사실 40만 문장이면 굉장히 작은 코퍼스에 속하는데 이런 걸로 제대로된 결과가 나올까 걱정도 많이 되더라구요. 규모가 작아서 그런지 학습은 몇 분 만에 금방 끝났습니다.


파라미터

* 코퍼스 내 유효한 단어는 약 12,000개

* 매핑 차원은 25, 50, 75, 100, 200 등 여러가지를 시도해 봄

* 학습반복횟수: 10회

* 알고리즘: CBOW


사실 어떤 파라메터가 어떻게 영향을 미치는지 정확하게 몰라서 차원만 바꿔가면서 테스트해 보았습니다. 간단하게 결과를 정리하면 차원숫자가 낮을수록 처리가 빠르고(당연한 소리!), 단어 간 유사도가 높게 측정됩니다. 즉 변별력이 좀 낮아진다는 거지요. 차원 숫자가 높을 수록 오래걸리지만, 단어 간 유사도가 낮아집니다. 변별력이 높아지는데, 차원을 계속 키운다고 무한정 올라가지는 않습니다. 적당한 수준이 있을텐데 그게 어디쯤일지는 코퍼스나 언어특성에 따라 다르겠지요.

디폴트 값으로 100을 많이 주는데, 실험해본 결과 코퍼스 크기가 작아서 그런지 100차원이나 50차원이나 유의어/관련어를 추출하는데는 크게 변별력 차이가 없어서 50차원으로 학습했습니다.


유의어 추출은 벡터 간 코사인 유사도를 통해 쉽게 계산할수 있습니다. 만약 두 단어 벡터가 정규화되어있다면 단순히 내적을 구하는 것만으로도 유사도를 구할수 있지요. 그 덕분인지 학습이 끝난 뒤, 유사도 추출은 굉장히 빠르게 마무리되었습니다.


단순 공기어 빈도 통계와는 어떻게 다를까?

몇몇 단어의 예를 들어서 공기어 통계와 Word2Vec 벡터 매핑의 관련어 추출이 어떤 차이가 있는지 살펴보지요.

고빈도어

1. Aqua (물)
Collocation Stat.
Word의미Z
calidus(따뜻한, 따뜻하게 느껴지는, 훈훈한)90.6912
dēcoquō(끓다, 거품이 일다, 끓이다)68.3465
frīgidus(추운, 차가운, 으슬으슬 추운)67.9737
bibō(마시다)60.3087
foveō(따뜻하게 하다, 덥히다, 기르다)52.5454
fōns(샘, 분수, 샘물)52.1842
verbēna(잎, 나뭇잎 )34.6802
mulsum(달콤한 와인)33.7039
spongia(스폰지, 해면, 스폰지 모양의 물건)33.6926
pōtus(마실 것, 음료, 한 모금)33.1311


Word2Vec Simil.
Word의미유사도
alveus(구멍, 동공, 깊은 구멍)0.58093
amnis(강, 바다, 하천)0.54576
abyssus(심해, 심연, 밑바닥)0.54457
aestus(열, 온기, 불)0.52561

공기어 통계에서는 굉장히 관련어를 많이 뽑아내는 반면, 벡터매핑에서는 엉뚱한 것을 뽑아내고 있습니다. 다양한 맥락에서 등장하다보니 학습이 제대로 안되었거나, 혹은 파라메터 설정이 잘못되었을수 있죠.



2. Possum (할 수 있다)

Collocation Stat.
Word의미Z
nōn(아닌)67.7212
nec(~또한 아니다, 그리고 ~않다, ~아니다)49.4688
(만약, 만일)37.3538
sine( ~없이)31.361
ut(~해서, ~하기 위하여)31.0231
quod(~는데, 왜냐하면, ~때문에)30.2091
nisi(~하지 않는다면, ~를 제외하고)29.1299
nihil(아무 )27.888
percipiō(떠맡다, 장악하다; 가정하다, 추정하다; 벌다)27.661
cōnsequus(다음, 다음의)26.8007


Word2Vec Simil.
Word의미유사도
dēbeō(~할 의무가 있다, 반드시 ~해야하다)0.70212
facilis(쉬운, 편한, 수월한)0.66336
omnīnō(전체적으로, 모두 함께, 전적으로)0.64785
oporteō(요구하다, 명령하다)0.64306
nequeō(무능하다, ~할 수 없다)0.61951
magnopere(대단히, 몹시, 크게)0.60819
nisi(~하지 않는다면, ~를 제외하고)0.60131
crēdibilis(믿을 수 있는, 신용할 수 있는, 있을 법한)0.55582
oportet(필요하다, 필수적이다, 적절하다 )0.54717
arbitror(재판하다, 판결을 내리다, 심리하다)0.54602

공기어 통계에서는 사실상 불용어들이 대부분을 차지하고 있습니다만, 벡터 매핑에서는 그래도 그나마 의미상 관련있는 단어들이 추출되었습니다.



3. Pater (아버지, 귀족/의원 등의 존칭)

Collocation Stat.
Word의미Z
cōnscrīptus(의원, 고문, 상담자)67.3937
fīlius(아들, 남자 자손 , 아이 )57.4867
plēbs(평민, 대중, 인민)43.6552
māter(어머니, 근원, 가정부장)35.9792
avus(할아버지, 조상, 노인)27.8012
frāter(형제, 친구, 애인)22.7317
familia(가족, 식구, 가구)21.8301
nātus(탄생, 나이, 연령)21.7684
meus(나의, 내)21.3479
līberī(아이들, 어린이들, 자유민들)21.2164


Word2Vec Simil.
Word의미유사도
frāter(형제, 친구, 애인)0.80777
pārēns(순종하는, 충실한, 유순한)0.78733
nepōs(손자, 외손자, 손녀)0.74312
parēns(부모, 아버지, 아버지)0.73006
fīlia(딸, 막내, )0.71752
fīlius(아들, 남자 자손 , 아이 )0.71375
māter(어머니, 근원, 가정부장)0.70581
līberī(아이들, 어린이들, 자유민들)0.67715
adoptō(선택하다, 고르다, 채용하다)0.65801
hērēs(상속자, 상속인, 후계자)0.65712

pater라는 단어가 의원들을 부리는 존칭으로 쓰였다는 걸 가정하면 공기어 통계의 추출결과도 납득가능합니다. 다만 벡터 매핑의 결과가 좀더 보편적인 의미의 pater를 잘 집어낸듯하군요.


중빈도어

1. cibus (음식)

Collocation Stat.
Word의미Z
pōtio(마시기, 음용, 음주)106.174
assūmō(수여받다, 받다, 채용하다)63.9053
febris(열, 오한)49.9264
abstineō(삼가다, 절제하다, 거리두다)47.9412
vīnum(와인, 술, 포도)44.3458
fastīdium(질색, 반감, 증오)39.2674
merācus(희석하지 않은, 물 타지 않은, 산뜻한)32.4414
frictiō(탈곡, 마사지)32.0011
balneum(목욕, 욕실, 욕조)30.5049
austērus(쓴, 시큼한, 떫은)29.1561


Word2Vec Simil.
Word의미유사도
abstinentia(절제, 금욕, 단식)0.68715
balineum(목욕, 욕실, 욕조)0.65285
balneum(목욕, 욕실, 욕조)0.62253
alimentum(음식, 영양분, 영양)0.60055
calefaciō(가열하다, 덥히다, 뜨겁게 하다)0.59645
carnis(고기, 살점, 몸체)0.53878
calor(따뜻함, 적당한 온도, 열)0.53694
bibō(마시다)0.53254
acēscō(시큼해지다, 쉬다)0.5195
austērus(쓴, 시큼한, 떫은)0.51135

음식과 연관있는 먹고 마시는 단어가 많이 등장합니다.  양쪽 모두 목욕이라는 단어가 등장하는데, 목욕탕 내에서 다과를 즐겼던 로마 문화를 본다면 충분히 납득가능합니다.


2. misereo(슬퍼하다)


Collocation Stat.
Word의미Z
miseror(한탄하다, 슬퍼하다, 슬프다)22.9907
parcō(삼가다, 그만두다, 자제하다)19.0808
(너)14.4547
ego(나)14.164
clāmō(외치다, 떠들어대다, 소리치다)13.6136
dominus(주인, 집주인, 지배자)12.6518
misericordia(연민, 동정, 자비)10.8054
pudeō(부끄럽다, 창피하다)10.7404
ōrō(연설하다, 웅변하다, 말하다)10.7339
et(그리고, ~와, 더하기)9.32274


Word2Vec Simil.
Word의미유사도
invideō(옆눈으로 보다, 째려보다, 악의를 가지고 보다)0.74842
īgnōscō(용서하다, 면제하다)0.65793
maledīcō(씹다, 저주하다, 마법을 걸다)0.65592
amō(사랑하다, 좋아하다, ~해야만 하다)0.63901
exōrō(납득시키다, 설득하다, 애원하다)0.63457
dēfleō(눈물을 쏟아내다, 한탄하다, 우느라 둔해지다)0.63222
memor(염두하는, 기억하는, 좋은 기억을 가진)0.62687
heu!(아이고, 참, 아니)0.61844
lūgeō(슬퍼하다, 비통해하다, 애도하다)0.61321
āmēs(기둥, 폴란드인, 포크 모양의 막대)0.60923


공기어 통계에서는 불용어가 많이 등장하는 반면, 벡터매핑에서는 그런게 없습니다. 



3. nix (눈 snow)


Collocation Stat.
Word의미Z
imber(비, 폭풍우, 폭풍)32.877
candidus(빛나는 흰색의, 하얀, 흰)27.9848
frīgus(추위, 냉기, 차가움)22.6096
hiems(겨울)19.6566
mōns(산, 산악)17.9774
sōl(해, 태양)11.2576
aqua(물)11.1853
solutus(매지 않은, 속박에서 풀려나온, 자유의 몸인)10.4373
sīdus(별자리, 별, 밤하늘)9.83614
ventus(바람, 강풍)9.64179


Word2Vec Simil.
Word의미유사도
glaciēs(얼음, 빙하, 견고)0.87482
aquōsus(축축한, 물기가 있는, 젖은)0.84071
imber(비, 폭풍우, 폭풍)0.84032
gelus([[gelu]])0.8323
gelū(결빙, 결상, 서리)0.81195
brūma(동지, 겨울, 겨울의 추위)0.79252
nivālis(눈 오는, 눈 내리는, 눈 덮인)0.78889
nebula(안개, 구름, 증기)0.78685
imbrifer(비를 가져오는, 비를 내리는)0.78662
āreō(마르다, 바싹 마르다, 시들다)0.78213


공기어 통계에서는 말그대로 눈과 같이 등장할 만한 단어들이 나열되는 반면, 벡터 매핑에서는 좀더 의미상으로 연관있는 것들이 나옵니다. 



저빈도어


1. lodix (침대보)


Collocation Stat.
Word의미Z
nec(~또한 아니다, 그리고 ~않다, ~아니다)7.73179


Word2Vec Simil.
Word의미유사도
effectiō(성취, 달성, 업적)0.83741
illoc(거기에, 저쪽에, 저기에)0.82082
capsella(작은 상자, 금고)0.81319
allēgoricus(우화적인, 두 의미를 지니는)0.79531
concaleō(아주 뜨거워지다, 더워지다)0.792
assertor(주장자, 확언자, 고집자)0.78728
hospitāle(병원, 객실, 접대실)0.78702
antevertō(기대하다, 고대하다, 선호하다)0.77738
cacoēthes(악성 질병, 열광, 마니아)0.77681
deliquō(밝히다, 켕기다, 명백하게 하다)0.77638

등장 빈도가 적어 공기어 통계 기법에서는 불용어 밖에 추출되지 않았고, 벡터 매핑에서는 관련없는 단어들이 나옵니다.


2. melinus(꿀의, 꿀에 관한)


Collocation Stat.
Word의미Z
vel(~와, 또는, 그리고)22.5525


Word2Vec Simil.
Word의미유사도
corallium(산호)0.93685
hebenus(흑단, 칠흑)0.91987
fūlīgo(검댕, 그을음)0.91961
alūmen(명반, 백반, 칼륨명반)0.90394
ammoniacum(암모니아수, 암모니아)0.89963
cicūta

(독미나리, 독미나리의 줄기로 만든 플룻)

0.89309
crocum(크로커스, 사프란)0.89214
anserīnus(거위의, 기러기의)0.88936
aloē

(알로에,)

0.88928
ligustrum(쥐똥나무)0.88751


마찬가지.


3. permano (침투하다, 스미다)


Collocation Stat.
Word의미Z
per( ~를 통하여, ~동안)7.10937
quīdam(누군가, 어떤 것, 무엇인가)6.58513


Word2Vec Simil.
Word의미유사도
penetrābilis(통행 할 수 있는, 침입할 수 있는, 꿰뚫는)0.75921
hiulcus(솔직한, 개방적인, 거리낌없는)0.75453
excantō(매혹하다, 요술을 걸다)0.75369
mollitūdō(유연성, 유순, 부드러움)0.74931
palpitō(설레다, 떨리다, 떨다)0.74365
innōdō(묶다, 얽다, 매다)0.74294
effluō(탈출하다, 도망치다, 달아나다)0.74097
īnfluō(, 흐르다, 솟다)0.73632
exhālō(내쉬다, 숨을 내쉬다)0.72887
bulliō(거품일게 하다, 끓이다)0.72813

벡터 모델에서는 일부 유사한 단어를 뽑아냈습니다.



정리해보자면

대체적인 경향으로보면 학습이 잘되었을 경우 Word2Vec에서 좀더 의미적으로 관련있는 단어를 뽑아낸다는 것을 알 수 있습니다. 고빈도일수록 벡터 모델에서는 유사도가 낮아지는 반면, 공기어 통계에서는 Z값이 높아집니다. 저빈도에서는 오히려 벡터 모델이 유사도가 높아져 불필요한 단어를 많이 뽑아내지만, 공기어 통계에서는 거의 아무것도 뽑아내지 못합니다.


고빈도, 중빈도, 저빈도 모든 경우에서 평균적으로 Word2Vec 모델의 관련어 추출이 더 의미있는 결과를 보여준다고 생각하여 라틴어 사전의 관련어 디비를 해당 모델을 적용한 것으로 교체하였어요! 뭐 별차이 없어보일지 몰라도 괜히 스스로 흡족하네요. 분포를 기반으로 하는 모델이 좋은 점은 진짜로 그냥 문장이 모여있는 코퍼스만 있어도 그 안에서 단어의 의미를 어느정도 추론할 수 있다는거죠. 별 다른 처리 없이도 이렇게 관련어 추출을 어느정도 해냈으니까요.

그러니깐 gensim 만세! 파이썬 만세!

저작자 표시 비영리 동일 조건 변경 허락
신고
이 댓글을 비밀 댓글로