한글 NLP with Python
한국어 품사및 태그
아래의 태그는 ‘세종 계획’에서 나온 태그를 기준으로 하였습니다.
각 library들마다 약간씩 이름이 다를 수 있습니다. 자세한 각 라이브러리별 품사에 대한 태킹을 여기를 눌러주시기 바랍니다.
먼저 용어부터 정리를 하면 다음과 같습니다.
- 체언: 명사, 대명사, 수사 -> 세 품사를 묶어 체언이라고 함 (예. 사람, 학교, 초등학교, 나, 너, 이것, 하나, 둘째, etc)
- 용언: 동사, 형용사 두 품사를 묶어 용언이라고 함 (예. 먹다, 달리다, 예쁘다, 착하다)
- 형태소: 의미를 가진 최소 단위. ‘사람’, ‘나’, ‘하나’ 같은 말은 더 이상 쪼개지지 않습니다.
- 접사: 독립적으로 쓰이지 못하고, 다른 말에 붙어 새로운 단어를 만드는 형태소. (예.
풋
사과,햇
과일, 지우개
, 점쟁이
) - 어근: 단어에서 실질적 의미(중심이 되는)를 나타내는 부분. (
사람
,학교
,나
, 풋사과
,점
쟁이,초등 학교
,깨끗
하다 )
tag | name | description | example |
---|---|---|---|
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도 같이 설치를 합니다.
MECAB 설치
KoNLPy에서 쉽게 설치하는 방법이 있는데 (mecab.sh사용) 해당 방식으로 설치시
낮은 버젼의 Mecab이 설치가 되며, 추후 사전추가시 어려움이 생길수 있습니다.
Mecab은 따로 최신버젼을 설치를 합니다.
MECAB-KO 형태소 분석기 엔진 설치
은전한닢 프로젝트에서 만든 MeCab의 fork 프로젝트이며 한국어의 특성에 맞는 기능을 추가하였습니다.
다운로드 페이지에서 최신 버젼을 다운로드 할수 있습니다.
추가적으로 .so 파일들을 연결시켜주기 위해서 sudo vi /etc/ld.so.conf
으로 열고..
/usr/local/lib
를 추가합니다.
마지막으로 sudo ldconfig
를 실행.
버젼을 확인합니다.
MECAB-KO 사전 설치
다운로드 페이지 최신 사전 파일을 다운로드 받을수 있습니다.
설치는 기본적으로 /usr/local/lib/mecab/dic/mecab-ko-dic
에 설치 됩니다.
Dependencies를 설치합니다.
MeCAB-KO-DIC을 설치합니다.
MECAB-KO 설치 확인 테스트
형태소 분석 비교
아버지가방에들어가신다
아버지가방에들어가신다
를 갖고서 각각의 사전에 대한 spacing algorithm을 비교합니다.
아버지가 방에 들어 가신다
이렇게 제대로 해석한것은 Mecab이며,
Kkma, Twitter는 아버지 가방에 들어 가신다
라고 분석했습니다.
Hannanum | Kkma | Komoran | Mecab | |
---|---|---|---|---|
아버지가방에들어가 / N | 아버지 / NNG | 아버지가방에들어가신다 / NNP | 아버지 / NNG | 아버지 / Noun |
이 / J | 가방 / | 가 / JKS | 가방 / Noun | |
시ㄴ다 / E | 에 / JKM | 방 / NNG | 에 / Josa | |
들어가 / VV | 에 / JKB | 들어가신 / Verb | ||
시 / EPH | 들어가 / VV | 다 / Eomi | ||
ㄴ다 / EFN | 신다 / EP+EC |
머리를 감기다
머리를 감기다
에서는 감기가 병을 가르키는 명사 감기
를 가르키는 것인지, 동사 감기다
를 말하는 것인지 구분합니다.
궁극적으로 Komoran 그리고 Mecab 만 감기
를 동사로 제대로 구분을 해냈습니다.
Hannanum | Kkma | Komoran | Mecab | |
---|---|---|---|---|
머리 / N | 머리 / NNG | 머리 / NNG | 머리 / NNG | 머리 / Noun |
를 / J | 를 / JKO | 를 / JKO | 를 / JKO | 를 / Josa |
감기 / N | 감기 / NNG | 감기 / VV | 감기 / VV | 감기 / Noun |
이 / J | 이 / VCP | |||
다/ E | 다 / EFN | 다 / EC | 다 / EC | 다 / Josa |
처리 속도 비교
중성자별(neuron star)은 초신성 폭발 직후 무거운 별이 중력붕괴하여 만들어진 밀집성의 일종이다
라는 문장을 갖고서 속도 측정을 하였습니다.
Hannanum | Kkma | Komoran | Mecab | ||
---|---|---|---|---|---|
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 해줄수 있습니다.
문장을 형태소로 변환
Hannanum
Kkma
Komoron
Mecab
POS (Part of speech) Tags
최근 Twitter 또는 인스타그램등등의 SNS에서 사용될 만한 문장으로 예제를 돌려보았습니다.
특히 Twitter 사전의 경우 @누구
또는 #태그
를 정확하게 SNS에서 사용하는 hashtag로 인식을 했으며,
그 외의 사전은 먹스타그램
처럼 하나의 형태소별로 쪼개놓을 것을 알 수 있습니다.
Hannanum
Kkma
Komoran
Mecab
단어만 추출
단어를 추출하는데 크게 문제는 없지만, Kkma의 경우 명사 + 명사 로 만들어진 부분을 중복해서 집어내고 있으며,
Mecab의 경우 ‘인스타그램’이라는 최신 단어를 분리시키는 단점들을 보이고 있습니다.
Hannanum
Kkma
Komoron
Mecab
사전 추가하기
MeCAB 사전 추가
먼저 mecab-ko-dic
가 설치된 곳으로 이동합니다.
만약 없으면 “MECAB-KO 사전 설치” 부분을 다시 보고 설치를 합니다.
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
에는 다음과 같이 단어를 추가할 수 있습니다.
추가후에 add-userdic.sh
를 실행시킵니다.
마지막으로 설치를 합니다.
마지막으로 ‘가모라’가 인명으로 하나의 이름으로 인식되는지 확인해봅니다.
아래에서처럼 ‘가모라’는 하나의 단어로 인식이 잘 됩니다.
twitter-korean-text에 사전 추가
사전에 Marvel Comics 영울들의 이름을 추가시켜보도록 하겠습니다.
먼저 twitter-korean-text 를 git에서 clone을 합니다.
IntelliJ Idea를 열고 위의 프로젝트를 엽니다.
twitter-korean-text/src/main/resources/com/twitter/penguin/korean/util 위치에 보면 다양한 사전이 txt파일 형식으로 저장이 되어 있습니다.
비교를 하기 위해서 먼저 테스트 케이스를 만듭니다.
/src/test/scala/com/twitter/penguin/korean/MarvelTest.scala 에 다음과 같은 코드를 넣습니다.
실행시킨 결과는 아래와 같으며, 앤더슨조, 헐크버스터, 자이언트루퍼를 하나의 단어가 아니라 독립된 단어로 형태로를 구분하였습니다.
사전에 “앤더슨조”, “헐크버스터”, “자이언트루퍼”를 추가시키겠습니다.
twitter-korean-text/src/main/scala/com/twitter/penguin/korean/tools/DeduplicateAndSortDictionaries.scala 파일을 열고,
DeduplicateAndSortDictionaries 를 실행해서 사전을 업데이터 해줍니다.
다시한번 MarvelTest 실행시켜서 테스트 합니다.
이번에는 “앤더슨조”, “헐크버스터”, 그리고, “자이언트루퍼”를 하나의 대명사로 인식을 하였습니다.
Maven Project에서 package를 실행합니다.
만들어진 jar 파일을 konlpy로 옮겨줍니다.
현재 Twitter에 사전추가는 되지만 추가된 사전을 KoNLPy와 연동시키는 부분에 관해서는 KoNLPy의 소스코드를 변경이 필요하다는 결론을 냈습니다.
KoNLPy에서는 jar파일로 Twitter-korean-text를 갖고 있습니다.
문제는 버젼이 낮으며 업데이트가 안되어 있는 상태입니다.