2.X/3. Dealing with Human Language

3-3-2. You Have an Accent

drscg 2017. 9. 24. 17:23

English uses diacritics (like ´^, and ¨) only for imported words—like rôledéjà, and däis—but usually they are optional. Other languages require diacritics in order to be correct. Of course, just because words are spelled correctly in your index doesn’t mean that the user will search for the correct spelling.

영어만이 외래어(예: rôledéjàdäis)를 위해, 발음 구별 부호(diacritics, 예: ´^¨)를 사용한다. 그러나, 일반적으로 그들은 선택적이다. 물론, 다른 언어들이 올바른지 확인하기 위해, 발음 구별 부호가 필요하다. 물론, 단어가 올바른 맞춤법으로 색인이 되었다고 해서, 사용자가 올바른 맞춤법으로 검색한다는 것을 의미하지는 않는다.

It is often useful to strip diacritics from words, allowing rôle to match role, and vice versa. With Western languages, this can be done with the asciifolding character filter. Actually, it does more than just strip diacritics. It tries to convert many Unicode characters into a simpler ASCII representation:

단어에서 발음 구별 부호를 떼어내는 것은 유용하다. rôle 이 role 에 일치하고, 그 반대도 마찬가지이다. 서구 언어에서, 이것은 asciifolding character filter로 가능하다. 실제로, 이것은 발음 구별 부호를 떼어내는 것 이상의 역할을 한다. 많은 Unicode 문자를 간단한 ASCII 형태로 변경한다.

  • ß ⇒ ss
  • æ ⇒ ae
  • ł ⇒ l
  • ɰ ⇒ m
  •  ⇒ ??
  •  ⇒ 2
  •  ⇒ 6

Like the lowercase filter, the asciifolding filter doesn’t require any configuration but can be included directly in a custom analyzer:

lowercase filter와 마찬가지로, asciifolding filter는 어떤 설정도 없이, 사용자 정의(custom) analyzer에 바로 넣을 수 있다.

PUT /my_index
{
  "settings": {
    "analysis": {
      "analyzer": {
        "folding": {
          "tokenizer": "standard",
          "filter":  [ "lowercase", "asciifolding" ]
        }
      }
    }
  }
}

GET /my_index?analyzer=folding
My œsophagus caused a débâcle 

myoesophaguscausedadebacle 이 출력된다.

Retaining Meaningedit

Of course, when you strip diacritical marks from a word, you lose meaning. For instance, considerthese three Spanish words:

물론, 단어에서 발음 구별 부호를 떼어내면, 의미를 잃어버린다. 예를 들어, 아래 3 개의 스페인어(spanish) 단어를 생각해 보자.

esta

Feminine form of the adjective this, as in esta silla (this chair) or esta (this one).

this 라는 형용사의 여성형. esta silla (이 의자) 또는 esta (이것).

ésta

An archaic form of esta.

esta 의 고대형

está

The third-person form of the verb estar (to be), as in está feliz (he is happy).

동사 esta (~이 되다.)의 3 인칭 형태, está feliz (그는 행복하다.)

While we would like to conflate the first two forms, they differ in meaning from the third form, which we would like to keep separate. Similarly:

처음의 두 형태는 혼합할 수 있지만, 세 번째와는 의미가 다르다. 그래서 세 번째는 따로 저장해야 한다. 유사하게,

The first person form of the verb saber (to know) as in Yo sé (I know).

동사 saber (알고 있다)의 1 인칭 형태. Yo sé (나는 알고 있다).

se

The third-person reflexive pronoun used with many verbs, such as se sabe (it is known).

많은 동사와 함께 사용되는 3 인칭 재귀대명사. se sabe (그것은 알려졌다.).

Unfortunately, there is no easy way to separate words that should have their diacritics removed from words that shouldn’t. And it is quite likely that your users won’t know either.

불행히도, 발음 구별 부호를 제거할 단어와 그러지 않아야 할 단어를 구분하는 쉬운 방법은 없다. 그리고, 사용자도 거의 알 수 없을 것이다.

Instead, we index the text twice: once in the original form and once with diacritics removed:

대신, 한 번은 원래의 형태로, 그리고 한번은 발음 구별 부호를 제거한 형태로, 두 번 색인한다.

PUT /my_index/_mapping/my_type
{
  "properties": {
    "title": { 
      "type":           "string",
      "analyzer":       "standard",
      "fields": {
        "folded": { 
          "type":       "string",
          "analyzer":   "folding"
        }
      }
    }
  }
}

title field는 standard analyzer를 사용하고, 발음 구별 부호가 그대로 있는 원래의 형태를 포함한다.

title.folded field는 folding analyzer를 사용하고, 발음 구별 부호를 떼어낸다.

You can test the field mappings by using the analyze API on the sentence Esta está loca (This woman is crazy):

Esta está loca(이 여자는 미쳤다.)라는 문장을, analyze API를 사용해, field mapping을 테스트해 보자.

GET /my_index/_analyze?field=title 
Esta está loca

GET /my_index/_analyze?field=title.folded 
Esta está loca

estaestáloca 을 출력한다.

estaestaloca 을 출력한다.

Let’s index some documents to test it out:

테스트를 위해, 몇 개의 document를 색인 해 보자.

PUT /my_index/my_type/1
{ "title": "Esta loca!" }

PUT /my_index/my_type/2
{ "title": "Está loca!" }

Now we can search across both fields, using the multi_match query in most_fields mode to combine the scores from each field:

이제, 각 field로부터 score를 조합하기 위해, most_fields mode의 multi_match query를 사용하여, 두 field를 검색할 수 있다.

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "type":     "most_fields",
      "query":    "esta loca",
      "fields": [ "title", "title.folded" ]
    }
  }
}

Running this query through the validate-query API helps to explain how the query is executed:

이 query를 validate-query API를 통해 실행해 보면, query가 실행되는 방법을 이해하는데 도움이 된다.

GET /my_index/_validate/query?explain
{
  "query": {
    "multi_match": {
      "type":     "most_fields",
      "query":    "está loca",
      "fields": [ "title", "title.folded" ]
    }
  }
}

The multi-match query searches for the original form of the word (está) in the title field, and the form without diacritics esta in the title.folded field:

multi-match query는 title field에서 단어 está 의 원형을, title.folded field에서 발음 구별 부호가 없는 형태인 esta 를 검색한다.

(title:está        title:loca       )
(title.folded:esta title.folded:loca)

It doesn’t matter whether the user searches for esta or está; both documents will match because the form without diacritics exists in the the title.folded field. However, only the original form exists in the title field. This extra match will push the document containing the original form of the word to the top of the results list.

esta 나 está 중, 사용자가 어떤 것을 검색하든 관계없다. title.folded field에 발음 구별 부호가 없는 형태가 존재하기 때문에, 두 document 모두가 일치할 것이다. 그러나, 원래으 형태가 title field에 존재한다. 이 추가 일치가 결과 목록의 상단에, 단어의 원래 형태를 포함하는 document를 밀어 넣을 것이다.

We use the title.folded field to widen the net in order to match more documents, and use the original title field to push the most relevant document to the top. This same technique can be used wherever an analyzer is used, to increase matches at the expense of meaning.

더 많은 document를 일치 시키기 위해, 검색망을 넓히는(widen the net) 방법으로 title.folded field를 사용한다. 그리고 가장 관련 있는 document를 상단으로 밀어 넣기 위해, 원래의 title field를 사용한다. 의미를 잃어버리면서, 일치를 증가시키기 위해, analyzer가 사용되는 어디에서라도, 이 동일한 기술은 사용될 수 있다.

Tip

The asciifolding filter does have an option called preserve_original that allows you to index the original token and the folded token in the same position in the same field. With this option enabled, you would end up with something like this:

asciifolding filter는, 원래의 token과 변형된 token을 동일한 field에서 동일한 위치에 색인할 수 있도록, preserve_original 이라 불리는 옵션을 가지고 있다. 이 옵션을 활성화하면, 결국 아래처럼 된다.

Position 1     Position 2
--------------------------
(ésta,esta)    loca
--------------------------

While this appears to be a nice way to save space, it does mean that you have no way of saying, "Give me an exact match on the original word." Mixing tokens with and without diacritics can also end up interfering with term-frequency counts, resulting in less-reliable relevance calcuations.

이것은 공간을 절약할 수 있는 멋진 방법으로 보이지만, "원래의 단어와 정확히 일치하는 결과를 줘" 라고 하면, 방법이 없다는 의미이다. 발음 구별 부호가 있는 것과 없는 token을 섞는 것은, 결국 TF 계산에 방해가 되거나, 덜 안정적인 relevance 계산을 야기할 수 있다.

As a rule, it is cleaner to index each field variant into a separate field, as we have done in this section.

일반적으로, 위에서 이야기한 것처럼, 각 field의 변형된 값은 개별 field에 색인 하는 것이 명확하다.


'2.X > 3. Dealing with Human Language' 카테고리의 다른 글

3-3. Normalizing Tokens  (0) 2017.09.24
3-3-1. In That Case  (0) 2017.09.24
3-3-3. Living in a Unicode World  (0) 2017.09.24
3-3-4. Unicode Case Folding  (0) 2017.09.24
3-3-5. Unicode Character Folding  (0) 2017.09.24