현재 개발중인 검색 시스템에서 형태소 분석기를 사용해야 했다.
유저가 입력하는 다양한 형태의 검색어에서 keyword를 추출한 뒤 검색 알고리즘에 활용하기 위해서이다.
보통 ML이 활용되는 경우 python 패키지(이 경우 KoNLPy)를 활용할 수 있지만 형태소 분석 task만을 담당하는 서버를 따로 만드는 비용이 크다고 생각했고 Java로 개발 중인 서버에서 형태소를 분석하기 위한 방법을 찾아보았다.
https://github.com/open-korean-text/open-korean-text
KoNLPy는 OKT를 활용하여 python에서 활용할 수 있게 만든 패키지였다.
OKT는 Scala와 Java로 개발된 오픈소스 한국어 처리기로 정규화, 토큰화, 어근화, 어구 추출 등을 지원한다.
즉, python에서 Java 클래스가 포함된 KoNLPy를 사용하기 위해 JDK와 JPype라는, python에서 자바 클래스를 사용할 수 있게 해주는 패키지를 설치하는 것이다.
OKT의 Github Readme에는 Maven을 이용한 사용법이 나와있었지만, 나는 SpringBoot에서 Gradle을 빌드 도구로 사용하고 있었기 때문에 Gradle을 이용한 사용기를 공유하겠다.
https://jar-download.com/artifacts/org.openkoreantext/open-korean-text/2.1.0/source-code
위 링크로 이동하여 open-korean-text 2.1.0 버전을 다운받아 압축을 풀고 이를 프로젝트 내 lib 폴더로 이동시킨다.
repositories {
maven { url 'https://jitpack.io' }
}
dependencies {
implementation files('lib/open-korean-text-2.1.0.jar')
implementation 'org.scala-lang:scala-library:2.12.4'
implementation 'com.twitter.penguin:korean-text:4.4.4'
}
scala와 트위터 한국어 라이브러리를 추가하는 과정이다.
위와 같이 build.gradle에 설정을 추가해준다.
import org.openkoreantext.processor.KoreanTokenJava;
import org.openkoreantext.processor.OpenKoreanTextProcessorJava;
import org.openkoreantext.processor.tokenizer.KoreanTokenizer;
import scala.collection.Seq;
public class Test {
public static void main() {
String text = "한국어를 처리하는 예시입니닼ㅋㅋㅋㅋㅋ #한국어";
// Normalize
CharSequence normalized = OpenKoreanTextProcessorJava.normalize(text);
// 한국어를 처리하는 예시입니다ㅋㅋ #한국어
// Tokenize
Seq<KoreanTokenizer.KoreanToken> tokens = OpenKoreanTextProcessorJava.tokenize(normalized);
// [한국어, 를, 처리, 하는, 예시, 입니, 다, ㅋㅋ, #한국어]
List<KoreanTokenJava> tokenList = OpenKoreanTextProcessorJava.tokensToJavaKoreanTokenList(tokens);
// [한국어(Noun: 0, 3), 를(Josa: 3, 1), 처리(Noun: 5, 2), 하는(Verb(하다): 7, 2), 예시(Noun: 10, 2), 입니다(Adjective(이다): 12, 3), ㅋㅋㅋ(KoreanParticle: 15, 3), #한국어(Hashtag: 19, 4)]
// Phrase Extraction
List<KoreanPhraseExtractor.KoreanPhrase> phrases = OpenKoreanTextProcessorJava.extractPhrases(tokens, true, true);
// [한국어(Noun: 0, 3), 처리(Noun: 5, 2), 처리하는 예시(Noun: 5, 7), 예시(Noun: 10, 2), #한국어(Hashtag: 18, 4)]
}
}
위와 같이 분석 결과를 활용할 수 있다:)
형태소 분석을 목적으로 사용했다 보니 어느정도 수준으로 구분해는지 궁금해졌다.
내부 구조를 분석해보니 형태소 종류는 아래와 같은 enum 타입으로 제공하고 있었다.
public enum KoreanPosJava {
// Word leved POS
Noun, Verb, Adjective,
Adverb, Determiner, Exclamation,
Josa, Eomi, PreEomi, Conjunction,
Modifier, VerbPrefix, Suffix, Unknown,
// Chunk level POS
Korean, Foreign, Number, KoreanParticle, Alpha,
Punctuation, Hashtag, ScreenName,
Email, URL, CashTag,
// Functional POS
Space, Others,
ProperNoun
}
출처
https://baboototo.github.io/springboot-okt/