자바 형태소 분석기 - 꼬꼬마분석기 설치와 사용
1. 설치
링크(다운로드)에서 꼬꼬마 형태소분석기 jar파일을 다운로드 할 수 있다.
jar 파일을 다운받고 사용할 자바 프로젝트에서 우클릭 한 후,
Build Path-Configure Build Path에 들어간다. (단축키 alt+enter)
Libraries에 들어가 add External JARs...를 클릭하고 다운받아놓은 .jar 파일을 추가한다.
프로젝트에 Referenced Libraies 아래 org.snu.ids.ha.jar가 추가되면 성공.
2. 사용
사용하기 위해 src아래 main을 포함한 클래스파일을 만들고
테스트를 위해 main() 아래 메소드 maTest()를 추가한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public static void maTest() { String string = "아버지가방에들어가셨다."; try { MorphemeAnalyzer ma = new MorphemeAnalyzer(); ma.createLogger(null); Timer timer = new Timer(); timer.start(); List<MExpression> ret = ma.analyze(string); timer.stop(); timer.printMsg("Time"); ret = ma.postProcess(ret); ret = ma.leaveJustBest(ret); List<Sentence> stl = ma.divideToSentences(ret); for( int i = 0; i < stl.size(); i++ ) { Sentence st = stl.get(i); System.out.println("============================================= " + st.getSentence()); for( int j = 0; j < st.size(); j++ ) { System.out.println(st.get(j)); } } ma.closeLogger(); } catch (Exception e) { e.printStackTrace(); } } | cs |
메인에서 메소드를 호출한다.
1 2 3 4 5 | public class KkmaExam { public static void main(String[] args) { maTest(); } | cs |
실행결과:
============================================= 아버지가방에 들어가셨다.
아버지가방에 => [0/아버지/NNG+3/가방/NNG+5/에/JKM]
들어가셨다. => [6/들어가/VV+9/시/EPH+10/었/EPT+10/다/EFN+11/./SF]
옆의 영어는 품사 태그표로 각 형태소마다 이름을 붙여준 것이다. (포스팅 하단참고)
띄어쓰기가 없지만 보통명사인 아버지, 가방을 잘 구별해내고
어간과 조사, 높임선어말어미와 과거시제선어말어미까지 완벽하게 구별해냈다.
참고로 R의 KoNLP에서는 위 문장을 넣으면 '아버지가방에들어가셨'를 명사로, '다'를 조사로 구분한다.
String string = "그가방은제것입니다. 손대지마시죠. 라고말하였다"; 를 넣어봤다.
============================================= 그 가방은 제 것입니다.
그 => [0/그/MDT]
가방은 => [1/가방/NNG+3/은/JX]
제 => [4/저/NP+5/의/JKG]
것입니다. => [5/것/NNB+6/이/VCP+7/ㅂ니다/EFN+9/./SF]
============================================= 손대지 마시죠.
손대지 => [11/손대지/NNG]
마시죠. => [14/마시/VV+16/죠/EFN+17/./SF]
============================================= 라고 말하였다
라고 => [19/라고/JX]
말하였다 => [22/말하/VV+24/였/EPT+25/다/EFN]
띄어쓰기를 알아서 해줌은 물론이고
'제'를 대명사 '저'와 조사로 나눠준 것. '입니다'를 이- ㅂ니다로 구별하는 것까지
'손대지' 말고는 거의 완벽하게 분석해냈음을 볼 수 있다.
String string = "이것도분석하는게가능한부분인가요오지고지리고돌리고인정?어인정";
============================================= 이것도 분석하는 게 가능한 부분인가요 오지고 지리고 돌리고 인정? 어 인정
이것도 => [0/이것/NP+2/도/JX]
분석하는 => [3/분석/NNG+5/하/XSV+6/는/ETD]
게 => [0/것/NNB+1/이/JKS]
가능한 => [2/가능/NNG+4/하/XSV+5/ㄴ/ETD]
부분인가요 => [0/부분/NNG+2/이/VCP+3/ㄴ가요/ECS]
오지고 => [0/오지/VV+2/고/ECE]
지리고 => [0/지리/VV+2/고/ECE]
돌리고 => [22/돌리/VV+24/고/ECE]
인정? => [25/인정/NNG+27/?/SF]
어 => [28/어/VV+29/어/ECS]
인정 => [29/인정/NNG]
ㅇㅈ? 어 ㅇㅈ
3. 추출
이걸 추출해내는 방법은 공식홈페이지에 잘 나와있는데
1 2 3 4 5 6 7 8 9 10 11 | // string to extract keywords String strToExtrtKwrd = "이것도분석하는게가능한부분인가요오지고지리고돌리고인정?어인정"; // init KeywordExtractor KeywordExtractor ke = new KeywordExtractor(); // extract keywords KeywordList kl = ke.extractKeyword(strToExtrtKwrd, true); // print result for( int i = 0; i < kl.size(); i++ ) { Keyword kwrd = kl.get(i); System.out.println(kwrd.getString() + "\t" + kwrd.getCnt()); } | cs |
위 코드를 넣으면
이것 1
부분 1
가능 1
분석 1
인정 2
이렇게 명사만 추출해준다.
한글 형태소 품사 (Part Of Speech, POS) 태그표
한글 형태소의 품사를 '체언, 용언, 관형사, 부사, 감탄사, 조사, 어미, 접사, 어근, 부호, 한글 이외'와 같이 나누고 각 세부 품사를 구분한다.
대분류 | 세종 품사 태그 | 심광섭 품사 태그 | KKMA 단일 태그 V 1.0 | |||||||
태그 | 설명 | Class | 설명 | 묶음1 | 묶음2 | 태그 | 설명 | 확률태그 | 저장사전 | |
체언 | NNG | 일반 명사 | NN | 명사 | N | NN | NNG | 보통 명사 | NNA | noun.dic |
NNP | 고유 명사 | NNP | 고유 명사 | |||||||
NNB | 의존 명사 | NX | 의존 명사 | NNB | 일반 의존 명사 | NNB | simple.dic | |||
UM | 단위 명사 | NNM | 단위 의존 명사 | |||||||
NR | 수사 | NU | 수사 | NR | NR | 수사 | NR | |||
NP | 대명사 | NP | 대명사 | NP | NP | 대명사 | NP | |||
용언 | VV | 동사 | VV | 동사 | V | VV | VV | 동사 | VV | verb.dic |
VA | 형용사 | AJ | 형용사 | VA | VA | 형용사 | VA | |||
VX | 보조 용언 | VX | 보조 동사 | VX | VXV | 보조 동사 | VX | |||
AX | 보조 형용사 | VXA | 보조 형용사 | |||||||
VCP | 긍정 지정사 | CP | 서술격 조사 '이다' | VC | VCP | 긍정 지정사, 서술격 조사 '이다' | VCP | raw.dic | ||
VCN | 부정 지정사 | VCN | 부정 지정사, 형용사 '아니다' | VCN | ||||||
관형사 | MM | 관형사 | DT | 일반 관형사 | M | MD | MDT | 일반 관형사 | MD | simple.dic |
DN | 수 관형사 | MDN | 수 관형사 | |||||||
부사 | MAG | 일반 부사 | AD | 부사 | MA | MAG | 일반 부사 | MAG | ||
MAJ | 접속 부사 | MAC | 접속 부사 | MAC | ||||||
감탄사 | IC | 감탄사 | EX | 감탄사 | I | IC | IC | 감탄사 | IC | |
조사 | JKS | 주격 조사 | JO | 조사 | J | JK | JKS | 주격 조사 | JKS | raw.dic |
JKC | 보격 조사 | JKC | 보격 조사 | JKC | ||||||
JKG | 관형격 조사 | JKG | 관형격 조사 | JKG | ||||||
JKO | 목적격 조사 | JKO | 목적격 조사 | JKO | ||||||
JKB | 부사격 조사 | JKM | 부사격 조사 | JKM | ||||||
JKV | 호격 조사 | JKI | 호격 조사 | JKI | ||||||
JKQ | 인용격 조사 | JKQ | 인용격 조사 | JKQ | ||||||
JX | 보조사 | JX | JX | 보조사 | JX | |||||
JC | 접속 조사 | JC | JC | 접속 조사 | JC | |||||
선어말 어미 | EP | 선어말 어미 | EP | 선어말 어미 | E | EP | EPH | 존칭 선어말 어미 | EP | |
EPT | 시제 선어말 어미 | |||||||||
EPP | 공손 선어말 어미 | |||||||||
어말 어미 | EF | 종결 어미 | EM | 어말 어미 | EF | EFN | 평서형 종결 어미 | EF | ||
EFQ | 의문형 종결 어미 | |||||||||
EFO | 명령형 종결 어미 | |||||||||
EFA | 청유형 종결 어미 | |||||||||
EFI | 감탄형 종결 어미 | |||||||||
EFR | 존칭형 종결 어미 | |||||||||
EC | 연결 어미 | EC | ECE | 대등 연결 어미 | EC | |||||
ECD | 의존적 연결 어미 | |||||||||
ECS | 보조적 연결 어미 | |||||||||
ETN | 명사형 전성 어미 | ET | ETN | 명사형 전성 어미 | ETN | |||||
ETM | 관형형 전성 어미 | ETD | 관형형 전성 어미 | ETD | ||||||
접두사 | XPN | 체언 접두사 | PF | 접두사 | X | XP | XPN | 체언 접두사 | XPN | simple.dic |
XPV | 용언 접두사 | XPV | ||||||||
접미사 | XSN | 명사 파생 접미사 | SN | 명사화 접미사 | XS | XSN | 명사 파생 접미사 | XSN | ||
XSV | 동사 파생 접미사 | SV | 동사화 접미사 | XSV | 동사 파생 접미사 | XSV | ||||
XSA | 형용사 파생 접미사 | SJ | 형용사화 접미사 | XSA | 형용사 파생 접미사 | XSA | ||||
SA | 부사화 접미사 | XSM | 부사 파생 접미사 | XSM | ||||||
SF | 기타 접미사 | XSO | 기타 접미사 | XSO | ||||||
어근 | XR | 어근 | XR | XR | XR | 어근 | XR | |||
부호 | SF | 마침표물음표,느낌표 | SY | 부호 외래어 | S | SF | SF | 마침표물음표,느낌표 | SF | Symbol class |
SP | 쉼표,가운뎃점,콜론,빗금 | SP | SP | 쉼표,가운뎃점,콜론,빗금 | SP | |||||
SS | 따옴표,괄호표,줄표 | SS | SS | 따옴표,괄호표,줄표 | SS | |||||
SE | 줄임표 | SE | SE | 줄임표 | SE | |||||
SO | 붙임표(물결,숨김,빠짐) | SO | SO | 붙임표(물결,숨김,빠짐) | SO | |||||
SW | 기타기호 (논리수학기호,화폐기호) | SW | SW | 기타기호 (논리수학기호,화폐기호) | SW | |||||
분석 불능 | NF | 명사추정범주 | NR | 미등록어 | U | UN | UN | 명사추정범주 | NNA | N/A |
NV | 용언추정범주 | UV | UV | 용언추정범주 | N/A | |||||
NA | 분석불능범주 | UE | UE | 분석불능범주 | N/A | |||||
한글 이외 | SL | 외국어 | O | OL | OL | 외국어 | NNA | |||
SH | 한자 | OH | OH | 한자 | NNA | |||||
SN | 숫자 | ON | ON | 숫자 | NR |
포스팅에 사용한 전체 코드:
KkmaExam.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | package Kkma; import java.util.List; import org.snu.ids.ha.index.Keyword; import org.snu.ids.ha.index.KeywordExtractor; import org.snu.ids.ha.index.KeywordList; import org.snu.ids.ha.ma.MExpression; import org.snu.ids.ha.ma.MorphemeAnalyzer; import org.snu.ids.ha.ma.Sentence; import org.snu.ids.ha.util.Timer; public class KkmaExam { public static void main(String[] args) { maTest(); // string to extract keywords String strToExtrtKwrd = "이것도분석하는게가능한부분인가요오지고지리고돌리고인정?어인정"; // init KeywordExtractor KeywordExtractor ke = new KeywordExtractor(); // extract keywords KeywordList kl = ke.extractKeyword(strToExtrtKwrd, true); // print result for( int i = 0; i < kl.size(); i++ ) { Keyword kwrd = kl.get(i); System.out.println(kwrd.getString() + "\t" + kwrd.getCnt()); } } public static void maTest() { String string = "이것도분석하는게가능한부분인가요오지고지리고돌리고인정?어인정"; try { MorphemeAnalyzer ma = new MorphemeAnalyzer(); ma.createLogger(null); Timer timer = new Timer(); timer.start(); List<MExpression> ret = ma.analyze(string); timer.stop(); timer.printMsg("Time"); ret = ma.postProcess(ret); ret = ma.leaveJustBest(ret); List<Sentence> stl = ma.divideToSentences(ret); for( int i = 0; i < stl.size(); i++ ) { Sentence st = stl.get(i); System.out.println("============================================= " + st.getSentence()); for( int j = 0; j < st.size(); j++ ) { System.out.println(st.get(j)); } } ma.closeLogger(); } catch (Exception e) { e.printStackTrace(); } } } | cs |