Page tree
Skip to end of metadata
Go to start of metadata

참고 서적 엘라스틱서치 실무 가이드 - 거의 여기 다 있는 내용임, 이거 저작권(http://www.copy112.or.kr)에 걸릴거 같음. 너무 많은 부분을 가져 왔음

     

0. 한국어 텍스트 나누기

  • 빈칸을 사용해서 어절(형태소의 모임)을 구분함
  • 형태소 : 의미를 가지는 요소로서는 더 이상 분석할 수 없는 가장 작은 말의 단위. 문법적 관계적인 뜻만을 나타내는 단어 또는 단어의 부분
                  https://ko.wikipedia.org/wiki/%ED%98%95%ED%83%9C%EC%86%8C
  • 어절 : 문장을 이루는 도막 도막의 마디. 문장 성분의 최소 단위로서 띄어쓰기의 단위가 됨
  • MeCab(메카부 라고 읽음) : 21세기 세종 프로젝트에서 만들어진 말뭉치의 일부를 사용해서 한국어 형태론의 확률적 모델을 학습 시킬때, 유명한 오픈 소스 형태소 분석 엔진인 MeCab를 사용
                                                원래 일본어를 나누기 위해 작성됨
  • 말뭉치 : 영어의 corpus를 우리말로 번역한 단어. 대표적인 영어 사전인 Longman 사전에서는 ‘corpus’를 ‘연구를 위한 자료나 정보의 모음’이라고 규정하고 있고 Oxford 사전에서는 ‘언어학과
                  사전 편찬에서 한 언어를 대표하는 것으로 생각되는 원문, 발화 또는 기타 표본들의 뭉치로 대개 전자 자료의 틀로 저장되어 있는 것’을 ‘corpus’라고 풀이하고 있다.
                  국어 정보 처리 분야에서는 ‘연구 대상 분야의 언어 현실을 총체적으로 보여 주는 자료의 집합’을 ‘corpus’로 규정하고 있다.
                  말뭉치를 넓은 의미로 해석하면 언어 자료들이 조직적인 정보의 형태로 모여 있는 것은 모두 말뭉치라고 할 수 있다. 어떤 사람이 제주도 지역의 언어를 조사하여 그것을 카드에 체계적으로 정리하였다면 그것도 하나의 훌륭한 말뭉치가 된다.
                  그리고 인터넷 홈페이지에 유용한 자료를 만들어 놓았다면 그것도 역시 말뭉치가 될 수 있다. 그래서 말뭉치에는 언어 현실을 보여줄 수 있는 구어 자료나 문어 자료, 전산화된 자료와 전산화되지 않은 자료들이 모두 포함될 수 있다.
                   그러나 말뭉치를 좁은 의미로 해석하면 컴퓨터가 읽을 수 있는 형태로 저장된 일정 규모 이상의 언어 자료만을 가리키게 된다
                   https://www.korean.go.kr/nkview/nknews/199908/13_6.htm

1 Nori 형태소 분석기

2 설치

1) 플러그인 설치

플러그인 설치
윈도우
D:\elasticsearch-6.6.1\bin>elasticsearch-plugin.bat install analysis-nori
-> Downloading analysis-nori from elastic
[=================================================] 100%??
-> Installed analysis-nori
D:\elasticsearch-6.6.1\bin>


리눅스
D:\elasticsearch-6.6.1\bin>elasticsearch-plugin install analysis-nori
  • D:\elasticsearch-6.6.1\plugins 폴더에 analysis-nori 가 다운로드 된것을 확인 할 수 있음


3 분석기

  • 입력 문자 스트림을 용어로 분해하고, 색인 시점과 검색 시점에 수행 됨
  • 분석기의 핵심은 도큐먼트 필드를 분석하고 실제 색인을 만드는 일이다.
  • 분석기 구조는 문자 필드(character filters) 0개 이상, 토큰 나이저(tokenizer) 정확히 1개, 토큰 필드(token filters) 0개 이상으로 구성되어 있음

character filters tokenizer token filters에 대한 이미지 검색결과

1) 문자 필터

    • 0개 이상으로 구성. 입력 필드의 문자를 추가, 삭제, 변경 할 수 있음. 예) (smile) 은 _smile로_ 변환, (sad) 은 _sad_

2) 토큰 나이즈

    • 정확히 하나를 가짐

3) 토큰 필터

    • 0개 이상.
    • 소문자 토큰 필터(Lowercase Token Filter) : 입력 데이터의 모든 토큰을 소문자로 치환
    • 불용어 토큰 필터(Stop Token Filter) : 문맥에서 의미없는 단어를 제거. 예를 들어 영어의 is, a, an, the 와 같이 관사, 전치사, 조사, 접속사 등


  • Nori 분석기는 하나의 하나의 토크나이저와 두개의 토큰 필터로 구성되어 있음
    nori_tokenizer : 토크나이저
    nori_part_of_speech : 토큰 필터, nori_readingfrom : 토큰 필터


4 nori_tokenizer 토크 나이저

  • 형태소를 토큰 형태로 분리 하는데 사용하며, 다음과 같은 2가지 parameter를 지원
  • decompound_mode : 복합 명사를 토크나이저가 처리하는 방식
    user_dictionary : 사용자 사전 정의

1) decompound_mode

    • 토크나이저가 복합 명사를 처리하는 방식을 결정, 복합 명사가 있을 경우 단어를 어떻게 쪼갤지를 결정, 단어를 쪼개는 방법은 아래 세가지 중에서 설정

      (복합어는 하나의 실질 형태소에 접사가 붙거나 두개 이상의 실질 형태소가 결합된 말, 둘 이상의 말이 결합된 명사)

      파라미터 값설명예제
      none복합 명사로 분리하지 않음지름길, 눈물
      discard복합 명사로 분리하고 원본 데이터는 삭제잠실역 => [ 잠실, 역 ]
      mixed복합 명사로 분리하고 원본 데이터는 유지잠실역 => [ 잠실, 역, 잠실역 ]

2) user_dictionary

    • 내부적으로 세종 말뭉치와 mecab-ko-dic 사전을 사용함
    • user_dictionary를 이용해 사용자가 정의한 명사를 사전에 추가로 등록 할 수 있음.
    • config/userdic_ko.txt 형태로 생성해서 사용할 수 있으며 인덱스 매핑 시 분석기의 파라미터로 사전 경로를 등록하면 됨
    • utf-8 로 저장해야 함. ealsticsearch 시작시 오류남
    • 글자 수 보다 많은 형태소를 만들어도 오류남. 예) 삼성전자 4자인데.... 삼성전자 삼성 전자 삼 성 
    • Management 에서 index close 하고 index open 해야 적용됨, 무식하게 몰라서 처음엔 재가동 했음.... ㅠ.ㅠ

인덱스 생성
nori plugin 설치 후에 재부팅 후에 해야 됨


PUT nori_analyzer
{
  "settings": {
    "index": {
      "analysis" : {
        "tokenizer" : {
          "nori_user_dict_tokenizer" : {
            "type" : "nori_tokenizer",
            "decompound_mode": "mixed",
            "user_dictionary" : "userdict_ko.txt"
          }
        },
        "analyzer" : {
          "nori_token_analyzer" : {
            "type" : "custom",
            "tokenizer": "nori_user_dict_tokenizer"
          }
        }
      }
    }
  }
}
테스트
테스트 
POST nori_analyzer/_analyze
{
  "analyzer": "nori_token_analyzer",
  "text" : "부슬비"
}


-------------------------------- 실행 결과 ---------------------------------
{
  "tokens" : [
    {
      "token" : "부슬비",
      "start_offset" : 0,
      "end_offset" : 3,
      "type" : "word",
      "position" : 0,
      "positionLength" : 2
    },
    {
      "token" : "부슬",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "비",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "word",
      "position" : 1
    }
  ]
}


5 토큰 필터

1) nori_part_of_speech 토큰 필터

    • 품사 태그 세트와 일치하는 토큰을 찾아 제거하는 토큰 필터. 문서에 존재하는 모든 명사를 역색인으로 생성하는 것이 아니라 역색인될 명사를 선택적으로 고를 수 있음
      (품사 : 한 언어의 단어들을 그 의미, 형식, 기능에 따라 크게 분류한것. 한국어는 5언 9품사. 한국어에서는 형태가 변하는지 불변하는지에 따라 가변어와 불변어로 나누고, 그 기능에 따라 5언으로 나누며
                  마지막에 뜻에 따라 9품사로 나눔
      https://namu.wiki/w/%ED%95%9C%EA%B5%AD%EC%96%B4%EC%9D%98%205%EC%96%B8%209%ED%92%88%EC%82%AC)
    • 사용하고 싶지 않은 형태소를 제거 
    • stoptags 라는 parameter를 이용해 분리된 토큰에서 제거할 특정 형태소를 지정하는 것이 가능

예) 명사를 제외한 모든 형태소를 제거하는 예제

      인덱스를 close 하고 설정을 변경

      POST nori_analyzer/_close

설정 변경
PUT nori_analyzer/_settings
{
  "index" : {
    "analysis" : {
      "analyzer" : {
        "nori_stoptags_analyzer" : {
          "tokenizer" : "nori_tokenizer",
          "filter" : [
            "nori_posfilter"
            ]
        }
      },
      "filter": {
        "nori_posfilter" : {
          "type" : "nori_part_of_speech",
          "stoptags": [
            "E",
            "IC",
            "J",
            "MAG", "MAJ", "MM",
            "NA", "NR",
            "SC", "SE", "SF", "SH", "SL", "SN", "SP",
            "SSC", "SSO", "SY",
            "UNA", "UNKNOWN",
            "VA", "VCN", "VCP", "VSV",
            "VV", "VX",
            "XPN", "XR", "XSA", "XSN", "XSV"
            ]
        }
      }
    }
  }
}


실행한 하 인덱스를 오픈
POST nori_analyzer/_open
stoptags 파라미터를 이용한 예제
POST nori_analyzer/_analyze
{
  "analyzer": "nori_stoptags_analyzer",
  "text" : "거울아 거울아 세상에서 누가 제일 잘 생겼냐? 정대형!"
}


{
  "tokens" : [
    {
      "token" : "거울",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "거울",
      "start_offset" : 4,
      "end_offset" : 6,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "세상",
      "start_offset" : 8,
      "end_offset" : 10,
      "type" : "word",
      "position" : 4
    },
    {
      "token" : "누구",
      "start_offset" : 13,
      "end_offset" : 15,
      "type" : "word",
      "position" : 6
    },
    {
      "token" : "정대",
      "start_offset" : 26,
      "end_offset" : 28,
      "type" : "word",
      "position" : 13
    }
  ]
}


다른 예제
POST nori_analyzer/_analyze
{
  "analyzer": "nori_stoptags_analyzer",
  "text" : "정말 너무 너무 맛있다."
}


아래와 같이 하나도 토큰이 없음
{
  "tokens" : [ ]
}


stoptags 설명


2) nori_readingform 토큰 필터

    • 문서에 존재하는 한자를 한글로 변경하는 역할을 함. 별도 파라미터를 제공하지 않음


예제) nori_readingform 인덱스
PUT nori_readingform
{
  "settings": {
    "index" : {
      "analysis" : {
        "ananlyzer" : {
          "nori_readingform_analyzer" : {
            "tokenizer" : "nori_tokenizer",
            "filter" : ["nori_readingform"]
          }
        }
      }
    }
  }
}


위에 인덱스에
POST nori_readingform/_analyze
{
  "analyzer": "nori_readingform_analyzer",
  "text" : "日本"
}
이걸 실행하면 오류가 났다. 오타도 없는데... 뭐가 문제인지... ㅠ.ㅠ


{
  "error": {
    "root_cause": [
      {
        "type": "remote_transport_exception",
        "reason": "[mVjXfLn][127.0.0.1:9300][indices:admin/analyze[s]]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "failed to find analyzer [nori_readingform_analyzer]"
  },
  "status": 400
}




그래서 다시 만들어 봤음
PUT korean_nori_readingform
{
  "settings": {
    "index" : {
        "analysis":{
            "analyzer":{
                "korean_nori_analyzer":{
                    "type":"custom",
                    "tokenizer":"nori_tokenizer",
                    "filter":[
                        "nori_readingform"
                    ]
                }
            }
        }
    }
  }
}


POST korean_nori_readingform/_analyze
{
    "analyzer":"korean_nori_analyzer",
    "text":"日本에 저와 함께 가시지 않겠습니까?"
}


결과가 잘 나왔다
{
  "tokens" : [
    {
      "token" : "일본",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "word",
      "position" : 0
    },
    {
      "token" : "에",
      "start_offset" : 2,
      "end_offset" : 3,
      "type" : "word",
      "position" : 1
    },
    {
      "token" : "제",
      "start_offset" : 4,
      "end_offset" : 5,
      "type" : "word",
      "position" : 2
    },
    {
      "token" : "와",
      "start_offset" : 5,
      "end_offset" : 6,
      "type" : "word",
      "position" : 3
    },
    {
      "token" : "함께",
      "start_offset" : 7,
      "end_offset" : 9,
      "type" : "word",
      "position" : 4
    },
    {
      "token" : "가시",
      "start_offset" : 10,
      "end_offset" : 12,
      "type" : "word",
      "position" : 5
    },
    {
      "token" : "지",
      "start_offset" : 12,
      "end_offset" : 13,
      "type" : "word",
      "position" : 6
    },
    {
      "token" : "않",
      "start_offset" : 14,
      "end_offset" : 15,
      "type" : "word",
      "position" : 7
    },
    {
      "token" : "겠",
      "start_offset" : 15,
      "end_offset" : 16,
      "type" : "word",
      "position" : 8
    },
    {
      "token" : "습니까",
      "start_offset" : 16,
      "end_offset" : 19,
      "type" : "word",
      "position" : 9
    }
  ]
}

한글 형태소 분석기로 Nori를 사용하려면 다음과 같이 설정하면 된다고 합니다.... 책에서...

nori 한글 형태소 분석기 최종
PUT nori_full_analyzer
{
  "mappings": {
    "_doc" : {
      "properties": {
        "desription" : {
          "type" : "text",
          "analyzer" : "korean_analyzer"
        }
      }
    }
  }, 
  "settings": {
    "index" : {
      "analysis" : {
        "analyzer" : {
          "korean_analyzer" : {
            "filter" : [
              "pos_filter_speech",
              "nori_readingform",
              "lowercase"
            ],
            "tokenizer" : "nori_tokenizer"
        }
      },
      "filter": {
        "pos_filter_speech" : {
          "type" : "nori_part_of_speech",
          "stoptags": [
            "E",
            "IC",
            "J",
            "MAG", "MAJ", "MM",
            "NA", "NR",
            "SC", "SE", "SF", "SH", "SL", "SN", "SP",
            "SSC", "SSO", "SY",
            "UNA", "UNKNOWN",
            "VA", "VCN", "VCP", "VSV",
            "VV", "VX",
            "XPN", "XR", "XSA", "XSN", "XSV"
            ]
          }
        }
      }
    }
  }
}


POST nori_full_analyzer/_analyze
{
  "analyzer": "korean_analyzer",
  "text" : "나는 왕이다. 大王"
}


잘 된다.


끝..................... 이거 발표만 하고 지워야 할거 같음.... 책을 너무 베껴서... 잡혀 갈거 같음


































  • No labels