PONI's 좋은 개발자

[Elasticsearch] Analyzer(nori, nGram) 본문

ETL/Elasticsearch

[Elasticsearch] Analyzer(nori, nGram)

PONI 2023. 6. 1. 13:41
반응형

📋Analyzer

Elasticsearch는 색인(indexing)할 때 입력된 데이터는 term 으로 추출하기 위한 과정을 거치는데 이 과정을 Analyzer 라고 합니다.

Analyzer 는 하나의 Tokenizer 와 0 개 이상의 Token Filter 로 구성되어 있습니다.

Tokenizer 는 입력된 데이터를 토큰으로 분리하는 작업을 하고 Token Filter 는 Tokenizer 로 분리된 토큰들에 필터를 적용하는 역할을 합니다.

이렇게 TokenizerToken Filter 과정을 거치면 검색을 위한 term이 추출됩니다.

Analyzer 는 하나의 Tokenizer 와 다수의 Filter 로 구성하고, Filter 사용을 하지 않더라도 Tokenizer 는 반드시 선언이 되어야 합니다.

 

구성요소

Analyzer 는 다음 세 가지 요소로 구성됩니다.

  • Tokenizer : 해당 단어를 분리하는 작업
  • Token Filter : 분리된 단어들을 검색 가능하도록 가공하는 작업
  • Char Filter : 문장 변환하는 작업

 

📌노리(nori) 한글 형태소 분석기

Elasticsearch 에서 공식적으로 제공하는 한글 형태소 분석기입니다.1개의 Tokenizer 와 2개의 Token Filter 를 가지고 있습니다.

 

구성요소

  • Tokenizer : nori_tokenizer
  • Token Filter : nori_part_of_speech, nori_readingform
  • Char Filter : X

nori_tokenizer

  • decompound_mode: 복합 토큰에 대한 처리 방법을 설정
    • node : 처리 하지 않음 ex) 부산항, 부산역
    • discard : 복합 토큰을 분해하고 분석 대상 토큰을 버림 ex) 부산항 -> 부산, 항
    • mixed : 분석 대상 토큰을 유지하면서 복합 토큰을 분해 ex) 서울역 -> 서울, 서울, 역
  • discard_punctuation : 출력할 때, 구두점(쉼표, 마침표, 물음표 등)을 삭제할지 여부, 기본값은 True
  • user_dictionary : 사용자 지정 명사를 기본 사전에 추가 가능

 

nori_part_of_speech Token Filter : 품사 태그 집합과 일치하는 토큰을 제거

 

 

<사용예시>

{
  "settings": {
    "analysis": {
      "tokenizer": {
        "nori_none_token": {
          "type": "nori_tokenizer",
          "decompound_mode": "none"
        },
        "nori_discard_token": {
          "type": "nori_tokenizer",
          "decompound_mode": "discard"
        },
        "nori_mixed_token": {
          "type": "nori_tokenizer",
          "decompound_mode": "mixed"
        }
      },
      "analyzer": {
        "nori_none": {
          "type": "custom",
          "tokenizer": "nori_none_token",
          "filter": ["lowercase", "nori_posfilter", "stop_filter", "synonym_filter"]
        },
        "nori_discard": {
          "type": "custom",
          "tokenizer": "nori_discard_token",
          "filter": ["lowercase", "nori_posfilter", "stop_filter", "synonym_filter"]
        },
        "nori_mixed": {
          "type": "custom",
          "tokenizer": "nori_mixed_token",
          "filter": ["lowercase", "nori_posfilter", "stop_filter", "synonym_filter"]
        }
      },
      "filter": {
        "nori_posfilter": {
        "type": "nori_part_of_speech",
          "stoptags": [
            "E",
            "IC",
            "J",
            "MAG", "MAJ", "MM",
            "SP", "SSC", "SSO", "SC", "SE",
            "XPN", "XSA", "XSN", "XSV",
            "UNA", "NA", "VSV"
          ]
        }
      }
    }
  }

 

📍nGram Analyze

문자열 중 지정된 길이의 문자들을 출력합니다. 빠른 검색을 위해 사용될 용어들을 미리 분리해서 역색인(inverted index)에 저장합니다.

공백을 사용하지 않는 언어들을 다룰 때 유용합니다.

ngram Token Filter 를 사용하면 저장되는 term 의 갯수가 기하급수적으로 증가합니다. 따라서 일반적인 텍스트 검색에는 사용하지 않는 것이 좋으며 카테고리 목록이나 태그 목록과 같이 전체 개수가 많지 않은 데이터 집단에 자동완성 기능을 구현할 때 적합합니다.

 

옵션

  • min_gram : 토큰의 최소 길이, 기본 1
  • max_gram : 토큰의 최대 길이, 기본 2 (min_gram 과 max_gram 의 기본적 차이는 기본적으로 8 이므로 max_ngram_diff 옵션으로 차이를 설정)
  • token_chars : 지정된 값에 따라 해당하는 형식의 토큰으로 인삭
    • letter : a, b 등 알파벳 문자
    • digit : 0, 1, 2 등의 숫자
    • whitespace : 공백과 같은 개행 문자
    • punctuation : !, ., ? 과 같은 구두점
    • symbol : 특수문자

 

<사용예시>

{
  "settings": {
  	"index": {
      "max_ngram_diff" 10
    },
    "analysis": {
      "tokenizer": {
        "ngram_token": {
          "type": "ngram",
          "min_gram": 2,
          "max_gram": 10,
          "token_chars": [
            "letter",
            "digit",
            "punctuation"]
        }
      },
      "analyzer": {
        "ngram": {
          "tokenizer": "ngram_token"
        }
      }
    }
  }

 

🔗참조

https://www.elastic.co/guide/en/elasticsearch/plugins/current/analysis-nori.html

https://esbook.kimjmin.net/06-text-analysis/6.6-token-filter/6.6.4-ngram-edge-ngram-shingle

 

 

<개선사항은 언제든지 댓글로 부탁드립니다!>

반응형
Comments