2018년 5월 24일 엔지니어링

엘라스틱서치 6.2를 이용한 한국어, 중국어, 일본어 검색 - 1부: 형태소 분석기

By 김기주

92개국이 평창 동계올림픽대회에 참가했고, 49개국이 동계패럴림픽대회에 참가했습니다. Elastic은 34개국에 직원이 있습니다. 각국의 사람들이 각자의 언어로 메일을 씁니다. 그중에서 한글로 “올림픽대회”라는 키워드가 들어 있는 메일을 찾으려고 합니다.

https://www.elastic.co/guide/en/elasticsearch/guide/current/language-intro.html에 여러 가지 언어로 작성된 문서를 처리하는 몇 가지 방법이 나와 있습니다만 대부분 커스텀 플러그인이 필요 없는 유럽 언어를 예로 들고 있습니다. 이 문서는 한국어, 일본어, 중국어용 커스텀 플러그인(형태소 분석기)를 소개하고 멀티필드를 이용한 다중 언어 텍스트 검색 방법을 알아봅니다.

Standard Analyzer: 기본(default) 분석기

전문 검색에는 형태소 분석기가 필요합니다. 기본 분석기는 standard analyzer로, 한국어, 중국어, 일본어 검색에는 적합하지 않습니다. 다음은 standard analyzer로 한국어, 중국어, 일본어 텍스트를 분석한 결과입니다. 텍스트는 https://www.pyeongchang2018.com/ko/about-the-games에서 발췌했습니다.

[한국어]

POST _analyze
{
  "analyzer": "standard",
  "text": "제23회 동계올림픽대회는 대한민국 강원도 평창에서 2018년 2월 9일부터 25일까지 17일간 개최됩니다. 대한민국 평창은 세 번의 도전 끝에 지난 2011년 7월 6일 열린 제123차 IOC 총회에서 과반 표를 획득하며 2018년 동계올림픽 개최지로 선정되었습니다. 이로써 대한민국에서는 1988년 서울 올림픽 이후 30년 만에, 평창에서 개∙폐회식과 대부분의 설상 경기가 개최되며, 강릉에서는 빙상 종목 전 경기가, 그리고 정선에서는 알파인 스키 활강 경기가 개최될 예정입니다."
}
=>
{
  "tokens": [
    {
      "token": "제23회",
      "start_offset": 0,
      "end_offset": 4,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "동계올림픽대회는",
      "start_offset": 5,
      "end_offset": 13,
      "type": "<HANGUL>",
      "position": 1
    },
…

한국어는 교착어로 명사(예: “동계올림픽대회”) 뒤에 흔히 조사(예: “는”)가 붙습니다. 검색을 위해서는 조사를 제거해야 하지만 standard analyzer는 명사와 조사를 분리하지 않습니다.

[일본어]

POST _analyze
{
  "analyzer": "standard",
  "text": "第23回冬季オリンピック大会は大韓民国江原道平昌で2018年2月9日から25日までの17日間、開催されます。大韓民国・平昌は三度の挑戦の末、2011年7月7日に開かれた第123回IOC総会で過半数票を獲得し、2018年冬季オリンピック及びパラリンピックの開催地に選ばれました。これにより1988年ソウルオリンピック開催後30年の時を経てついに、大韓民国で最初の冬季パラリンピックの舞台が繰り広げられます。平昌で開・閉会式とほぼ全ての雪上競技が開催され、江陵では氷上種目全競技が、そして旌善ではアルペンスキー滑降競技が開催される予定です。"
}
=>
{
  "tokens": [
    {
      "token": "第",
      "start_offset": 0,
      "end_offset": 1,
      "type": "<IDEOGRAPHIC>",
      "position": 0
    },
    {
      "token": "23",
      "start_offset": 1,
      "end_offset": 3,
      "type": "<NUM>",
      "position": 1
    },
    {
      "token": "回",
      "start_offset": 3,
      "end_offset": 4,
      "type": "<IDEOGRAPHIC>",
      "position": 2
    },
    {
      "token": "冬",
      "start_offset": 4,
      "end_offset": 5,
      "type": "<IDEOGRAPHIC>",
      "position": 3
    },
    {
      "token": "季",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<IDEOGRAPHIC>",
      "position": 4
    },
    {
      "token": "オリンピック",
      "start_offset": 6,
      "end_offset": 12,
      "type": "<KATAKANA>",
      "position": 5
    },
    {
      "token": "大",
      "start_offset": 12,
      "end_offset": 13,
      "type": "<IDEOGRAPHIC>",
      "position": 6
    },
    {
      "token": "会",
      "start_offset": 13,
      "end_offset": 14,
      "type": "<IDEOGRAPHIC>",
      "position": 7
    },
    {
      "token": "は",
      "start_offset": 14,
      "end_offset": 15,
      "type": "<HIRAGANA>",
      "position": 8
    },
…

일본어도 교착어로 명사(예: “冬季オリンピック大会”) 뒤에 조사(예: “は”)가 붙습니다. 검색을 위해서는 역시 조사를 제거해야 하지만 standard analyzer는 명사와 조사를 분리하지 않습니다. 설상가상으로 일본어 문장은 한자와 가나로 이루어져 있는데 standard analyzer는 한자 하나하나를 토큰으로 만들어 버립니다.

[중국어]

POST _analyze
{
  "analyzer": "standard",
  "text": "第23届冬季奥运会将于2018年2月9日-25日在韩国江原道平昌展开。韩国平昌在第三次申奥之后,于2011年7月6日召开的第123届国际奥委会全会上被选定为2018年冬季奥运会的主办地。由此,韩国自1988年举办首尔夏季奥运会以后,时隔30年,将首次举办冬季奥运会。该届冬奥会的开·闭幕式以及大部分的雪上运动将在平昌进行,而所有冰上运动将在江陵、高山滑雪滑降比赛则将在旌善进行。"
}
=>
{
  "tokens": [
    {
      "token": "第",
      "start_offset": 0,
      "end_offset": 1,
      "type": "<IDEOGRAPHIC>",
      "position": 0
    },
    {
      "token": "23",
      "start_offset": 1,
      "end_offset": 3,
      "type": "<NUM>",
      "position": 1
    },
    {
      "token": "届",
      "start_offset": 3,
      "end_offset": 4,
      "type": "<IDEOGRAPHIC>",
      "position": 2
    },
    {
      "token": "冬",
      "start_offset": 4,
      "end_offset": 5,
      "type": "<IDEOGRAPHIC>",
      "position": 3
    },
    {
      "token": "季",
      "start_offset": 5,
      "end_offset": 6,
      "type": "<IDEOGRAPHIC>",
      "position": 4
    },
    {
      "token": "奥",
      "start_offset": 6,
      "end_offset": 7,
      "type": "<IDEOGRAPHIC>",
      "position": 5
    },
    {
      "token": "运",
      "start_offset": 7,
      "end_offset": 8,
      "type": "<IDEOGRAPHIC>",
      "position": 6
    },
    {
      "token": "会",
      "start_offset": 8,
      "end_offset": 9,
      "type": "<IDEOGRAPHIC>",
      "position": 7
    },
...

역시나 standard analyzer는 “冬季奥运会”를 “동계올림픽”이라는 단어로 인식하지 못하고 글자단위로 모두 나누어 버립니다.

언어별 분석기: 커스텀 플러그인

언어별 분석기를 사용하면 보다 나은 검색 결과를 얻을 수 있습니다. 유명한 한국어, 일본어, 중국어용 분석기로는 각각 openkoreantext-analyzer, kuromoji, smartcn이 있습니다. 아래 예들을 실행하기 전에 모든 노드에 설치해야 합니다. openkoreantext-analyzer는 Elastic 리포지토리에 없기 때문에 설치할 때 전체 URL을 적거나 미리 다운로드해야 합니다.

[한국어]

POST _analyze
{
  "analyzer": "openkoreantext-analyzer",
  "text": "제23회 동계올림픽대회는 대한민국 강원도 평창에서 2018년 2월 9일부터 25일까지 17일간 개최됩니다. 대한민국 평창은 세 번의 도전 끝에 지난 2011년 7월 6일 열린 제123차 IOC 총회에서 과반 표를 획득하며 2018년 동계올림픽 개최지로 선정되었습니다. 이로써 대한민국에서는 1988년 서울 올림픽 이후 30년 만에, 평창에서 개∙폐회식과 대부분의 설상 경기가 개최되며, 강릉에서는 빙상 종목 전 경기가, 그리고 정선에서는 알파인 스키 활강 경기가 개최될 예정입니다."
}
=>
{
  "tokens": [
    {
      "token": "제",
      "start_offset": 0,
      "end_offset": 1,
      "type": "Noun",
      "position": 0
    },
    {
      "token": "23회",
      "start_offset": 1,
      "end_offset": 4,
      "type": "Number",
      "position": 1
    },
    {
      "token": "동계올림픽",
      "start_offset": 5,
      "end_offset": 10,
      "type": "Noun",
      "position": 2
    },
    {
      "token": "대회",
      "start_offset": 10,
      "end_offset": 12,
      "type": "Noun",
      "position": 3
    },
...

이제 조사가 모두 제거되었습니다.

[일본어]

POST _analyze
{
  "analyzer": "kuromoji",
  "text": "第23回冬季オリンピック大会は大韓民国江原道平昌で2018年2月9日から25日までの17日間、開催されます。大韓民国・平昌は三度の挑戦の末、2011年7月7日に開かれた第123回IOC総会で過半数票を獲得し、2018年冬季オリンピック及びパラリンピックの開催地に選ばれました。これにより1988年ソウルオリンピック開催後30年の時を経てついに、大韓民国で最初の冬季パラリンピックの舞台が繰り広げられます。平昌で開・閉会式とほぼ全ての雪上競技が開催され、江陵では氷上種目全競技が、そして旌善ではアルペンスキー滑降競技が開催される予定です。"
}
=>
{
  "tokens": [
    {
      "token": "第",
      "start_offset": 0,
      "end_offset": 1,
      "type": "word",
      "position": 0
    },
    {
      "token": "23",
      "start_offset": 1,
      "end_offset": 3,
      "type": "word",
      "position": 1
    },
    {
      "token": "回",
      "start_offset": 3,
      "end_offset": 4,
      "type": "word",
      "position": 2
    },
    {
      "token": "冬季",
      "start_offset": 4,
      "end_offset": 6,
      "type": "word",
      "position": 3
    },
    {
      "token": "オリンピック",
      "start_offset": 6,
      "end_offset": 12,
      "type": "word",
      "position": 4
    },
    {
      "token": "大会",
      "start_offset": 12,
      "end_offset": 14,
      "type": "word",
      "position": 5
    },
...

역시 조사가 제거되고 한자가 단어 단위로 토큰화되었습니다.

[중국어]

POST _analyze
{
  "analyzer": "smartcn",
  "text": "第23届冬季奥运会将于2018年2月9日-25日在韩国江原道平昌展开。韩国平昌在第三次申奥之后,于2011年7月6日召开的第123届国际奥委会全会上被选定为2018年冬季奥运会的主办地。由此,韩国自1988年举办首尔夏季奥运会以后,时隔30年,将首次举办冬季奥运会。该届冬奥会的开·闭幕式以及大部分的雪上运动将在平昌进行,而所有冰上运动将在江陵、高山滑雪滑降比赛则将在旌善进行。"
}
=>
{
  "tokens": [
    {
      "token": "第",
      "start_offset": 0,
      "end_offset": 1,
      "type": "word",
      "position": 0
    },
    {
      "token": "23",
      "start_offset": 1,
      "end_offset": 3,
      "type": "word",
      "position": 1
    },
    {
      "token": "届",
      "start_offset": 3,
      "end_offset": 4,
      "type": "word",
      "position": 2
    },
    {
      "token": "冬季",
      "start_offset": 4,
      "end_offset": 6,
      "type": "word",
      "position": 3
    },
    {
      "token": "奥运会",
      "start_offset": 6,
      "end_offset": 9,
      "type": "word",
      "position": 4
    },
...

역시 “冬季”와 “奥运会”가 단어 단위로 토큰화되었습니다.

이제 한국어, 중국어, 일본어 문장을 분석할 수 있게 되었습니다. 엘라스틱서치 6.2를 이용한 한국어, 중국어, 일본어 검색 - 2부: Multi-fields에서는 multi-fields를 이용해서 한중일어 문장을 인덱싱하고 검색하는 예를 살펴보겠습니다.