본문 바로가기
DB

형태소 분석기 설치

by 동기 2023. 1. 8.
반응형
  • thumbnail

Stemming

검색을 할 때는 보통 이런 문법에 따른 단어의 변형에 상관 없이 검색이 가능해야 하기 때문에 텍스트 데이터를 분석할 때 각각의 텀에 있는 단어들을 기본 형태인 어간을 추출하는 과정을 진행해야 합니다. 이 과정을 보통 어간 추출 또는 형태소 분석 이라고 하며 영어로는 stemming 이라고 합니다. 그리고 형태소 분석을 하는 도구를 형태소 분석기, 영어로는 stemmer 라고 합니다.

Nori 개요

Elasticsearch 6.6 버전 부터 공식적으로 Nori(노리) 라고 하는 한글 형태소 분석기를 Elastic사에서 공식적으로 개발해서 지원을 하기 시작했습니다. 특이하게 nori는 프랑스 엔지니어인 Jim Ferenczi 에 의해 처음 개발이 되었습니다. Jim 은 아파치 루씬의 커미터이며 Elasticsearch의 일본어 형태소 분석기인 Kuromoji(구로모지) 역시 Jim 이 처음 개발했습니다. Nori 는 은전한닢에서 사용하는 mecab-ko-dic 사전을 재 가공 하여 사용하고 있습니다.


1. Nori 설치

Nori 를 사용하기 위해서는 먼저 elasticsearch에 analysis-nori 플러그인을 설치해야 합니다. Elasticsearch 홈 디렉토리에서 다음 명령을 실행하면 버전에 맞는 nori 플러그인을 받아서 자동으로 설치합니다.

elasticsearch home 경로로 이동

cd /usr/share/elasticsearch

설치

sudo bin/elasticsearch-plugin install analysis-nori

Elasticsearch 재시작

sudo systemctl restart elasticsearch.service

Nori는

  • nori_tokenizer 토크나이저와
  • nori_part_of_speech, nori_readingform 토큰 필터를 제공합니다.

2. 토크나이저 비교해보기

기본인 standard와 nori_tokenizer 를 비교해 보겠습니다

standard 토크나이저는 공백 외에 아무런 분리를 하지 못했지만 nori_tokenizer는 한국어 사전 정보를 이용해 "token" : "순간", "token" : "울산" 같은 단어를 분리 한 것을 확인할 수 있습니다.

3. 사용자 정의 사전 이용해보기

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옵션을 이용하여 사용자 사전 "순간이동기" 를 지정하고 "순간이동기를" 을 분석한 예제입니다.

1. Tokenizer 생성

nori-test-index 인덱스에 “순간이동기”사전을 추가한 test_nori_tokenizer 생성

  • put request
sudo curl -XPUT --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://[hostname]:9200/nori-test-index" -H 'Content-Type: application/json' -d'{"settings": {"analysis": {"tokenizer": {"test_nori_tokenizer": {"type": "nori_tokenizer","user_dictionary_rules": ["순간이동기"]}}}}}'

  • response
{"acknowledged":true,"shards_acknowledged":true,"index":"nori-test-index"}

2. 결과 확인

test_nori_tokenizer 토크나이저로 “순간이동기를” 분석 결과

  • request
sudo curl -XGET --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://build:9200/nori-test-index/_analyze?pretty" -H 'Content-Type: application/json' -d'{"tokenizer":"test_nori_tokenizer", "text":"이동기가 순간이동기를 통해 울산밖으로 나왔다"}'
  • response
{
  "tokens" : [
    {
      "token" : "이동기",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "가",
      "start_offset" : 3,
      "end_offset" : 4,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "순간이동기",
      "start_offset" : 5,
      "end_offset" : 10,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "를",
      "start_offset" : 10,
      "end_offset" : 11,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "통하",
      "start_offset" : 12,
      "end_offset" : 14,
      "type" : "word",
      "position" : 4
    },
    {
      "token" : "아",
      "start_offset" : 12,
      "end_offset" : 14,
      "type" : "word",
      "position" : 5
    },
    {
      "token" : "울산",
      "start_offset" : 15,
      "end_offset" : 17,
      "type" : "word",
      "position" : 6
    },
    {
      "token" : "밖",
      "start_offset" : 17,
      "end_offset" : 18,
      "type" : "word",
      "position" : 7
    },
    {
      "token" : "으로",
      "start_offset" : 18,
      "end_offset" : 20,
      "type" : "word",
      "position" : 8
    },
    {
      "token" : "나오",
      "start_offset" : 21,
      "end_offset" : 23,
      "type" : "word",
      "position" : 9
    },
    {
      "token" : "았",
      "start_offset" : 21,
      "end_offset" : 23,
      "type" : "word",
      "position" : 10
    },
    {
      "token" : "다",
      "start_offset" : 23,
      "end_offset" : 24,
      "type" : "word",
      "position" : 11
    }
  ]
}

이렇게 사용자 사전에 “순간이동기”라는 단어를 추가하면 "순간이동기를"은 “순간이동기”+”를" 로 분석이 되어 이 문장이 포함된 도큐먼트는 “순간”,”동기” 로는 검색이 되지 않고 “순간이동기” 로 검색이 됩니다.

  • nori 제거
    sudo bin/elasticsearch-plugin remove analysis-nori


참고

https://esbook.kimjmin.net/06-text-analysis/6.7-stemming/6.7.2-nori

반응형

'DB' 카테고리의 다른 글

PostgreSQL 설치/설정/백업/복구  (4) 2023.12.27
mysql설치/설정  (0) 2023.05.18
Elasticsearch 설치  (0) 2023.01.08
엘라스틱 스택 다운,설치  (0) 2023.01.08

댓글