본문 바로가기

카테고리 없음

(자연어처리) 어떤 형태소 분석기를 사용할 것인가?

형태소 분석기 여섯 가지 중 어떤 형태소 분석기를 사용할 것인지, 선택 기준을 내 나름대로 정해본다.

 

1) 형태소 분석 실행 시간

Khaiii(이하 '카이')는 실전에서 Mecab과 비슷한 속도를 보였다. 3M 바이트 한글 텍스트 파일을 형태소 분석했는데 몇 분 정도가 걸렸다. 아주 느린 형태소 분석기는 성능과 상관없이 실전에 투입하기가 곤란할 것이다. 형태소 분석에만 몇 시간씩 걸린다면 답답해서 어떻게 사용할까. 하지만 성능이 좋다면, 지나치게 느리지만 않다면 사용해볼 만하다.

 

2) 성능

형태소 분석을 얼마나 꼼꼼하게 하는지, 정확하게 하는지, 국어사전의 띄어쓰기를 준수하는지를 살펴볼 것이다.

가령 '어디로인가'와 '어디론가'를 형태소 분석했을 경우, 같은 결과가 나와야 한다. '어디', '로', '이', 'ㄴ가'로 분석되어야 한다.

 

3) 다 붙여놓은 한글을 형태소 분석하는 실력은 검증하지 않는다.

'아버지가방에들어가신다', '추돌하는차옆구리가찢기고파란혈액이흐른다' 와 같은 띄어쓰기 없는 문장을 형태소 분석하는  실력은 성능 평가에 넣지 않을 생각이다. 그 이유는, '제대로 띄어쓴 문장 만들기'를 제일 목표로 하는 모듈들이 파이썬용으로 나온 게 몇 종 있기 때문에, 필요하다면 띄어쓰기 모듈을 통해 '제대로 띄어쓴' 다음 형태소 분석기를 적용하면 될 것이기 때문이다.

 

4) 고유명사, 복합 명사를 판단하는 능력을 살펴본다. 복합 명사의 경우, 국어 사전 기준으로 띄어써서 형태소 분석을 하는지 살펴본다.

 

5) Khaiii는 morphs와 pos 메서드를 지원하지 않아, 필자가 별도로 만들어서 함수로서 사용한다. 그리고 카이에는 base model과 large 모델이 있는데, 성능이 한결 나은 large 모델을 사용한다.

 

아래 글에서 카이의 사용법을 설명하면서 함수를 작성해서 사용하는 법을 예시해뒀으니 참고하기 바란다.

https://madrabbit7.tistory.com/73

 

(딥러닝/자연어 처리) 형태소 분석기 Khaiii 사용법: Base 모델 vs Large, 오류 대처, morphs/pos 함수 만

1) Khaiii 설치 카카오의 형태소 분석기인 Khaiii 설치에 애를 먹었다. 데스크탑B는 i7 3770에 우분투 21.04, 우분투 20.04를 번갈아 설치했지만 Khaiii 설치에 실패했다. 노트북C에는 페도라 34가 설치되어

madrabbit7.tistory.com

 

1. 속도와 기본 분석

 

from konlpy.tag import Hannanum
from konlpy.tag import Kkma
from konlpy.tag import Komoran
from konlpy.tag import Mecab
from konlpy.tag import Okt
from util import *
import time

hannanum = Hannanum()
kkma = Kkma()
komoran = Komoran()
mecab = Mecab()
okt = Okt()

#sentence = "홀로 우뚝 선 저 바위 칭얼대는 파도에 가려 숨어있는지 꽁꽁언 겨울바다 꼭 입을 다문다 포말은 일렁이고 산다는 건 다 그런 거다"
#sentence = "비 개인 오후 다섯 시 딱딱해진 것을 가져본 적 없는 지렁이가 납작하게 죽어 있다 내가 밟아 죽였는지는 기억나지 않는다 옹송그리며 지렁이의 몸에 새카맣게 들러붙은 똥파리들 잘 차려진 식사 중이다"
#sentence = "동태가 생태보다 무서운 것은 토막 난 몸으로도 눈을 뜨고 있다는 사실이다 조문객의 눈을 뚫어지게 바라보는 사후의 눈 내 살 누가 파먹나 사력을 다해 노려본다는 것이다"
sentence = "추돌한 차 옆구리가 찢기고 파란 혈액이 흐른다 네 잘못이 내 잘못인양 덩치 큰 차에 묶여 끌려가는 뒷 모습 인생도 어디론가 끌려가고 있다"
#sentence = "뱀이 왜 기어 다니는지 아세요 불안하기 때문이래요 손발 없이 귀머거리로 사는 동물은 또 없거든요 독이라도 품어야 살 수 있지 않겠어요 얼마나 불안했으면 혀가 다 갈라졌겠어요"
#sentence = "정동진에는 해가 없다 비는 있다 배는 산으로 가고 기차는 바다 속으로 들어간다 아이들은 포효하는 바다 속으로 뛰어들고 강은 산으로 흐르고 철조망은 바다를 덮치고 바다는 철조망을 삼키고 모래시계는 거꾸로 흐른다"
#sentence = "그는 언덕을 달려 내려가다가 발을 헛디뎌 땅바닥에 곤두박질쳤다."
#sentence = "다리 밑에 지게 받혀놓은 농부들"
#sentence = "다리 밑에 지게를 받혀놓은 농부들"


print("-------------- Hannanum ------------")
start = time.time()
print(hannanum.morphs(sentence))
print("걸린 시간: ", time.time() - start )

print("-------------- Kkma ------------")
start = time.time()
print(kkma.morphs(sentence))
print("걸린 시간: ", time.time() - start )


print("-------------- Komoran ------------")
start = time.time()
print(komoran.morphs(sentence))
print("걸린 시간: ", time.time() - start )

print("-------------- Mecab ------------")
start = time.time()
print(mecab.morphs(sentence))
print("걸린 시간: ", time.time() - start )

print("-------------- Okt ------------")
start = time.time()
print(okt.morphs(sentence))
print("걸린 시간: ", time.time() - start )

print("-------------- Khaiii ------------")
start = time.time()
print(khaiii_morphs(sentence))
print("걸린 시간: ", time.time() - start )

-------------- Hannanum ------------
['추돌한', '차', '옆구리', '가', '찢기', '고', '파랗', '은', '혈액', '이', '흐르', 'ㄴ다', '네', '잘못', '이', '내', '어', '잘못', '이', 'ㄴ', '양', '덩치', '크', 'ㄴ', '차', '에', '묶이', '어', '끌리', '어', '가', '는', '뒷', '모습', '인생', '도', '어디론', '가', '끌리', '어', '가', '고', '있', '다']
걸린 시간:  0.4540975093841553
-------------- Kkma ------------
['추돌', '하', 'ㄴ', '차', '옆구리', '가', '찢기', '고', '파랗', 'ㄴ', '혈액', '이', '흐르', 'ㄴ다', '네', '잘못', '이', '내', '잘못', '인양', '덩치', '크', 'ㄴ', '차', '에', '묶이', '어', '끌려가', '는', '뒷', '모습', '인생', '도', '어디', '론', '가', '아', '끌려가', '고', '있', '다']
걸린 시간:  3.2326290607452393
-------------- Komoran ------------
['추돌', '하', 'ㄴ', '차', '옆구리', '가', '찢기', '고', '파란', '혈액', '이', '흐르', 'ㄴ다', '네', '잘못', '이', '내', '잘못', '이', 'ㄴ', '양', '덩치', '크', 'ㄴ', '차', '에', '묶이', '어', '끌려가', '는', '뒷', '모습', '인생', '도', '어디', '론', '가', '끌려가', '고', '있', '다']
걸린 시간:  0.008737325668334961
-------------- Mecab ------------
['추돌', '한', '차', '옆구리', '가', '찢기', '고', '파란', '혈액', '이', '흐른다', '네', '잘못', '이', '내', '잘못', '인양', '덩치', '큰', '차', '에', '묶여', '끌려가', '는', '뒷', '모습', '인생', '도', '어디', '론가', '끌려가', '고', '있', '다']
걸린 시간:  0.0005948543548583984
-------------- Okt ------------
['추돌', '한', '차', '옆구리', '가', '찢기고', '파란', '혈액', '이', '흐른다', '네', '잘못', '이', '내', '잘못', '인양', '덩치', '큰', '차', '에', '묶여', '끌려가는', '뒷', '모습', '인생', '도', '어디', '론', '가', '끌려가고', '있다']
걸린 시간:  2.5520451068878174
-------------- Khaiii ------------
['추돌', '하', 'ㄴ', '차', '옆구리', '가', '찢기', '고', '파랗', 'ㄴ', '혈액', '이', '흐르', 'ㄴ다', '너', '의', '잘못', '이', '나', '의', '잘못', '이', 'ㄴ', '양', '덩치', '크', 'ㄴ', '차', '에', '묶이', '어', '끌려가', '는', '뒷', '모습', '인생', '도', '어디', '로', '이', 'ㄴ가', '끌려가', '고', '있', '다']
걸린 시간:  0.01009988784790039

 

****

실행 시간을 보면, 짧은 문장 몇 개 분석하는 데 Okt, Kkma는 2~3초가 걸리고, Hannanum도 0.45초가 걸린다. 이런 문장을 수만 개 분석해야 할 일도 있는데, Mecab이 성능이 제일 좋고,  Komoran과 Khaiii가 그 뒤를 따른다.

 

*** 

1)  '추돌한'의 원형은 '추돌'으므로 '추돌','하','ㄴ'으로 분석되는 게 옳아 보인다. Kkma, Komoran, Khaiii가 옳게 분석했다. '추돌했던'이라는 문장을 만나면 각 분석기들는 다음과 같은 결과를 내놓는다.

Hannanum: '추돌했던'

Kkma: '추돌', '하', '었', '더', 'ㄴ'

Komoran: '추돌', '하', '았', '던'

Mecab: '추돌', '했', '던'

Okt: '추돌', '했던'

Khaiii: '추돌', '하', '였', '던'

 

'추돌했던'은 '추돌하였던'이 되고, '추돌'(원형), '하'(동사형), '였'(과거형), '던' 이 되는 게 무난해 보인다. Hannanum은 아예 분석 시도를 안 했고, Kkma는 형태소 분석 정석을 보여주는 듯하다(하지만 속도가 너무 느린 게 문제다). Komoran은 '았'이 아닌 '었'이었으면 좋았을 텐데. Mecab은 제법 무난하지만 자모 단위로 분석을 하지 않기 때문에 형태소 분석 정석에 가깝다고는 보기 힘들다. 

Mecab:  '추돌하였던' => '추돌','하','였','던'

              '추돌했다더라' => '추돌', '했', '다더라'

'하였'과 '했'은 같은 것인데 Mecab은 다르게 분석한다.

 

-- '어디론가'도 '어디로인가'이므로 '어디','로','이','ㄴ가' 로 분석한 것은 카이가 유일하다. '어디','론','가' 나 '어디','론가'로 5개 분석기가 분석했고, 유일하게 카이만 제대로 풀어냈다.

 

2) 고유명사와 복합 명사

 

sentence = "어제 정동진에 갔다. 정동진에는 해가 없다. 수락산자락에 핀 산유화로 태어나고 싶다. 겨울산 가을단풍에 맺힌 여름열매를 흔드는 봄바람의 여름바다"

 

-------------- Hannanum ------------
['어제', '정동진', '에', '가', '아다', '.', '정동진', '에는', '하', '어', '가', '아', '없', '다', '.', '수락산자락', '에', '피', 'ㄴ', '산유화', '로', '태어나', '고', '싶', '다', '.', '겨울산', '가을단풍', '에', '맺히', 'ㄴ', '여름열매', '를', '흔들', '는', '봄바람', '의', '여름바다']
걸린 시간:  0.4141871929168701
-------------- Kkma ------------
['어제', '정동', '진', '에', '가', '었', '다', '.', '정', '동진', '에', '는', '해', '가', '없', '다', '.', '수락산', '자락', '에', '핀', '산유화', '로', '태어나', '고', '싶', '다', '.', '겨울', '산', '가을', '단풍', '에', '맺히', 'ㄴ', '여름', '열매', '를', '흔들', '는', '봄바람', '의', '여름', '바다']
걸린 시간:  3.4130589962005615
-------------- Komoran ------------
['어제', '정동진', '에', '가', '았', '다', '.', '정동진', '에', '는', '해', '가', '없', '다', '.', '수락산', '자락', '에', '피', 'ㄴ', '산유화', '로', '태어나', '고', '싶', '다', '.', '겨울', '산', '가을', '단풍', '에', '맺히', 'ㄴ', '여름', '열매', '를', '흔들', '는', '봄바람', '의', '여름', '바다']
걸린 시간:  0.007587909698486328
-------------- Mecab ------------
['어제', '정동진', '에', '갔', '다', '.', '정동진', '에', '는', '해', '가', '없', '다', '.', '수락', '산자락', '에', '핀', '산유화', '로', '태어나', '고', '싶', '다', '.', '겨울', '산', '가을', '단풍', '에', '맺힌', '여름', '열매', '를', '흔드', '는', '봄바람', '의', '여름', '바다']
걸린 시간:  0.0017685890197753906
-------------- Okt ------------
['어제', '정동진', '에', '갔다', '.', '정동진', '에는', '해', '가', '없다', '.', '수락산', '자락', '에', '핀', '산유화', '로', '태어나고', '싶다', '.', '겨울', '산', '가을', '단풍', '에', '맺힌', '여름', '열매', '를', '흔드는', '봄바람', '의', '여름', '바다']
걸린 시간:  2.2604751586914062
-------------- Khaiii ------------
['어', '제', '정동진', '에', '가', '았', '다', '.', '정동진', '에', '는', '해', '가', '없', '다', '.', '수락', '산', '자락', '에', '피', 'ㄴ', '산유화', '로', '태어나', '고', '싶', '다', '.', '겨울', '산', '가을', '단풍', '에', '맺히', 'ㄴ', '여름', '열매', '를', '흔들', '는', '봄바람', '의', '여름바다']
걸린 시간:  0.018638134002685547

 

** Kkma는 '정동진'이라는 고유명사를 인식 못하고 있다. 대신 '수락산'을 인식한다.

** Khaiii는 제일 앞 단어인 '어제'를 '어','제'로 인식한다. 사실 이런 경향 때문에 일부 사용자들은 카이에게 불평을 터뜨리며 카이를 떠난다. '나는 어제 정동진에 갔다'를 분석시키면 '어제'를 제대로 인식한다. 즉, '어제' 앞에 다른 단어가 있으면 잘 맞춘다. 분석 대상 음절 앞에 띄어쓰기 된 다른 단어가 있다면 앞 단어의 형태소 분석을 통해 해당(뒷) 단어의 형태소 분석 정확도를 높이는 방식으로 CNN 알고리즘을 이용하기 때문에 발생하는 것으로 보인다. 문장의 첫 단어의 경우, 딥러닝 방식이 아니라 사전 참고 방식으로 분석하면 그 단어에 대한 형태소 분석 정확도를 높일 수 있을 것 같다.

** '수락산자락'을 카이는 '수락','산','자락'으로 나누었는데 수락산을 고유명사로 인식 못하고 있다.

** '정동진'과 '수락산'을 모두 인식하여 제대로 분리해낸 분석기는 코모란과 Okt다.

** '겨울산', '가을단풍', '여름열매', '여름바다'는 모두 띄어써야 하는 복합명사들이고, 사전에 없는 단어들이다. 즉, '겨울'+'산', '가을'+'단풍', '여름'+'열매', '여름'+'바다'로 나누어서 형태소 분석을 해야 한다. '봄바람'은 국어사전에 있는 단어로 분리해서는 안 된다. 카이는 '여름바다'를 제외하고 나머지는 다 맞추었다(4/5).    Okt는 모두 맞추었다(5/5). Mecab도 5/5. Komoran, Kkma도 모두 5/5. Hannanum은 0/5로 복합명사를 하나도 분리해내지 않았다. 

 

형태소 분리한 것으로 단어 사전을 만들게 되는데, 단어사전에 들어간 명사들은 국어 사전에 들어 있던 명사들과 같을수록 좋다. '바다', '산', '여름', '겨울', '봄', '가을' 의 여섯 개 단어로 총 8개의 복합 명사를 만들 수 있다. 여름바다, 여름산, 겨울바다, 겨울산, .... 사전에 없는 복합 명사 사이는 띄어쓰는 게 옳다.

 

3) 헷갈리는 품사

sentence = "다리 밑에 지게 받혀놓은 농부들"

 

-------------- Hannanum ------------
['다리', '밑', '에', '지', '게', '받히', '어', '놓', '은', '농부들']
걸린 시간:  0.5139782428741455
-------------- Kkma ------------
['다리', '밑', '에', '지게', '받히', '어', '놓', '은', '농부', '들']
걸린 시간:  3.74721097946167
-------------- Komoran ------------
['다리', '밑', '에', '지', '게', '받히', '어', '놓', '은', '농부', '들']
걸린 시간:  0.004818916320800781
-------------- Mecab ------------
['다리', '밑', '에', '지', '게', '받혀', '놓', '은', '농부', '들']
걸린 시간:  0.008713006973266602
-------------- Okt ------------
['다리', '밑', '에', '지게', '받혀놓은', '농부', '들']
걸린 시간:  2.1957383155822754
-------------- Khaiii ------------
['다리', '밑', '에', '지', '게', '받히', '어', '놓', '은', '농부', '들']
걸린 시간:  0.007855653762817383

 

'지게'라는 단어는 '지게'라는 명사이기도 하지만 '억울해지게', '뜸해지게'와 같이 동사 뒤에 붙어 피동 역할을 한다. 위에서는 명사로 사용되었다.

Kkma와 Okt가 맞혔고, 나머지는 모두 틀렸다. 

 

sentence = "다리 밑에 지게를 받혀놓은 농부들"

 

'지게'의 품사를 명확히 하기 위해 '지게를'로 바꿔놓으면 모두 잘 분석한다.

 

-------------- Hannanum ------------
['다리', '밑', '에', '지게', '를', '받히', '어', '놓', '은', '농부들']
걸린 시간:  0.30744385719299316
-------------- Kkma ------------
['다리', '밑', '에', '지게', '를', '받히', '어', '놓', '은', '농부', '들']
걸린 시간:  3.409492015838623
-------------- Komoran ------------
['다리', '밑', '에', '지게', '를', '받히', '어', '놓', '은', '농부', '들']
걸린 시간:  0.0036394596099853516
-------------- Mecab ------------
['다리', '밑', '에', '지게', '를', '받혀', '놓', '은', '농부', '들']
걸린 시간:  0.0014653205871582031
-------------- Okt ------------
['다리', '밑', '에', '지게', '를', '받혀놓은', '농부', '들']
걸린 시간:  2.0185399055480957
-------------- Khaiii ------------
['다리', '밑', '에', '지게', '를', '받히', '어', '놓', '은', '농부', '들']
걸린 시간:  0.011444091796875

 

* '받혀놓은'은 '받히어놓은'이므로 Mecab과 Okt를 제외하고는 제대로 분석하고 있다.

 

4)  기타

 

sentence = "홀로 우뚝 선 저 바위 칭얼대는 파도에 가려 숨어있는지 꽁꽁언 겨울바다 꼭 입을 다문다 포
말은 일렁이고 산다는 건 다 그런 거다"

 

-------------- Hannanum ------------
['홀로', '우뚝', '서', 'ㄴ', '저', '바위', '칭얼대', '는', '파도', '에', '가리', '어', '숨', '어', '있', '는지', '꽁꽁언', '겨울바다', '꼭', '입', '을', '다물', 'ㄴ다', '포말', '은', '일렁이', '고', '사', 'ㄴ다는', '거', '은', '다', '그러', 'ㄴ', '거', '이', '다']
걸린 시간:  0.42502570152282715
-------------- Kkma ------------
['홀', '로', '우뚝', '선', '저', '바위', '칭얼대', '는', '파도', '에', '가리', '어', '숨', '어', '있', '는지', '꽁꽁', '얼', 'ㄴ', '겨울', '바다', '꼭', '입', '을', '다물', 'ㄴ다', '포말', '은', '일렁이', '고', '살', 'ㄴ다는', '것', '은', '다', '그러', 'ㄴ', '거', '이', '다']
걸린 시간:  3.2637031078338623
-------------- Komoran ------------
['홀로', '우뚝', '서', 'ㄴ', '저', '바위', '칭얼대', '는', '파도', '에', '가리', '어', '숨', '어', '있', '는지', '꽁꽁', '얼', 'ㄴ', '겨울', '바다', '꼭', '입', '을', '다물', 'ㄴ다', '포', '말', '은', '일렁이', '고', '살', 'ㄴ다는', '건', '다', '그런', '거', '다']
걸린 시간:  0.006722450256347656
-------------- Mecab ------------
['홀로', '우뚝', '선', '저', '바위', '칭얼대', '는', '파도', '에', '가려', '숨', '어', '있', '는지', '꽁꽁', '언', '겨울', '바다', '꼭', '입', '을', '다', '문다', '포말', '은', '일렁이', '고', '산다는', '건', '다', '그런', '거', '다']
걸린 시간:  0.0048024654388427734
-------------- Okt ------------
['홀로', '우뚝', '선', '저', '바위', '칭얼대는', '파도', '에', '가려', '숨어있는지', '꽁꽁', '언', '겨울', '바다', '꼭', '입', '을', '다문다', '포말', '은', '일렁', '이고', '산다', '는', '건', '다', '그런', '거', '다']
걸린 시간:  2.2116546630859375
-------------- Khaiii ------------
['홀로', '우뚝', '서', 'ㄴ', '저', '바위', '칭얼대', '는', '파도', '에', '가리', '어', '숨', '어', '있', '는지', '꽁꽁', '언', '겨울바다', '꼭', '입', '을', '다물', 'ㄴ', '다', '포말', '은', '일렁이', '고', '살', 'ㄴ다는', '것', 'ㄴ', '다', '그런', '거', '이', '다']
걸린 시간:  0.01300191879272461

 

** 우뚝 '선'에서 '선'은 '섰던', '서고'와 어미가 '서'로 갔다. 따라서 그냥 '선'으로 분석해버리면 간단한 사용 용도에 무난할 수도 있지만 문학적 분석에는 적합하지 않다. Hannanum, Komoran, Khaiii 가 제대로 분석했다.

** '다문다'도 마찬가지다. '다물', 'ㄴ다'로 분석되어야 하는데, Mecab처럼 '다','문다'로 해버리면 틀렸다. '모두 다 물어버린다'는 뜻으로 바뀌기 때문이다. '다문다', '다물었다', '다물다', '다물고'를 형태소 분석했을 때 첫 형태소는 '다물'이 되어야 한다. Mecab과 Okt가 틀리고 나머지는 다 맞혔다. Okt는 기본적으로 '숨어있는지' 정도는 띄어서 분석해줘야 하는데 그것조차 하지 않았다. 보통 띄어쓰기 실수하는 것 중에는 '서있는' 처럼 '있는'을 붙여쓰는 경우가 잦다.

 

5) 헷갈리는 것들2 

 

sentence = "뱀이 왜 기어다니는지 아세요 혀가 다 갈라졌겠어요 삶은 살아가는 것이지 삶는 게 아니에요
. 우리 계란을 삶아보아요. 빨래도 삶고요"

 

-------------- Hannanum ------------
['배', 'ㅁ', '이', '왜', '기어다니', '는지', '알', '세', '요', '혀', '가', '다', '가르', '아', '지', '었겠어', '요', '삶', '은', '살', '아', '가', '는', '것', '이', '지', '삶', '는', '것', '이', '아니', '에요', '.', '우리', '계란', '을', '삶', '아', '보', '아', '요', '.', '빨래', '도', '삶', '고요']
걸린 시간:  0.40601611137390137
-------------- Kkma ------------
['뱀', '이', '왜', '기어다니', '는지', '아세', '요', '혀', '가', '다', '갈라지', '었', '겠', '어요', '살', 'ㅁ', '은', '살아가', '는', '것', '이', '지', '삶', '는', '것', '이', '아니', '에요', '.', '우리', '계란', '을', '삶', '아', '보', '아요', '.', '빨래', '도', '삶', '고요']
걸린 시간:  3.1802914142608643
-------------- Komoran ------------
['뱀', '이', '왜', '기어', '다니', '는지', '아', '세', '요', '혀', '가', '다', '갈라지', '었', '겠', '어요', '삶', '은', '살아가', '는', '것', '이', '지', '삶', '는', '게', '아니', '에요', '.', '우리', '계란', '을', '삶', '아', '보', '아요', '.', '빨래', '도', '삶', '고요']
걸린 시간:  0.0075070858001708984
-------------- Mecab ------------
['뱀', '이', '왜', '기어다니', '는지', '아세요', '혀', '가', '다', '갈라졌', '겠', '어요', '삶', '은', '살아가', '는', '것', '이', '지', '삶', '는', '게', '아니', '에요', '.', '우리', '계란', '을', '삶', '아', '보', '아요', '.', '빨래', '도', '삶', '고요']
걸린 시간:  0.0005805492401123047
-------------- Okt ------------
['뱀', '이', '왜', '기어다니는지', '아세요', '혀', '가', '다', '갈라졌겠어요', '삶은', '살아가는', '것', '이지', '삶는', '게', '아니에요', '.', '우리', '계란', '을', '삶아', '보아', '요', '.', '빨래', '도', '삶고요']
걸린 시간:  2.271655797958374
-------------- Khaiii ------------
['뱀', '이', '왜', '기', '어', '다니', '는지', '알', '시', '어요', '혀', '가', '다', '갈라지', '었', '겠', '어요', '삶', '은', '살아가', '는', '것', '이', '지', '삶', '는', '것', '이', '아니', '에요', '.', '우리', '계란', '을', '삶', '아', '보', '아요', '.', '빨래', '도', '삶', '고요']
걸린 시간:  0.011988639831542969

 

** '뱀'이 '배다'의 명사형일 수도 있다. 사전 정보가 없다면 그렇다는 것이다. '삶'도 '살다'가 명사형으로 바뀐 것처럼. 그래도 '삶'은 명사로 굳어졌고, '뱀'은 '배다'의 명사형으로보다는 명사 '뱀'으로 많이 사용되고, 문맥으로 보면 대번에 알 수 있다.

Hannanum이 '뱀'을 '배'+'ㅁ'으로 분석했다.

Kkma는 '삶은'을 '살'+'ㅁ'+'은' 로 분석했다.

'게'는 '것이'의 준말이다. 코모란, 메켑, Okt는 '게'로 그대로 두었다.

'갈라졌겠어요' 는 '갈라지었겠어요'이고, '갈라지(다)' + '었', '겠', '어요'로 분해된다.

물론 '가르다', '지다' 두 개로 분리해서 볼 수도 있으나 '갈라지다'라는 말이 국어사전에 있으므로, 하나의 단어로 보는 게 좋겠다.

이 기능에 미달한 분석기는 Mecab, Okt이고  Hannanum는 사전에 있는 단어까지 다시 쪼개는 치밀함을 보였으나 실용적이지는 못하다.

*************** 총평

일단 Okt와 Kkma는 너무 느려서 실전에서 쓰기는 어려울 듯하다.

Mecab은 일반 용도로는 무난할 수 있으나 문학 용도로는 아쉬운 점이 있다. (Mecab의 pos 메서드를 써보면 Khaiii처럼 더욱 정확하게 분석을 하던데, 그 정보를 밖으로 끌어낼 방법을 아직 찾지 못했다.)

 

문학 용도에 가장 근접한 분석기는 카이(Khaiii)로 보인다. 그래서 한국어 시를 분석하는 형태소 분석기로 카이를 선택하게 되었는데 아쉬운 점은 있다.

 

* 사전에 없는 복합명사의 경우, 따로 분리해서 처리했으면 좋겠는데... ('겨울바다' => '겨울' '바다')

* 고유명사 인식을 때로 잘 못할 경우가 있다.                                      ('수락산자락' => '수락산', '자락')

* 앞에 단어가 없는 경우에 해당 음절을 잘 분석하지 못하는 경우가 있다.  ('어제' => '어', '제')

* 정확도가 높은 Large model을 기본으로 설치 되게 했으면 좋겠다. 

 

**** 카이를 비롯해 Mecab, 그외 형태소 분석기 개발 참여자 분들에게 감사 말씀드립니다.