한글 NLP with Python
한국어 품사및 태그
아래의 태그는 ‘세종 계획’에서 나온 태그를 기준으로 하였습니다.
각 library들마다 약간씩 이름이 다를 수 있습니다. 자세한 각 라이브러리별 품사에 대한 태킹을 여기를 눌러주시기 바랍니다.
먼저 용어부터 정리를 하면 다음과 같습니다.
- 체언: 명사, 대명사, 수사 -> 세 품사를 묶어 체언이라고 함 (예. 사람, 학교, 초등학교, 나, 너, 이것, 하나, 둘째, etc)
- 용언: 동사, 형용사 두 품사를 묶어 용언이라고 함 (예. 먹다, 달리다, 예쁘다, 착하다)
- 형태소: 의미를 가진 최소 단위. ‘사람’, ‘나’, ‘하나’ 같은 말은 더 이상 쪼개지지 않습니다.
- 접사: 독립적으로 쓰이지 못하고, 다른 말에 붙어 새로운 단어를 만드는 형태소. (예. 풋사과, 햇과일, 지우개, 점쟁이)
- 어근: 단어에서 실질적 의미(중심이 되는)를 나타내는 부분. (사람, 학교, 나, 풋사과, 점쟁이, 초등 학교, 깨끗하다 )
tagnamedescriptionexample
NNG | 일반 명사 | 일반적인 사물의 이름을 가르킨다 | 하늘, 나무, 사랑, 희망 |
NNP | 고유 명사 | 특정한 사람이나 사물의 이름을 가르킨다 | 안창호, 금강산, 신라, 한강 |
NNB | 의존 명사 | 자립명사라고도 하며 스스로 뜻을 지니고 있어 다른 말의 도움없이 쓰이는 명사 |
뿐, 바, 따름, 이, 데, 줄, 나름, 나위 |
NR | 수사 | 사물의 수량이나 순서를 나타냄 | 하나, 둘, 셋, 넷, 다섯, 첫째, 둘째, 셋째 |
NP | 대명사 | 인칭 대명사는 사람의 이름을 대신하여 가르키며, 지시 대명사는 사람이외의 사물, 장소를 가르키는 말 |
어르신, 당신, 귀하, 자네, 너, 이것, 저것, 그것, 무엇 |
VV | 동사 | 동작이나 과정을 나타냄 | 가다, 먹다, 자다 |
VA | 형용사 | 사물의 모습이나 상태를 표현 | 귀엽다, 예쁘다, 노랗다, 둥글다, 있다, 같다 |
VX | 보조 용언 | 본영언과 연결되어 그것의 뜻을 보충하는 역활. 보조 동사, 보조 형용사등이 있다. |
가지고 싶다, 먹어 보다 |
VCP | 긍정 지정사 | 이다 | |
VCN | 부정 지정사 | 아니다 | |
MM | 관형사 | 체언앞에 놓여서 그 체언의 내용을 꾸며줌 | 순 살코기, 저 어린이, 한 사람 |
MAG | 일반 부사 | 용언 또는 다른 말 앞에 놓여 그 뜻을 분명하게 함 | |
MAJ | 접속 부사 | 문장 수식의 접속사와 단어나 구 등을 이어주는 접속사 | 그리고, 그러나, 그러면, 그뿐 아니라 |
IC | 감탄사 | 감동, 부름, 놀람, 응답등을 나타냄 | 어이쿠, 에그머니, 앗, 어럽쇼, 호호, 파이팅 |
JKS | 주격 조사 | 체언이 서술어의 주어임을 표시하는 격조사 ~이/~가 , ~께서, ~에서 |
바람이 분다, 소리가 들린다, 우리 학교에서 우승을 차지했다 |
JKC | 보격 조사 | 체언이 보어임을 표시하는 격조사 ~이/~가 |
그녀가 선생님이 되었다, 그는 남자가 아니다 |
JKG | 관형격 조사 | 앞의 체언이 뒤에 오는 체언을 수식하는 기능하는 격조사 ~의 |
이 문장의 과형격 조사는 의이다 |
JKO | 목적격 조사 | 낱말이 타동사의 대상이 되게 만든다 을/를 |
공부를 하라, 노력을 하라 |
JKB | 부사격 조사 | 앞의 체언을 부사어가 되게 만든다 에/에게, 에서/서, 보다, ~한테, 로, 로서, 와/과, ~(으)로, 라/라고, |
바보에게 바보가, 집에서 공부하는게 좋다 |
JKV | 호격 조사 | 체언과 결합하여 누구를 부를때 사용 아/야 |
길동아, 빨리 나와, 영희야 밥먹어라 |
JKQ | 인용격 조사 | 앞의 말을 인용 | “언제 오겠니”라고 물었다. “우선 멈춤”이라고 적혀 있었다. 그는 내일 온다고 말했다. 그녀는 자기가 좋아하는 사람은 영철이라고 말했다. |
JC | 접속 조사 | 두 단어를 같은 자격으로 이어 주는 구실을 함 ~와/과, 하고, 이며, 에다, (이)랑 |
영희와 철수는 친구다 |
JX | 보조사 | 특별한 의미를 더함 | 너도 (역시) 떠나니? 너만(단독) 반대니? 너조차(역시, 최종) 떠나니? 너부터 (시작, 먼저) 떠나라 10시까지 (도착) 오너라 너마저 (종결) 떠나는 구나 |
EP | 선어말어미 | 어말 어미 앞에 놓여 특수한 문법적 기능을 수행 | 선생님께서 오시는구나 (주체높임) 나는 지금 책을 읽는다 (현재) 이 책은 예전에 내가 읽었던 것이다. (과거) 내일 그곳으로 가겠다 (미래) 안녕하시옵니까? (공손) 지금 여기서 무엇을 하느냐?! (직설) 오늘 가보니 아무것도 없더구나 (회상) 이제 어찌 하오리까? (추측) |
EF | 종결 어미 | 말하는 이의 태도에 따라 의문문, 명령문, 청유문, 감탄문등으로 나뉨 |
오늘은 날씨가 춥다. (평서문) 선녀가 따로 없구나! (감탄문) 어서 들어가거라 (명령문) 언제 밥 한번 먹자 (청유문) |
EC | 연결 어미 | 어간에 붙어 다음 말을 연결하는 구실을 함 대등적 연결 어미: ~고, ~(으)며, ~(으)나 보조적 연결어미: ~아/어, ~게, ~지 종속적 연결 어미: ~면, ~지 |
가을이 가고 겨울이 왔다 (가다 + ~고) 음악을 들으며 공부를 한다 (듣다 + ~으며) 키가 크나 힘은 약하다 (크다 + ~나) 사과는 내가 진작 먹어 버렸다 (먹다 + ~어) 손님을 응접실에서 기다리게 했다 (기다리다 + ~게) 느낌이 좋지 않다 (좋다 + ~지) 이번에 떨어지면 정말 큰일난다 (떨어지다 + ~면) |
ETN | 명사형 전성 어미 | ~기, ㅁ, 음 | 있음 (있다) 없음 (없다) 바람 (바라다) 춤 (추다) 삶 (살다) 앎 (알다) 졺 (졸다) 즐거움 (즐겁다) 놀라움 (놀랍다) 무거움 (무겁다) 가벼움 (가볍다) 담배 끊기를 바랍니다. 열심히 공부하기를 약속했다 |
ETM | 관형형 전성 어미 | 동사: ~은, ~ㄴ, ~던, ~았던, ~었던, ~였던 형용사: ~았던, ~었던, ~였던 |
아까 먹은 사과는 정말 맛있었다 (먹다 + ~은) 네가 어제 쓴 일기를 보고 싶다 (쓰다 + ~ㄴ) 좀 전에 보던 영화 제목이 뭐야? (보다 + ~던) 작년에 봤던 각설이 (보다 + ~던) 정말 끝까지 노력했던 적 있어? 나도 한때는 겁이 없었던 시절이 있었지 (없다 + ~었던) 유난히 키가 작았던 그 소녀를 기억한다 (작다 + ~았던) 그렇게 기뻤던 날을 어떻게 잊을 수 있겠나 (기쁘다 + ~었던) 유난히 시원했던 여름으로 기억한다 (시원하다 + ~였던) 저기서 TV를 보는 사람이 내 남편이에요 (보다 + ~는) 그럼 여기서 소설을 쓰는 사람은 누구예요? (쓰다 + ~는) 좋은 생각이 떠올랐다 (좋다 + ~은) 예쁜 그림이 있다 (예쁘다 + ~ㄴ) 이 음식들을 모두 내일 먹을 것이다 (먹다 + ~을) 내일이면 떠날 사람이다 (떠나다 + ~ㄹ) |
XPN | 체언 접두사 | 낱말의 앞에 붙어서 의미를 첨가하여 다른 낱말을 이루는 말. |
갓마흔, 갓서른, 갓졸업하다 (지금, 막, 금방) 군말, 군소리, 군침 (쓸데없는) 날고기, 날감자 (익지 않은, 마르지 않은, 가공하지 않은) 덧칠하다, 덧붙이다 (더해진, 부가된) 되풀이하다, 되새김질, 되돌아보다 (다시, 되풀이하다) 맞선, 맞벌이, 맞절 (마주보다, 함께, 반대방향으로) 매년, 매달, 매번, 매사 (하나하나의, 각각의) 맨주먹, 맨바닥 (더하지 않은) 빗나가다, 빗맞다 (비뚜로, 잘못, 기울어진) 생매장, 생쌀, 생맥주 (날것, 익히지 않은, 자연의) 설익다 (불충분함) 알밤, 알사탕, 알약, 알몸 (작고 둥근, 벌거벗은, 주요한) 외길, 외나무다리, 외아들, 외톨이 (오직, 하나의) 잔기침, 잔돈, 잔소리, 잔주름 (작은, 필요치 않은) 짓누르다, 짓밟다 (함부로, 마구, 흠씬) 첫걸음, 첫날, 첫눈, 첫사랑 (처음의, 초기의) 총계, 총선거, 총액 (모든, 전체의, 종합적인) 최고, 최근, 최상급, 최소, 최신식 (가장 앞선/좋은/많은) 풋사랑, 풋사과 (덜 익은, 경험이 부족한, 신선한, 새로운) 햇감자, 햇곡식, 햇과일, 햅쌀 (새로운, 그해의 가장 처음) 한밤중, 한가운데, 한마음, 한민족 (큰, 넓은, 중심의) 헛기침, 헛고생, 헛수고 (속이 빈, 소용이 없는) 홀몸, 홀아비, 홀어머니 (외로운, 짝이없는, 하나뿐인) |
XSN | 명사파생 접미사 | 명사 + 접미사 = 명사 | 부자간, 형제간, 서울과 부산간, 며칠간 (~간, 사이의, 관계) 장난감, 일감, 사윗감, 우월감 (~에 적합한 사람, ~를 위한 재료) 12시경, 초순경 (~경, 시간, 쯤, 무렵) 어선군, 유빙군 (~군, 무리, 떼) 마음껏, 힘껏, 소신껏 (~껏, 가장 높은 한도에 이르도록) 잠꾸러기, 말썽꾸러기 (~꾸러기, 버릇이 많거나, 일으키는 사람) 구경꾼, 나무꾼, 춤꾼 (그 일을 잘하는 사람, 몰려드는 사람) 여자끼리, 우리끼리 (~끼리, 여럿이 함께 패를 지음) 사장님, 선생님, 달님 (~님, 호칭에 붙어 높임을 나타냄) 게으름뱅이, 주정뱅이 (습관 성질등을 얕잡아 이름) 떡보, 술보, 울보 (유달리 즐기거나 정도가 심함) 생김새, 모양새, 쓰임새 (됨됨이, 정도, 상태) 마음씨, 김해 김씨, 말씨 (태도, 같은 성의 계통) 둘씩, 다섯씩 (각각 같은 수효로 나눔) 오늘쯤, 어디쯤 (어느정도) |
XSV | 동사 파생 접미사 | 동사 + 접미사 = 동사 | 기웃거리다, 북적거리다, 투덜거리다, 헐떨거리다 (~거리다, ~대다, 어떤 행동을 반복하다) 깨뜨리다, 넘어뜨리다, 떨어뜨리다 (동사를 힘주어 나타냄) 형만한 아우, 우리 집만한 집이 없다, 주먹만한 돌 (~만한 크기의) |
XSA | 형용사 파생 접미사 | 형용사 + 접미사 = 형용사 | 학생답다, 여자답다, 군인답다 (~답다, ~같은, ~라 할 만하다) 자유롭다, 신비롭다, 해롭다 (~한 성격을 지니는) 사랑스럽다, 자랑스럽다, 걱정스럽다 (~와 같은, ~처럼 보이는) 겸연쩍다, 미심쩍다, 수상쩍다 (~한 느낌을 갖다/주다/느끼다) |
XR | 어근 | 중심이 되는 낱말 | 사람, 학교, 나, 풋사과, 점쟁이, 초등 학교, 깨끗하다 |
SF | 마침표 물음표 느낌표 |
., !, ? | |
SE | 줄임표 | ... | |
SS | 따옴표 괄호표 줄표 |
', ", (, ), ― | |
SP | 쉼표 가운뎃점 콜론 빗금 |
||
SO | 붙임표 | (물결,숨김,빠짐) | |
SW | 기타기호 | (논리수학기호,화폐기호) | |
SH | 한자 | ||
SL | 외국어 | hello, hi | |
SN | 숫자 | 1, 2, 3 | |
NF | 명사추정범주 | ||
NV | 용언추정범주 | ||
NA | 분석불능범주 |
KoNLPy
KoNLPy의 장점은 이미 잘 만들어진 형태소 엔진을 파이썬에서 사용할수 있도록 해준다는 것입니다.
꼬꼬마 (Kkma), 한나눔(Hannanum), 자바 한국어 형태소 분석기 (Komoran), 은전한닢 프로젝트 (Mecab), Twitter의 사전을 하나의 라이브러리에서 사용할수 있습니다.
설치
KoNLPy 설치
KoNLPy (코엔엘파이라고 읽음)을 설치는 매우 단순합니다.
MeCab도 같이 설치를 합니다.
sudo pip3 install konlpy
MECAB 설치
KoNLPy에서 쉽게 설치하는 방법이 있는데 (mecab.sh사용) 해당 방식으로 설치시
낮은 버젼의 Mecab이 설치가 되며, 추후 사전추가시 어려움이 생길수 있습니다.
Mecab은 따로 최신버젼을 설치를 합니다.
MECAB-KO 형태소 분석기 엔진 설치
은전한닢 프로젝트에서 만든 MeCab의 fork 프로젝트이며 한국어의 특성에 맞는 기능을 추가하였습니다.
다운로드 페이지에서 최신 버젼을 다운로드 할수 있습니다.
wget https://bitbucket.org/eunjeon/mecab-ko/downloads/mecab-0.996-ko-0.9.2.tar.gz
tar -zxvf mecab-*-ko-*.tar.gz
cd mecab-*-ko-*
./configure
make
make check
sudo make install
추가적으로 .so 파일들을 연결시켜주기 위해서 sudo vi /etc/ld.so.conf 으로 열고..
/usr/local/lib 를 추가합니다.
마지막으로 sudo ldconfig 를 실행.
버젼을 확인합니다.
$ mecab --version
mecab of 0.996/ko-0.9.2
MECAB-KO 사전 설치
다운로드 페이지 최신 사전 파일을 다운로드 받을수 있습니다.
설치는 기본적으로 /usr/local/lib/mecab/dic/mecab-ko-dic 에 설치 됩니다.
Dependencies를 설치합니다.
sudo apt-get install automake
MeCAB-KO-DIC을 설치합니다.
wget https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/mecab-ko-dic-2.1.1-20180720.tar.gz
tar -zxvf mecab-ko-dic-2.1.1-20180720.tar.gz
cd mecab-ko-dic-2.1.1-20180720
./autogen.sh
./configure
make
sudo make install
MECAB-KO 설치 확인 테스트
$ mecab -d /usr/local/lib/mecab/dic/mecab-ko-dic
사나는 사랑이다
사나 NNG,*,F,사나,*,*,*,*
는 JX,*,T,는,*,*,*,*
사랑 NNG,*,T,사랑,*,*,*,*
이 VCP,*,F,이,*,*,*,*
다 EC,*,F,다,*,*,*,*
EOS
형태소 분석 비교
아버지가방에들어가신다
아버지가방에들어가신다 를 갖고서 각각의 사전에 대한 spacing algorithm을 비교합니다.
아버지가 방에 들어 가신다 이렇게 제대로 해석한것은 Mecab이며,
Kkma, Twitter는 아버지 가방에 들어 가신다 라고 분석했습니다.
HannanumKkmaKomoranMecabTwitter
아버지가방에들어가 / N | 아버지 / NNG | 아버지가방에들어가신다 / NNP | 아버지 / NNG | 아버지 / Noun |
이 / J | 가방 / | 가 / JKS | 가방 / Noun | |
시ㄴ다 / E | 에 / JKM | 방 / NNG | 에 / Josa | |
들어가 / VV | 에 / JKB | 들어가신 / Verb | ||
시 / EPH | 들어가 / VV | 다 / Eomi | ||
ㄴ다 / EFN | 신다 / EP+EC |
머리를 감기다
머리를 감기다 에서는 감기가 병을 가르키는 명사 감기를 가르키는 것인지, 동사 감기다를 말하는 것인지 구분합니다.
궁극적으로 Komoran 그리고 Mecab 만 감기를 동사로 제대로 구분을 해냈습니다.
HannanumKkmaKomoranMecabTwitter
머리 / N | 머리 / NNG | 머리 / NNG | 머리 / NNG | 머리 / Noun |
를 / J | 를 / JKO | 를 / JKO | 를 / JKO | 를 / Josa |
감기 / N | 감기 / NNG | 감기 / VV | 감기 / VV | 감기 / Noun |
이 / J | 이 / VCP | |||
다/ E | 다 / EFN | 다 / EC | 다 / EC | 다 / Josa |
처리 속도 비교
중성자별(neuron star)은 초신성 폭발 직후 무거운 별이 중력붕괴하여 만들어진 밀집성의 일종이다 라는 문장을 갖고서 속도 측정을 하였습니다.
HannanumKkmaKomoranMecabTwitter
mean | 17.1 ms | 693 ms | 6.92 ms | 0.0901 ms | 16.3 ms |
slowest | 607 ms | 3850 ms | 1750 ms | 1.45 ms | 882 ms |
속도 측면에서 Mecab이 가장 빠릅니다.
Komoran의 경우 java.lang.OutOfMemoryError: GC overhead limit exceeded 에러가 빈번하게 나오며, 거의 멈춰있는 수준까지도 됨
KoNLPy API 사용
Tag Package
불러오기
다음의 사전 클래스들을 다음과 같이 불러오고 instantiate 해줄수 있습니다.
from konlpy.tag import Kkma, Hannanum, Komoran, Mecab, Twitter
twitter = Twitter()
mecab = Mecab()
kkma = Kkma()
hannanum = Hannanum()
komoran = Komoran()
문장을 형태소로 변환
Hannanum
> hannanum.morphs('@챗봇 내일 판매율 예측해서 Anderson한테 이메일로 보내줘.')
['@챗봇', '내', '이', 'ㄹ', '판매율', '예측해서', 'Anderson', '한테', '이메일', '로', '보내', '어', '주', '어', '.']
Kkma
> kkma.morphs('@챗봇 내일 판매율 예측해서 Anderson한테 이메일로 보내줘.')
['@', '챗봇', '내일', '판매', '율', '예측', '하', '어서', 'Anderson', '한테', '이메일', '로', '보내주', '어', '.']
Komoron
> komoran.morphs('@챗봇 내일 판매율 예측해서 Anderson한테 이메일로 보내줘.')
['@챗봇', '내일', '판매', '율', '예측', '하', '아서', 'Anderson', '한테', '이메일', '로', '보내', '어', '주', '어', '.']
Mecab
> mecab.morphs('@챗봇 내일 판매율 예측해서 Anderson한테 이메일로 보내줘.')
['@', '챗', '봇', '내일', '판매', '율', '예측', '해서', 'Anderson', '한테', '이메일', '로', '보내', '줘', '.']
> twitter.morphs('@챗봇 내일 판매율 예측해서 Anderson한테 이메일로 보내줘.')
['@', '챗봇', '내일', '판매', '율', '예측해서', 'Anderson', '한테', '이메일', '로', '보내', '줘', '.']
POS (Part of speech) Tags
최근 Twitter 또는 인스타그램등등의 SNS에서 사용될 만한 문장으로 예제를 돌려보았습니다.
특히 Twitter 사전의 경우 @누구 또는 #태그 를 정확하게 SNS에서 사용하는 hashtag로 인식을 했으며,
그 외의 사전은 먹스타그램 처럼 하나의 형태소별로 쪼개놓을 것을 알 수 있습니다.
Hannanum
> hannanum.pos('@anderson 어제 비올렛 스테이크 핵존맛! #쩔어 #먹스타그램')
[('@', 'S'),
('anderson', 'F'),
('어제', 'N'),
('비올렛', 'N'),
('스테이크', 'N'),
('핵존맛', 'N'),
('!', 'S'),
('#쩔어', 'N'),
('#먹스타그램', 'N')]
Kkma
> kkma.pos('@anderson 어제 비올렛 스테이크 핵존맛! #쩔어 #먹스타그램')
[('@', 'SW'),
('anderson', 'OL'),
('어제', 'NNG'),
('비올', 'NNG'),
('렛', 'UN'),
('스테이크', 'NNG'),
('핵', 'NNG'),
('존', 'NNP'),
('맛', 'NNG'),
('!', 'SF'),
('#', 'SW'),
('쩔', 'VV'),
('어', 'ECD'),
('#', 'SW'),
('먹', 'NNG'),
('스타', 'NNG'),
('그램', 'NNM')]
Komoran
> komoran.pos('@anderson 어제 비올렛 스테이크 핵존맛! #쩔어 #먹스타그램')
[('@', 'SW'),
('anderson', 'SL'),
('어제', 'MAG'),
('비올렛', 'NA'),
('스테이크', 'NNG'),
('핵', 'NNG'),
('존', 'NNG'),
('맛', 'NNG'),
('!', 'SF'),
('#쩔어', 'NA'),
('#', 'SW'),
('먹', 'NNG'),
('스타', 'NNG'),
('그램', 'NNB')]
Mecab
> mecab.pos('@anderson 어제 비올렛 스테이크 핵존맛! #쩔어 #먹스타그램')
[('@', 'SY'),
('anderson', 'SL'),
('어제', 'NNG'),
('비올', 'NNG'),
('렛', 'NNP'),
('스테이크', 'NNG'),
('핵', 'NNG'),
('존', 'NNP'),
('맛', 'NNG'),
('!', 'SY'),
('#', 'SY'),
('쩔', 'VA'),
('어', 'EC'),
('#', 'SY'),
('먹스', 'NNG'),
('타', 'XSV+EC'),
('그램', 'NNG')]
> twitter.pos('@anderson 어제 비올렛 스테이크 핵존맛! #쩔어 #먹스타그램')
[('@anderson', 'ScreenName'),
('어제', 'Noun'),
('비올', 'Noun'),
('렛', 'Noun'),
('스테이크', 'Noun'),
('핵존맛', 'Noun'),
('!', 'Punctuation'),
('#쩔어', 'Hashtag'),
('#먹스타그램', 'Hashtag')]
단어만 추출
단어를 추출하는데 크게 문제는 없지만, Kkma의 경우 명사 + 명사 로 만들어진 부분을 중복해서 집어내고 있으며,
Mecab의 경우 ‘인스타그램’이라는 최신 단어를 분리시키는 단점들을 보이고 있습니다.
Hannanum
> hannanum.nouns('철학은 기술을 만들고 기술은 문화를 만든다')
['철학', '기술', '기술', '문화']
Kkma
> kkma.nouns('롯데마트의 간장치킨이 영세상인들을 울게 만들다')
['롯데', '롯데마트', '마트', '간장', '간장치킨', '치킨', '영세', '영세상인', '상인']
Komoron
> komoran.nouns('치킨월드의 불닭볶음은 대중의 많은 인기를 얻고 있다')
['치킨', '월드', '불닭', '볶음', '대중', '인기']
Mecab
> mecab.nouns('소녀시대 태연은 인스타그램을 통해 일본투어를 시작하겠다고 전해왔다')
['소녀', '시대', '태연', '인', '스타', '그램', '일본', '투어', '시작']
> twitter.nouns('소녀시대 태연은 인스타그램을 통해 일본투어를 시작하겠다고 전해왔다')
['소녀시대', '태연', '인스타그램', '통해', '일본', '투어', '전해']
사전 추가하기
MeCAB 사전 추가
먼저 mecab-ko-dic가 설치된 곳으로 이동합니다.
만약 없으면 “MECAB-KO 사전 설치” 부분을 다시 보고 설치를 합니다.
user.csv 파일을 만들고 아래의 형식대로 단어를 추가할 수 있습니다.
gedit user.csv
user.csv에는 다음과 같은 형태로 지정합니다.
자세한 내용은 mecab-ko-dic 품사 태그 설명을 참조 합니다.
표층형좌ID우ID우선도품사의미 부류종성 유무발음타입첫번째 품사마지막 품사표현
태양 | 0 | NNG | * | T | 태양 | * | * | * | * | ||
서울 | 0 | NNP | 지명 | T | 서울 | * | * | * | * | ||
불태워졌 | 0 | VV+EM+VS+EP | T | 불태워졌 | Inflected | VV | EP | 불태우/VV/+어/EC/+지/VX/+었/EP/ | |||
해수욕장 | 0 | NNG | T | 해수욕장 | Compound | * | * | 해수/NNG/+욕/NNG/+장/NNG/* |
이름영어명설명
표층형 | Surface layer shape | 단어명 |
좌측 ID | Left context ID | MeCAB내부에서 사용되는 ID값이며, left-id.def 에서 참조함. 빈칸으로 냅둘시 자동으로 ID를 할당함 |
우측 ID | Right context ID | MeCAB내부에서 사용되는 ID값이며, right-id.def에서 참조함. 빈칸으로 냅둘시 자동으로 ID를 할당함 |
우선도 | Cost | 해당 단어가 얼마나 자주 나타나는지를 나타내며, 값이 작을수록 더 자주 나타난다는 뜻. 그냥 빈칸으로 두면 됨 |
품사 | Part of speech | 품사 Tag값이 설정됨 |
의미 부류 | 인명, 지명, * 이 들어갈수 있음 | |
종성 유무 | 받침이 있으면 T 없으면 F | |
발음 | Pronunciation | 발음을 적음 |
타입 | Inflected - 활용, Compound - 복합명사, Preanalysis - 기분석, * | |
첫번째 품사 | ||
마지막 품사 | ||
표현 | 활용, 복합명사, 기분석이 어떻게 구성되는지 알려줌 |
예를 들어서 user.csv에는 다음과 같이 단어를 추가할 수 있습니다.
가모라,,,0,NNP,인명,F,가모라,*,*,*,*
추가후에 add-userdic.sh를 실행시킵니다.
$ ./tools/add-userdic.sh
generating userdic...
nnp.csv
... (생략)
reading ./NNG.csv ... 205269
emitting double-array: 100% |###########################################|
reading ./matrix.def ... 3819x2694
emitting matrix : 100% |###########################################|
done!
To enable dictionary, rewrite /usr/local/etc/mecabrc as "dicdir = /usr/local/lib/mecab/dic/mecab-ko-dic"
마지막으로 설치를 합니다.
sudo make install
마지막으로 ‘가모라’가 인명으로 하나의 이름으로 인식되는지 확인해봅니다.
아래에서처럼 ‘가모라’는 하나의 단어로 인식이 잘 됩니다.
$ mecab
가모라
가모라 NNP,인명,F,가모라,*,*,*,*
EOS
twitter-korean-text에 사전 추가
사전에 Marvel Comics 영울들의 이름을 추가시켜보도록 하겠습니다.
먼저 twitter-korean-text 를 git에서 clone을 합니다.
git clone https://github.com/twitter/twitter-korean-text.git
IntelliJ Idea를 열고 위의 프로젝트를 엽니다.
twitter-korean-text/src/main/resources/com/twitter/penguin/korean/util 위치에 보면 다양한 사전이 txt파일 형식으로 저장이 되어 있습니다.
비교를 하기 위해서 먼저 테스트 케이스를 만듭니다.
/src/test/scala/com/twitter/penguin/korean/MarvelTest.scala 에 다음과 같은 코드를 넣습니다.
package com.twitter.penguin.korean
class MarvelTest extends TestBase {
var text = "앤더슨조는 무적 헐크버스터, 자이언트루퍼와 맞서 싸웠다"
test("new word") {
var tokens = TwitterKoreanProcessor.tokenize(text)
println(tokens)
}
}
실행시킨 결과는 아래와 같으며, 앤더슨조, 헐크버스터, 자이언트루퍼를 하나의 단어가 아니라 독립된 단어로 형태로를 구분하였습니다.
List(앤더슨(ProperNoun: 0, 3), 조(Suffix: 3, 1), 는(Josa: 4, 1), (Space: 5, 1), 무족(Noun: 6, 2), (Space: 8, 1), 헐크(ProperNoun: 9, 2), 버스터(ProperNoun: 11, 3), ,(Punctuation: 14, 1), (Space: 15, 1), 자이언트(ProperNoun: 16, 4), 루퍼(ProperNoun: 20, 2), 와(Josa: 22, 1), (Space: 23, 1), 맞서(Verb: 24, 2), (Space: 26, 1), 싸웠(Verb: 27, 2), 다(Eomi: 29, 1))
사전에 “앤더슨조”, “헐크버스터”, “자이언트루퍼”를 추가시키겠습니다.
twitter-korean-text/src/main/scala/com/twitter/penguin/korean/tools/DeduplicateAndSortDictionaries.scala 파일을 열고,
DeduplicateAndSortDictionaries 를 실행해서 사전을 업데이터 해줍니다.
다시한번 MarvelTest 실행시켜서 테스트 합니다.
이번에는 “앤더슨조”, “헐크버스터”, 그리고, “자이언트루퍼”를 하나의 대명사로 인식을 하였습니다.
List(앤더슨조(ProperNoun: 0, 4), 는(Josa: 4, 1), (Space: 5, 1), 무적(Noun: 6, 2), (Space: 8, 1), 헐크버스터(Noun: 9, 5), ,(Punctuation: 14, 1), (Space: 15, 1), 자이언트루퍼(ProperNoun: 16, 6), 와(Josa: 22, 1), (Space: 23, 1), 맞서(Verb: 24, 2), (Space: 26, 1), 싸웠(Verb: 27, 2), 다(Eomi: 29, 1))
Maven Project에서 package를 실행합니다.
만들어진 jar 파일을 konlpy로 옮겨줍니다.
sudo mv target/twitter-korean-text-2.4.3.jar /usr/local/lib/python3.6/site-packages/konlpy/java/
현재 Twitter에 사전추가는 되지만 추가된 사전을 KoNLPy와 연동시키는 부분에 관해서는 KoNLPy의 소스코드를 변경이 필요하다는 결론을 냈습니다.
KoNLPy에서는 jar파일로 Twitter-korean-text를 갖고 있습니다.
문제는 버젼이 낮으며 업데이트가 안되어 있는 상태입니다.
References
KoNLPy: 파이썬 한국어 NLP
KoNLPy(“코엔엘파이”라고 읽습니다)는 한국어 정보처리를 위한 파이썬 패키지입니다. 설치법은 이 곳을 참고해주세요.
NLP를 처음 시작하시는 분들은 시작하기 에서 가볍게 기본 지식을 습득할 수 있으며, KoNLPy의 사용법 가이드는 사용하기, 각 모듈의 상세사항은 API 문서에서 보실 수 있습니다.
>>> from konlpy.tag import Kkma
>>> from konlpy.utils import pprint
>>> kkma = Kkma()
>>> pprint(kkma.sentences(u'네, 안녕하세요. 반갑습니다.'))
[네, 안녕하세요..,
반갑습니다.]
>>> pprint(kkma.nouns(u'질문이나 건의사항은 깃헙 이슈 트래커에 남겨주세요.'))
[질문,
건의,
건의사항,
사항,
깃헙,
이슈,
트래커]
>>> pprint(kkma.pos(u'오류보고는 실행환경, 에러메세지와함께 설명을 최대한상세히!^^'))
[(오류, NNG),
(보고, NNG),
(는, JX),
(실행, NNG),
(환경, NNG),
(,, SP),
(에러, NNG),
(메세지, NNG),
(와, JKM),
(함께, MAG),
(설명, NNG),
(을, JKO),
(최대한, NNG),
(상세히, MAG),
(!, SF),
(^^, EMO)]
거인의 어깨 위에 서기
아름답지만 다소 복잡하기도한 한국어는 전세계에서 13번째로 많이 사용되는 언어입니다. 복잡미묘한 한국어 텍스트에서 유용한 특성을 추출하기 위해 그 동안 수많은 한국어 정보처리 도구가 개발되기도 했습니다.
KoNLPy는 같은 기능을 하는 또 하나의 도구를 만들려는 것이 아닙니다. 그보다는, 현존하는 도구 위에 한 층을 쌓아 더 멀리 내다보려는 것입니다. 또한 KoNLPy는 파이썬 프로그래밍 언어로 사용할 수 있도록 만들어졌는데, 그것은 파이썬이 간결하고 우아한 문법구조, 강력한 스트링 연산 기능을 가지고 있을 뿐 아니라 크롤링, 웹프로그래밍, 그리고 데이터 분석을 수행할 수 있는 다양한 패키지를 사용할 수 있는 언어이기 때문입니다.
이 프로젝트에는 세 가지 철학이 있습니다:
- 사용법이 간단해야 한다.
- 누구나 쉽게 이용할 수 있어야 한다. [1]
- “인터넷 민주주의는 효과적이다.”
위의 항목 중 하나라도 어긋나는 것이 있다면 제보 부탁드립니다.
라이센스
KoNLPy는 오픈소스 소프트웨어이며, 아래의 라이센스를 채택하고 있습니다:
라이센스에 따라 자유롭게 코드를 이용하실 수 있으며, 연구에 KoNLPy를 사용하신 경우 아래 논문을 인용해주시기 바랍니다.
- 박은정, 조성준, “KoNLPy: 쉽고 간결한 한국어 정보처리 파이썬 패키지”, 제 26회 한글 및 한국어 정보처리 학술대회 논문집, 2014.
BibTeX는 아래의 코드를 사용하시면 됩니다.:
@inproceedings{park2014konlpy,
title={KoNLPy: Korean natural language processing in Python},
author={Park, Eunjeong L. and Cho, Sungzoon},
booktitle={Proceedings of the 26th Annual Conference on Human & Cognitive Language Technology},
address={Chuncheon, Korea},
month={October},
year={2014}
}
참여하기
KoNLPy는 완벽하지 않습니다. 하지만 조금씩 지속적으로 발전시킬 예정이며, 누구나 개발 과정에 참여할 수 있습니다.
버그를 찾으셨나요? KoNLPy를 발전시킬 좋은 방법이 떠오르시나요? KoNLPy 깃헙 페이지 를 방문해서 아이디어를 제안해주시거나 풀리퀘스트를 보내주세요.
또, 오징어 IRC 네트워크의 #koreannlp 채널에 참여해서 한국어 NLP에 관한 대화에 참여하시거나, KoNLPy 메일링리스트에 가입해서 관련 정보를 받아보거나 궁금한 것에 대한 질문을 할 수도 있습니다.
무엇보다, 질문하는 것만으로도 엄청난 기여라는 점을 알아주세요! 질문은 개발 커뮤니티에 피드백을 주는 가장 직접적이면서도 쉬운 방법이고, 아이디어의 원천도 됩니다.
사용하기
API
인덱스와 표
[2] | GPL이 항상 최선은 아니지만, 몇몇 중요한 dependency가 GPL 라이센스를 채택하고 있기 때문에 그것을 계승하는 차원에서 선택하였습니다. (차후에는 이런 상황이 바뀔 수도 있다고 생각합니다.) |
KLT2000 한국어 형태소 분석기 -- 딥러닝(토큰화), 색인어/키워드 추출, 사용자 매뉴얼 등
아래 파일들이 첨부되어 있습니다.
- KLT2000-TestVersion.zip -- 형태소 분석기(윈도용: cmd창에서 실행)
(또는 https://cafe.naver.com/nlpkang/41 에서 다운로드)
- KLT2000-linux.tar.gz -- 형태소 분석기(linux용)
(또는 http://nlp.kookmin.ac.kr/down/KLT/KLT2000-linux.tar.gz 에서 다운로드)
실행파일 -- index, index2018, indexS, indexT, cnndecomp (사용법은 윈도용과 동일함)
- KLT2000-NDX-xxx.pdf : 색인어 추출 매뉴얼
- KLT2000-KMA-xxx.pdf : 형태소 분석 매뉴얼
<중요> 형태소 분석기의 입출력 한글코드 -- EUC-KR (KS완성형, 윈도의 ANSI)
<중요> 실행 옵션 -- "hdic/KLT2000.ini"의 현재 옵션값 예
==============================================================
AutoSpacing=5 // "5" 음절 이상 어절은 모두 자동 띄어쓰기 적용
AddCnounComponents=1 // 복합명사 분해결과를 출력
RemoveCnounItself=1 // 복합명사 자체를 출력에서 제외 -- 분해결과를 출력했으므로
ExtracAllStems=5 // 동사/형용사 등을 추출하여 원형으로 출력
==============================================================
C> index2018.exe test.txt
C> index2018.exe test.txt output.txt --> 결과를 output.txt에 저장
C> kma.exe -2 --> 한글 어절(또는 문장)을 키보드에서 직접 입력하여 실행하는 방법
<참고> 사용자 사전을 이용하여 미등록어 등록하는 방법
‘./hdic/ham-usr.dic’ 파일에 미등록어를 등록할 수 있습니다.
이 때, 한글 코드는 EUC-KR(KS완성형)로 저장되어야 함!
사용자 사전을 적용하려면 아래 과정이 필요합니다.
1) “./hdic/KLT2000.ini” 파일이 정상적으로 load되어야 하고,
2) KLT2000.ini에 명시된 “지정된 경로”(default: “./hdic”)에 “지정된 파일”(default: ‘ham-usr.dic’)이 존재해야 합니다.
<중요> 실행 오류가 발생할 때
1) hdic/KLT2000.ini 파일을 읽지 못하는 경우(실행파일 폴더에 hdic/KLT2000.ini이 있어야 함).
--> hdic/KLT2000.ini의 19~20번째 라인의 KLT2000.ini의 상대경로(또는 절대경로) 확인 및 수정
--> hdic/KLT2000.ini는 텍스트 파일(EUC-KR)이므로 editor를 이용하여 수정!
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; 사전파일들이 있는 디렉토리 경로 지정 -- max. 127 bytes
; Default: DicDirPath=./hdic/, Ex. DicDirPath=/home/sskang/KLT2000-TestVersion/hdic/
;DicDirPath=c:/Temp/KLT2000-TestVersion/EXE/hdic/
DicDirPath=./hdic/
;--------------------------------------------------------------------------------------------------------
지정된 경로가 잘못되어 사용자 사전 파일을 찾지 못하거나, 또는 KS 완성형(EUC-KR)이 아닌 유니코드로 저장한 경우에는 사용자 사전이 적용되지 않습니다.
2) 입력 파일의 한글코드 인코딩 확인
- default 입출력 한글코드 -- KS완성형(EUC-KR 또는 cp949)
- UTF-8 입출력을 할 때 -- 아래 옵션값을 '1'에서 '2'로 수정 (KLT2000.ini의 58~65라인)
;-------------------------------------------------------------------------------------------
; 입출력 한글코드를 지정할 수 있는 옵션
; Default --> KS완성형(KS C 5601-1987)
; '1' --> KSC5601(default)
; '2' --> UTF8 인코딩
HangulCodeInput=1
HangulCodeOutput=1
;-------------------------------------------------------------------------------------------
위 옵션값을 2로 수정하여 UTF-8 입력파일을 실행했는데도 오류가 발생하면...
- 입력파일을 iconv를 이용하여 KS완성형으로 변환하여 위 옵션값을 1로 하여 실행한 후에
- 출력파일을 iconv를 이용하여 다시 UTF-8로 변환하면 문제가 해결됨!
$ iconv -f utf-8 -t cp949 test.txt > test_cp949.txt
$ ./index2018 test_cp949.txt output.txt
$ iconv -f utf-8 -t output.txt > output-utf8.txt
<참고> 형태소 분석 관련 논문 목록