2 minute read

7.7 버전부터 노리에서 숫자로 변환하는 기능이 추가 되었다는걸 이제 알았다,,

에휴 docs 부터 차근차근 읽고 할껄

이전프로젝트에서 전처리 프로세스 만들려고, 생긴 에러나 등등,,,

참 ㅋㅋㅋ 근데 es가 참 대단한것 같다. 버전 따라가는것 힘든것만 제외 한다면,,,=

Korean (nori) Analysis Plugin

7.17 기준

  • nori analyzer
  • nori_tokenizer
  • nori_part_of_speech token filter
  • nori_readingform token filter
  • nori_number token filter

추천글

elasticsearch deep dive 개인적으로 굉장히 정리가 잘되어 있는 블로그의 글인것 같다. 먼저 한번 읽어보길 권한다.

nori analyzer & tokenizer

이전에 이미 토크나이저와 아날라이저에 관해선 글을 쓴적이 있었다.

일단 노리를 사용하기 위해선 nori를 설치 하고 삭제 할줄 알아야 한다. 이건 es 공식 아날라이저로 따로 plugin을 만드는 수고는 필요가 없다,

설치

sudo bin/elasticsearch-plugin install analysis-nori

플러그인은 반드시 클러스터의 모든 노드에 설치가 되어야 하고 각각의 노드들은 설치후 반드시 재시작을 해주어야 한다,

조만간 커스머이징 플러그인을 설치하는 방법도 다루도록 한다

삭제

sudo bin/elasticsearch-plugin remove analysis-nori

삭제 하기전 노드가 종료 되었는지 확인하도록 하자

nori_part_of_speech

nori_part_of_speech는 특정 형태소의 종류를 제외하여 검색하는 필터이다.

이를 통해 키워드 spotting등 다양한 기능을 편하게 개발이 가능하다.

그리고 대부분의 예제들이 nori_part_of_speech를 다루기 떄문에 많이들 알고 있는 필터 기능이다.

{ "settings": { "index" : { "analysis" : { "tokenizer": { "nori_user_dict": { "type": "nori_tokenizer", "decompound_mode": "none", "user_dictionary": "dic/nori_userdict_ko.txt" } }, "analyzer" : { "custom_analyze" : { "type": "custom", "tokenizer" : "nori_user_dict", "filter": [ "my_posfilter" ] } }, "filter": { "my_posfilter": { "type": "nori_part_of_speech", "stoptags": [ "NP", "UNKNOWN" ] } } } } } }

위 같이 setting 하여 사용하는것이 가능하다.

결과는 직접 확인하길 ~

nori_readingform

이건 한자를 한글로 변환해주는 똑똑한 놈이다. 근데 개인적으로 이건 정말 내가 쓸일은 적을것 같다.

내가 한자를 알아서 그런건 아님,, 있다는것만 알아두고 넘어가자

PUT nori_sample
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "nori_tokenizer",
            "filter": [ "nori_readingform" ]
          }
        }
      }
    }
  }
}

GET nori_sample/_analyze
{
  "analyzer": "my_analyzer",
  "text": "鄕歌"      
}

결과는 아래와 같다,

{
  "tokens" : [ {
    "token" : "향가",     
    "start_offset" : 0,
    "end_offset" : 2,
    "type" : "word",
    "position" : 0
  }]
}

nori_number

대망의 nori_number filter 이다,, 이걸로 삽질을 많이 했었는데,,

물론 변환에 있어 커스터마이징이 필요한 부분도 존재하지만 이건 굉장히 요긴하게 쓰일만한 기능이다. STT 분야에서도 한글 -> 숫자, 한글->영문 변환은 필수적이기 때문에, 자연어 기술에 시간을 쓰기 힘들다면 적극 권장한다.

각설하고 nori_number은 한글을 숫자로 변환해주는 필터이다 한글은 자주 숫자와 조합하여 쓰이기 때문에 discard_punctuational 옵션에 따라 삼천 이백을 3200으로 볼지 3000 200 으로 볼지 결정이 된다.

아래 표준화 결과를 통해 어떻게 변환되는지 확인이 가능하다.

영영칠 → 7
일영영영 → 1000
삼천2백2십삼 → 3223
조육백만오천일 → 1000006005001
3.2천 → 3200
1.2만345.67 → 12345.67
4,647.100 → 4647.1
15,7 → 157 (be aware of this weakness)

setting

PUT nori_sample
{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "my_analyzer": {
            "tokenizer": "tokenizer_discard_puncuation_false",
            "filter": [
              "part_of_speech_stop_sp", "nori_number"
            ]
          }
        },
        "tokenizer": {
          "tokenizer_discard_puncuation_false": {
            "type": "nori_tokenizer",
            "discard_punctuation": "false"
          }
        },
        "filter": {
            "part_of_speech_stop_sp": {
                "type": "nori_part_of_speech",
                "stoptags": ["SP"]
            }
        }
      }
    }
  }
}

GET nori_sample/_analyze
{
  "analyzer": "my_analyzer",
  "text": "십만이천오백과 3.2천"
}

결과

{
  "tokens" : [{
    "token" : "102500",
    "start_offset" : 0,
    "end_offset" : 6,
    "type" : "word",
    "position" : 0
  }, {
    "token" : "과",
    "start_offset" : 6,
    "end_offset" : 7,
    "type" : "word",
    "position" : 1
  }, {
    "token" : "3200",
    "start_offset" : 8,
    "end_offset" : 12,
    "type" : "word",
    "position" : 2
  }]
}