Nori 분석기란?
Elasticsearch Nori 분석기는 한국어 텍스트를 처리하기 위해 개발된
Elasticsearch의 기본 제공 분석기이다.
Nori 분석기는 주로 다음과 같은 작업을 수행한다.
1. 토큰화(Tokenization)
한국어 문장을 형태소 단위로 분리한다.
형태소는 문장에서 의미를 갖는 최소 단위로서, 일반적으로 명사, 동사, 형용사 등이 될 수 있다.
Nori는 형태소 분석을 위해 색인 전에 형태소 단위로 문장을 쪼갠다.
2. 어휘 형태소 분석(Lexical Token Analysis)
Nori는 어휘 사전을 사용하여 형태소를 분석한다.
어휘 사전은 일반적인 단어와 함께 한국어의 특수한 언어 현상을 처리하는 데 사용되는 사전이다.
Nori는 품사 태깅, 불규칙 활용 형태소 처리, 조사의 결합 등을 수행하여 언어의 복잡성을 처리한다.
3. 불용어 처리(Stopword Handling)
Nori 분석기는 Elasticsearch에서 제공하는 기본적인 불용어(stopword) 처리 기능도 포함하고 있다.
불용어는 문서에서 제거할 단어로, 예를 들어 "는", "을", "이"와 같은 한국어 조사가 불용어로 처리될 수 있다.
Nori 분석기 설치 방법
OS 내에 이미 Elasticsearch 가 설치되어 있다고 가정하고 Nori 분석기 설치 방법을 알아보자.
현재 테스트로 진행할 OS는 Ubuntu 20.04 버전에 ES 7.17.7 버전이다.
일단, /usr/share/elasticsearch/bin 으로 이동해 준다.
그리고 아래와 같이 analysis-nori 플러그인을 설치해 준다.
./elasticsearch-plugin install analysis-nori
ES node 가 운영되고 있다면,
새로운 Nori 분석기를 적용해 주기 위해서는 재시작이 필요하다.
Rolling Restart를 통해서 ES 가 Nori 분석기를 적용할 수 있게 만들어주자.
Nori 분석기가 잘 설치되었는지 확인하기 위해서는
아래의 경로로 이동해 Nori 분석기를 찾아준다.
/usr/share/elasticsearch/plugins
아래와 같이 analysis-nori 디렉터리가 존재하면 설치가 완료된 것이다.
그럼 이제 실제로 Kibana dev tool에서 Nori 분석기를 적용하기 위해 테스트를 진행해 보자.
첫 번째로 기본 토크나이저로 "사랑이란 아프려고 하는 거죠"를 분석해 보자.
[기본 토크나이저]
GET _analyze
{
"tokenizer": "standard",
"text": [
"사랑이란 아프려고 하는거죠"
],
"explain" : true
}
[결과]
{
"detail" : {
"custom_analyzer" : true,
"charfilters" : [ ],
"tokenizer" : {
"name" : "standard",
"tokens" : [
{
"token" : "사랑이란",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<HANGUL>",
"position" : 0,
"bytes" : "[ec 82 ac eb 9e 91 ec 9d b4 eb 9e 80]",
"positionLength" : 1,
"termFrequency" : 1
},
{
"token" : "아프려고",
"start_offset" : 5,
"end_offset" : 9,
"type" : "<HANGUL>",
"position" : 1,
"bytes" : "[ec 95 84 ed 94 84 eb a0 a4 ea b3 a0]",
"positionLength" : 1,
"termFrequency" : 1
},
{
"token" : "하는거죠",
"start_offset" : 10,
"end_offset" : 14,
"type" : "<HANGUL>",
"position" : 2,
"bytes" : "[ed 95 98 eb 8a 94 ea b1 b0 ec a3 a0]",
"positionLength" : 1,
"termFrequency" : 1
}
]
},
"tokenfilters" : [ ]
}
}
[Nori 토크나이저]
GET _analyze
{
"tokenizer": "nori_tokenizer",
"text": [
"사랑이란 아프려고 하는거죠"
],
"explain" : true
}
[결과]
{
"detail" : {
"custom_analyzer" : true,
"charfilters" : [ ],
"tokenizer" : {
"name" : "nori_tokenizer",
"tokens" : [
{
"token" : "사랑",
"start_offset" : 0,
"end_offset" : 2,
"type" : "word",
"position" : 0,
"bytes" : "[ec 82 ac eb 9e 91]",
"leftPOS" : "NNG(General Noun)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "NNG(General Noun)",
"termFrequency" : 1
},
{
"token" : "이란",
"start_offset" : 2,
"end_offset" : 4,
"type" : "word",
"position" : 1,
"bytes" : "[ec 9d b4 eb 9e 80]",
"leftPOS" : "J(Ending Particle)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "J(Ending Particle)",
"termFrequency" : 1
},
{
"token" : "아프",
"start_offset" : 5,
"end_offset" : 7,
"type" : "word",
"position" : 2,
"bytes" : "[ec 95 84 ed 94 84]",
"leftPOS" : "VA(Adjective)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "VA(Adjective)",
"termFrequency" : 1
},
{
"token" : "려고",
"start_offset" : 7,
"end_offset" : 9,
"type" : "word",
"position" : 3,
"bytes" : "[eb a0 a4 ea b3 a0]",
"leftPOS" : "E(Verbal endings)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "E(Verbal endings)",
"termFrequency" : 1
},
{
"token" : "하",
"start_offset" : 10,
"end_offset" : 11,
"type" : "word",
"position" : 4,
"bytes" : "[ed 95 98]",
"leftPOS" : "VV(Verb)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "VV(Verb)",
"termFrequency" : 1
},
{
"token" : "는",
"start_offset" : 11,
"end_offset" : 12,
"type" : "word",
"position" : 5,
"bytes" : "[eb 8a 94]",
"leftPOS" : "E(Verbal endings)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "E(Verbal endings)",
"termFrequency" : 1
},
{
"token" : "것",
"start_offset" : 12,
"end_offset" : 13,
"type" : "word",
"position" : 6,
"bytes" : "[ea b2 83]",
"leftPOS" : "NNB(Dependent noun)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "NNB(Dependent noun)",
"termFrequency" : 1
},
{
"token" : "이",
"start_offset" : 13,
"end_offset" : 14,
"type" : "word",
"position" : 7,
"bytes" : "[ec 9d b4]",
"leftPOS" : "VCP(Positive designator)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "VCP(Positive designator)",
"termFrequency" : 1
},
{
"token" : "죠",
"start_offset" : 13,
"end_offset" : 14,
"type" : "word",
"position" : 8,
"bytes" : "[ec a3 a0]",
"leftPOS" : "E(Verbal endings)",
"morphemes" : null,
"posType" : "MORPHEME",
"positionLength" : 1,
"reading" : null,
"rightPOS" : "E(Verbal endings)",
"termFrequency" : 1
}
]
},
"tokenfilters" : [ ]
}
}
위와 같이 결과를 본다면, 기본 토크나이저와 Nori 토크나이저가 각 단어를
토큰화하는 방식이 완전히 다른 것을 볼 수 있다.
기본 토크나이저에서는 단어자체의 품사정보가 나오지 않는다.
하지만, Nori 토크나이저를 보면,
"leftPOS", "rightPOS"에 품사정보가 존재하는 것을 볼 수 있다.
Nori 분석기가 제공하는 품사 태그는 아래와 같다.
이와 같이 한글데이터가 존재하는 검색엔진을 구성하고 싶다면,
Nori 분석기를 설치해서 검색엔진을 구성하는 게 바람직하다.
'Elasticsearch' 카테고리의 다른 글
[Elasticsearch] maximum shards open error (0) | 2023.12.27 |
---|---|
[Elasticsearch] 검색성능 비교 (0) | 2023.05.15 |
[Elasticsearch] Disk-based shard allocation (1) | 2023.03.02 |
[Elasticsearch] text, keyword 타입 (0) | 2023.03.02 |
[Elasticsearch] 검색(Search) (0) | 2023.02.28 |