이 문서의 허가되지 않은 무단 복제나 배포 및 출판을 금지합니다. 본 문서의 내용 및 도표 등을 인용하고자 하는 경우 출처를 명시하고 김종민(kimjmin@gmail.com)에게 사용 내용을 알려주시기 바랍니다.
커뮤니티 한글 형태소 분석기 - 아리랑, 은전한닢, Open Korean Text
한글은 형태의 변형이 매우 복잡한 언어입니다. 특히 복합어, 합성어 등이 많아 하나의 단어도 여러 어간으로 분리해야 하는 경우가 많아 한글을 형태소 분석을 하려면 반드시 한글 형태소 사전이 필요합니다. 오픈 소스 커뮤니티에서 개발되어 Elasticsearch에서 사용 가능한 한글 형태소 분석기는 다음과 같은 것들이 있습니다.
설명: mecab-ko-dic 기반으로 만들어진 JVM 상에서 돌아가는 한국어 형태소분석기입니다. 기본적으로 java와 scala 인터페이스를 제공합니다. 사전이 패키지 내에 포함되어 있기 때문에 별도로 mecab-ko-dic을 설치할 필요가 없습니다. 특징으로는 (시스템 사전에 등록되어 있는 단어에 한하여) 복합명사 분해와 활용어 원형 찾기가 가능합니다.
Elasticsearch가 한글을 지원하지 않던 시절에 위의 형태소 분석기들은 한글 사용자들에게 큰 도움이 되었습니다. 하지만 외부에서 만들어진 기능이다 보니 Elasticsearch 버전이 올라가 구조가 변경되면 사용이 불가능해지고, 버그가 오류가 있어도 누군가가 나서서 쉽게 고치기 어려운 문제가 있었습니다.
Nori 를 사용하기 위해서는 먼저 elasticsearch에 analysis-nori 플러그인을 설치해야 합니다. elasticsearch 홈 디렉토리에서 다음 명령을 실행하면 버전에 맞는 nori 플러그인을 받아서 자동으로 설치합니다.
nori 플러그인 설치
$bin/elasticsearch-plugininstallanalysis-nori
설치된 nori 플러그인을 제거하려면 다음 명령을 실행합니다.
nori 플러그인 제거
$bin/elasticsearch-pluginremoveanalysis-nori
Elastic 클라우드 서비스에서 사용하기 위해서는 클러스터를 배포할 때 Customize deployment 메뉴의 Manage plugins and settings 부분에서 analysis-nori 부분을 선택합니다.
nori_tokenizer
Nori는 nori_tokenizer 토크나이저와 nori_part_of_speech, nori_readingform 토큰 필터를 제공합니다. 먼저 nori_tokenizer 토크나이저를 사용해서 한글을 간단하게 테스트 할 수 있습니다. 다음은 standard와 nori_tokenizer 를 비교해서 "동해물과 백두산이" 를 분석한 예제입니다. 당연히 테스트 하는 elasticsearch 에는 analysis-nori 플러그인이 설치되어 있어야 합니다.
standard 토크나이저로 "동해물과 백두산이" 문장 분석
GET _analyze{"tokenizer": "standard","text": ["동해물과 백두산이" ]}
Standard 토크나이저는 공백 외에 아무런 분리를 하지 못했지만 nori_tokenizer는 한국어 사전 정보를 이용해 "token" : "동해", "token" : "산" 같은 단어을 분리 한 것을 확인할 수 있습니다. 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옵션을 이용하여 사용자 사전 "해물" 을 지정하고 "동해물과" 를 분석한 예제입니다.
각 설정에 따라 어근을 분리하거나 분리하지 않거나 모두 저장하는 것을 확인할 수 있습니다. decompound_mode 의 디폴트 값은 discard 입니다.
nori_part_of_speech 와 품사 정보
한글 검색에서는 보통 명사, 동명사 정도만을 검색하고 조사, 형용사 등은 제거하는 것이 바람직합니다. nori_part_of_speech 토큰 필터를 이용해서 제거할 품사(POS - Part Of Speech) 정보의 지정이 가능하며, 옵션 stoptags 값에 배열로 제외할 품사 코드를 나열해서 입력해서 사용합니다. 다음은 품사 코드의 일부 정보들입니다.
이 외의 품사 코드는 출처에 명시된 정보 페이지에서 찾을 수 있습니다. stoptags의 디폴트 값은 다음과 같습니다.
query 또는 _analuze API 에서 "explain": true 옵션을 추가하면 분석된 한글 형태소들의 품사 정보를 같이 볼 수 있습니다. explain 옵션은 nori 외에도 대부분의 애널라이저나 쿼리에서 사용하면 확장된 정보를 보여줍니다. 다음은 "동해물과 백두산이" 문장을 분석하면서 explain 옵션을 추가하여 상세 정보를 본 예제입니다.
"explain": true 옵션을 이용해서 분석 정보 표시
GET _analyze{"tokenizer": "nori_tokenizer","text": "동해물과 백두산이","explain": true}
이번 장에서는 elasticsearch가 데이터를 저장하는 색인 과정에서 처리하는 수많은 작업들에 대해 알아보았습니다. 텍스트 분석 및 텀의 개념과, 데이터 분석에 사용되는 애널라이저, 토크나이저, 토큰 필터, 캐릭터 필터 도구들에 대해 학습을 했습니다. 이런 텍스트 데이터 처리 과정을 통해 Elasticsearch는 빠른 풀 텍스트 검색 기능을 제공하며 다양한 방법으로 데이터를 다룰 수 있도록 합니다.
다음 장에서는 인덱스의 세팅 및 매핑 설정 방법과 다양한 형태의 필드들에 대해 알아보도록 하겠습니다.