Elasticsearch failed to build synonyms 이슈

JunMyung Lee·2023년 4월 27일
0

Elasticsearch

목록 보기
17/37

ES를 통해서 Nori로 형태소분석을 진행하여 NNP(고유명사), NNG(일반명사)를 제외한 모든 품사태그를 stoptags에 넣어 단어의 토큰을 빼오도록 하고 싶었다. 그런데 이때, 동의어를 확장해서 가지고 오려고 했을때 이슈케이스를 작성한다.

Index settings

PUT temp

{
  "settings": {
    "analysis": {
      "filter": {
        "pos_filter": {
          "type": "nori_part_of_speech",
          "stoptags": [
            "E",
            "IC",
            "J",
            "MAG",
            "MAJ",
            "MM",
            "NA",
            "NNB",
            "NNBC",
            "NP",
            "NR",
            "SC",
            "SE",
            "SF",
            "SH",
            "SL",
            "SN",
            "SP",
            "SSC",
            "SSO",
            "SY",
            "UNA",
            "UNKNOWN",
            "VA",
            "VCN",
            "VCP",
            "VSV",
            "VV",
            "VX",
            "XPN",
            "XR",
            "XSA",
            "XSN",
            "XSV"
          ]
        },
        "synonym_filtering": {
          "type": "synonym_graph",
          "synonyms_path": "synonym.txt"
        }
      },
      "tokenizer": {
        "nori_user_dict": {
          "type": "nori_tokenizer",
          "user_dictionary": "noun.txt",
          "decompound_mode": "discard"
        }
      },
      "analyzer": {
        "nori_custom": {
          "filter": [
            "lowercase",
            "trim",
            "pos_filter",
            "synonym_filtering"
          ],
          "tokenizer": "nori_user_dict"
        }
      }
    }
  }
}

Result

{
  "error" : {
    "root_cause" : [
      {
        "type" : "illegal_argument_exception",
        "reason" : "failed to build synonyms"
      }
    ],
    "type" : "illegal_argument_exception",
    "reason" : "failed to build synonyms",
    "caused_by" : {
      "type" : "parse_exception",
      "reason" : "Invalid synonym rule at line 3",
      "caused_by" : {
        "type" : "illegal_argument_exception",
        "reason" : "term: guangzhou was completely eliminated by analyzer"
      }
    }
  },
  "status" : 400
}

여기서 guangzhou라는 단어는 광저우의 동의어로 현재 동의어 사전 처리가 되어있다. 왜 이런 일이 발생하는지 현재도 자세히는 알지 못한다. (설명을 들어도 명확하게 알아듣질 못했다는...)
기억남는 부분이라도 작성해 본다.

나는 filter의 순서에 의해서 처리가 됨으로써 당연히 "pos_filter"단계에서 나온 명사를 기준으로만 동의어 처리가 되니까 아무런 상관이 없는 줄알았는데, 이러한 사유가 있어서 안되었다.

  • stoptags 옵션은 동의어 사전에 있는 단어들 중에서도 분석 과정에서 제거될 단어들을 지정한다.
  • synonym 필터에서 사용된 토크나이저와 pos_filter에서 사용된 토크나이저가 다른 경우 예외가 발생할 수 있다.

pos_filter의 stoptags 옵션으로 "SL"을 지정하면, 이 옵션에 해당하는 외국어 단어들은 분석 결과에서 제거된다.
그런데 synonym_filter에서는 이러한 외국어 단어들을 포함한 동의어 사전을 사용하고 있으므로, 이러한 단어들이 분석 결과에서 제거되어 버리면서 동의어 필터링이 제대로 동작하지 않는 것.

무슨말인지 어렵다. 들어보면 pos_filter와 synonym_filter는 연관이 있나보다. 다음을 보자

stoptags 옵션은 분석 결과에서 제거될 단어들을 지정하는 옵션입니다. 이 옵션으로 지정된 단어들은 분석 결과에 포함되지 않습니다.
예를 들어, pos_filter의 stoptags 옵션에 "SL"을 지정하면 외국어(Second Language) 태그가 붙은 단어들은 분석 결과에서 제거됩니다.
그런데, synonym_filter에서는 동의어 사전에 있는 모든 단어들이 분석 결과에 포함되어야 합니다. 따라서, synonym_filter에서는 stoptags 옵션을 사용하지 않는 것이 좋습니다. 만약 synonym_filter에서 stoptags 옵션을 사용해야 한다면, stoptags에는 동의어 사전에 포함되지 않는 단어만 지정해야 합니다.
따라서 stoptags 옵션은 pos_filter의 옵션이지만, synonym_filter와 연관이 있으므로 함께 사용할 때에는 주의가 필요합니다.

결론적으로, stoptags로 영문을 제거하라고 했는데, 동의어로 지정된 단어가 영문으로 되어있기 때문에 룰이 맞지 않기 때문에 예외가 발생한것.!!
두번을 나눠서 analyzer를 만들든지 해야하는 처리가 필요하다.

0개의 댓글