Nori 한글 형태소 분석기
한글은 형태의 변형이 매우 복잡한 언어입니다. 특히 복합어, 합성어 등이 많아 하나의 단어도 여러 어간으로 분리해야 하는 경우가 많아 한글을 형태소 분석을 하려면 반드시 한글 형태소 사전이 필요합니다.
Elasticsearch 6.6 버전부터 공식적으로 Nori(노리) 라고 하는 한글 형태소 분석기를 Elastic사에서 공식적으로 개발해서 지원을 하기 시작했습니다.
nori_tokenizer
Nori는 nori_tokenizer 토크나이저와 nori_part_of_speech, nori_readingform 토큰 필터를 제공합니다.
먼저 nori_tokenizer 토크 나이저를 사용해서 한글을 간단하게 테스트할 수 있습니다.
다음은 standard와 nori_tokenizer 를 비교해서 "동해물과 백두산이" 를 분석한 예제입니다.
# "standard" 토큰나이저로 "동해물과 백두산이"문장 분석
GET _analyze
{
"tokenizer": "standard",
"text": [
"동해물과 백두산이"
]
}
# "nori_tokenizer" 토큰나이저로 "동해물과 백두산이"문장 분석
GET _analyze
{
"tokenizer": "nori_tokenizer",
"text": [
"동해물과 백두산이"
]
}
Standard 토크나이저는 공백 외에 아무런 분리를 하지 못했지만 nori_tokenizer는 한국어 사전 정보를 이용해 "token" : "동해", "token" : "산" 같은 단어를 분리한 것을 확인할 수 있습니다.
nori_tokenizer 에는 다음과 같은 옵션들이 있습니다.
- user_dictionary : 사용자 사전이 저장된 파일의 경로를 입력합니다.
- user_dictionary_rules : 사용자 정의 사전을 배열로 입력합니다.
- decompound_mode : 합성어의 저장 방식을 결정합니다. 다음 3개의 값을 사용 가능합니다.
- none : 어근을 분리하지 않고 완성된 합성어만 저장합니다.
- discard (디폴트) : 합성어를 분리하여 각 어근만 저장합니다.
- mixed : 어근과 합성어를 모두 저장합니다.
user_dictionary는 다른 애널라이저들과 마찬가지로 config 디렉토리의 상대 경로를 입력하며 변경 시 인덱스를 _close / _open 하면 반영됩니다.
사전의 단어들에는 우선순위가 있으며 문장 "동해물과" 에서는 "동해" 가 가장 우선순위가 높아 "동해" 가 먼저 추출되고 다시 "물" 그리고 "과" 가 추출되어 "동해"+"물"+"과" 같은 형태가 됩니다. user_dictionary 경로에 있는 사전 파일이나 user_dictionary_rules 설정값에 단어만 나열해 주면 이 단어들을 가장 우선으로 추출합니다.
다음은 my_nori 인덱스에 user_dictionary_rules옵션을 이용하여 사용자 사전 "해물" 을 지정하고 "동해물과" 를 분석한 예제입니다.
# my_nori 인덱스에 "해물"사전을 추가한 my_nori_tokenizer 생성
PUT my_nori
{
"settings": {
"analysis": {
"tokenizer": {
"my_nori_tokenizer": {
"type": "nori_tokenizer",
"user_dictionary_rules": [
"해물"
]
}
}
}
}
}
# my_nori_tokenizer 토크나이저로 "동해물과" 분석
GET my_nori/_analyze
{
"tokenizer": "my_nori_tokenizer",
"text": [
"동해물과"
]
}
이렇게 사용자 사전에 "해물" 이라는 단어를 추가하면 "동해물과" 는 "동"+"해물"+"과" 로 분석이 되어 이 문장이 포함된 도큐먼트는 "동해" 로는 검색이 되지 않고 "해물"로 검색이 됩니다.
다음은 decompound_mode 의 3가지 옵션이 문장 "백두산이"을 각각 어떻게 분석되는지 확인하는 예제입니다.
PUT my_nori
{
"settings": {
"analysis": {
"tokenizer": {
"nori_none": {
"type": "nori_tokenizer",
"decompound_mode": "none"
},
"nori_discard": {
"type": "nori_tokenizer",
"decompound_mode": "discard"
},
"nori_mixed": {
"type": "nori_tokenizer",
"decompound_mode": "mixed"
}
}
}
}
}
# nori_none 토크나이저로 "백두산이" 분석 -> 어근을 분리하지 않고 합성어만 저장 - 백두산, 이
GET my_nori/_analyze
{
"tokenizer": "nori_none",
"text": [ "백두산이" ]
}
# nori_discard 토크나이저로 "백두산이" 분석 -> 합성어를 분리하여 각 어근만 저장 default - 백두, 산, 이
GET my_nori/_analyze
{
"tokenizer": "nori_discard",
"text": [ "백두산이" ]
}
# nori_mixed 토크나이저로 "백두산이" 분석 -> 어근과 합성어 둘 다 저장 - 백두산, 백두, 산, 이
GET my_nori/_analyze
{
"tokenizer": "nori_mixed",
"text": [ "백두산이" ]
}
nori_part_of_speech 와 품사 정보
한글 검색에서는 보통 명사, 동명사 정도만을 검색하고 조사, 형용사 등은 제거하는 것이 바람직합니다.
nori_part_of_speech 토큰 필터를 이용해서 제거할 품사(POS - Part Of Speech) 정보의 지정이 가능하며, 옵션 stoptags 값에 배열로 제외할 품사 코드를 나열해서 입력해서 사용합니다. 다음은 품사 코드의 일부 정보들입니다.
이 외의 품사 코드는 출처에 명시된 정보 페이지에서 찾을 수 있습니다. stoptags의 디폴트 값은 다음과 같습니다.
"stoptags": [
"E", "IC", "J", "MAG", "MAJ",
"MM", "SP", "SSC", "SSO", "SC",
"SE", "XPN", "XSA", "XSN", "XSV",
"UNA", "NA", "VSV"
]
다음은 my_pos 인덱스에 수사(NR)를 제거하도록 stoptags를 지정하고 문장 "다섯아이가"를 분석한 예제입니다.
# my_pos 인덱스에 수사를 제거하고 my_pos_f 토큰 필터 지정
PUT my_pos
{
"settings": {
"index": {
"analysis": {
"filter": {
"my_pos_f": {
"type": "nori_part_of_speech",
"stoptags": [
"NR"
]
}
}
}
}
}
}
# my_pos_f 토큰 필터로 "다섯아이가" 분석
GET my_pos/_analyze
{
"tokenizer": "nori_tokenizer",
"filter": [
"my_pos_f"
],
"text": "다섯아이가"
}
본래 "다섯"+"아이"+"가" 로 분석되어야 할 문장에서 수사인 "다섯"이 제거된 것을 확인할 수 있습니다.
nori_readingform
nori_readingform 토큰 필터는 한자로 된 단어를 한글로 바꾸어 저장을 합니다. 별도의 옵션 없이 토큰 필터로 명시하면 바로 적용이 가능합니다.
# nori_readingform 토큰필터로 "춘하추동"분석
GET _analyze
{
"tokenizer": "nori_tokenizer",
"filter": [
"nori_readingform"
],
"text": "春夏秋冬"
}
# 결과
{
"tokens" : [
{
"token" : "춘하추동",
"start_offset" : 0,
"end_offset" : 4,
"type" : "word",
"position" : 0
}
]
}
explain : true 옵션
query 또는 _analuze API 에서 "explain": true 옵션을 추가하면 분석된 한글 형태소들의 품사 정보를 같이 볼 수 있습니다. explain 옵션은 nori 외에도 대부분의 애널라이저나 쿼리에서 사용하면 확장된 정보를 보여줍니다.
# explain : true 옵션 사용
GET _analyze
{
"tokenizer": "nori_tokenizer",
"text": "동해물과 백두산이",
"explain": true
}
마무리
이번 포스팅에서 한글 형태소 분석기인 노리에 대해서 알아보았습니다. 다음 장에서는 elasticsearch에서 가장 많은 시간이 소요되는 인덱스의 세팅 및 매핑 설정 방법과 다양한 형태의 필드에 대해 알아보겠습니다.
'ELK stack' 카테고리의 다른 글
[ELK] 7. elasticsearch 인덱스 매핑과 데이터 타입(2) - 날짜, 객체, 위치 정보 (0) | 2022.06.28 |
---|---|
[ELK] 6. elasticsearch 인덱스 매핑과 데이터 타입(1) - 문자열, 숫자 (0) | 2022.06.28 |
[ELK] 4. elasticsearch 데이터 색인과 텍스트 분석 (0) | 2022.06.26 |
[ELK] 3. elasticsearch query DSL (0) | 2022.06.24 |
[ELK] 2. Elasticsearch Document CRUD, Bulk, Search (0) | 2022.06.23 |
댓글