2.X/3. Dealing with Human Language

3-2-5. Tidying Up Input Text

drscg 2017. 9. 24. 17:29

Tokenizers produce the best results when the input text is clean, valid text, where valid means that it follows the punctuation rules that the Unicode algorithm expects. Quite often, though, the text we need to process is anything but clean. Cleaning it up before tokenization improves the quality of the output.

tokenizer는 입력 문장(text)이 깔끔할 경우 최고의 결과를 만들어 낸다. 유효한 곳에 유효한 문장(valid text, where valid)이라는 말은, Unicode 알고리즘의 문장 부호 규칙을 준수한다는 것을 의미한다. 비록 흔한 경우이지만, 우리가 처리할 문장(text)은 깔끔하지만은 않다. 문장(text)을 token으로 만들기 전에, 깔끔하게 정리하면, 출력의 질은 향상될 것이다.

Tokenizing HTMLedit

Passing HTML through the standard tokenizer or the icu_tokenizer produces poor results. These tokenizers just don’t know what to do with the HTML tags. For example:

standard tokenizer나 icu_tokenizer 에 HTML을 전달하면, 좋지 않은 결과를 만들어 낸다. 이들 tokenizer는 HTML tag를 어떻게 처리해야 하는지를 모른다. 예를 들며,

GET /_analyzer?tokenizer=standard
<p>Some d&eacute;j&agrave; vu <a href="http://somedomain.com>">website</a>

The standard tokenizer confuses HTML tags and entities, and emits the following tokens: pSomedeacutejagravevuahrefhttpsomedomain.comwebsitea. Clearly not what was intended!

standard tokenizer는 HTML tag와 요소(entity)를 혼동한다. 그래서 다음처럼 출력한다. : pSomedeacutejagravevuahrefhttpsomedomain.comwebsitea. 의도했던 것과 너무 다르다.

Character filters can be added to an analyzer to preprocess the text before it is passed to the tokenizer. In this case, we can use the html_strip character filter to remove HTML tags and to decode HTML entities such as &eacute; into the corresponding Unicode characters.

문장(text)을 tokenizer에 전달하기 전에, 문장(text)을 사전 처리하기 위해, character filter 를 analyzer에 추가할 수 있다. 이 경우에는, HTML tag의 제거와, &eacute; 같은 HTML 요소(entity)를 해당하는 Unicode 문자로 해석하기 위해, html_strip character filter를 사용할 수 있다.

Character filters can be tested out via the analyze API by specifying them in the query string:

character filter는, query string에 그것을 지정하여, analyze API로 테스트할 수 있다.

GET /_analyzer?tokenizer=standard&char_filters=html_strip
<p>Some d&eacute;j&agrave; vu <a href="http://somedomain.com>">website</a>

To use them as part of the analyzer, they should be added to a custom analyzer definition:

analyzer의 일부로 이것을 사용하기 위해서는, 사용자 정의(custom) analyzer에 추가해야 한다.

PUT /my_index
{
    "settings": {
        "analysis": {
            "analyzer": {
                "my_html_analyzer": {
                    "tokenizer":     "standard",
                    "char_filter": [ "html_strip" ]
                }
            }
        }
    }
}

Once created, our new my_html_analyzer can be tested with the analyze API:

일단 만들어지면, 새로운 my_html_analyzer 는 analyze API로 테스트할 수 있다.

GET /my_index/_analyzer?analyzer=my_html_analyzer
<p>Some d&eacute;j&agrave; vu <a href="http://somedomain.com>">website</a>

This emits the tokens that we expect: Somedéjàvuwebsite.

이 request는 기대했던 token(Somedéjàvuwebsite)을 출력한다.

Tidying Up Punctuationedit

The standard tokenizer and icu_tokenizer both understand that an apostrophe within a word should be treated as part of the word, while single quotes that surround a word should not.Tokenizing the text You're my 'favorite'. would correctly emit the tokens You're, my, favorite.

standard tokenizer와 icu_tokenizer 둘 모두는, 단어 내에 나타나는 아포스트로피(apostrophe)를 단어의 일부로 처리한다. 반면에 단어를 _둘러싸고_ 있는 단일 인용부호(single quotes)는 그렇지 않다. You're my 'favorite' 라는 문장을 token으로 만들어 보면, You're, my, favorite 이라는 token을 올바르게 출력할 것이다.

Unfortunately, Unicode lists a few characters that are sometimes used as apostrophes:

불행하게도, Unicode는 아포스트로피(apostrophes)처럼 사용되는 몇 개의 문자를 나열하고 있다.

U+0027

Apostrophe (')—the original ASCII character

아포스트로피('), 원래의 ASCII 문자

U+2018

Left single-quotation mark ()—opening quote when single-quoting

왼쪽 단일 인용 부호(), 단일 인용의 경우 인용문을 연다.

U+2019

Right single-quotation mark ()—closing quote when single-quoting, but also the preferred character to use as an apostrophe

오른쪽 단일 인용 부호(), 단일 인용의 경우 인용문을 닫는다. 그러나, 아포스트로피(')처럼 사용되어 선호하는 글자를 나타낸다.

Both tokenizers treat these three characters as an apostrophe (and thus as part of the word) when they appear within a word. Then there are another three apostrophe-like characters:

두 tokenizer는 이들 3개의 문자가 단어 내에 나타나는 경우, 이것들을 아포스트로피(')로 처리한다. (따라서, 단어의 일부가 된다.) 그리고, 또 다른 아포스트로피(') 같은 문자가 있다.

U+201B

Single high-reversed-9 quotation mark ()—same as U+2018 but differs in appearance

단일 high-reversed-9 인용 부호(), U+2018 과 동일하나 모양이 다르다.

U+0091

Left single-quotation mark in ISO-8859-1—should not be used in Unicode

ISO-8859-1에서의 왼쪽 단일 인용 부호, Unicode에서 사용되지 않는다.

U+0092

Right single-quotation mark in ISO-8859-1—should not be used in Unicode

ISO-8859-1에서의 오른쪽 단일 인용 부호, Unicode에서 사용되지 않는다.

Both tokenizers treat these three characters as word boundaries—a place to break text into tokens.Unfortunately, some publishers use U+201B as a stylized way to write names like M‛coy, and the second two characters may well be produced by your word processor, depending on its age.

두 tokenizer는 이들 3개의 문자를 단어의 경계(문장을 token으로 나누는 기준 장소)로 처리한다. 불행히도, 일부 사용자는 M‛coy 처럼 이름을 쓰는 습관적인 방식으로 U+201B 를 사용한다. 두 번째의 두 문자는 word processor(버전에 따라)에 의해 잘 만들어질 것이다.

Even when using the "acceptable" quotation marks, a word written with a single right quotation mark—You’re—is not the same as the word written with an apostrophe—You're—which means that a query for one variant will not find the other.

심지어, "허용 가능한" 인용 부호를 사용하는 경우에도, 오른쪽 단일 인용 부호와 함께 쓰여진 단어(You’re)는 아포스트로피(')와 함께 쓰여진 단어(You're)와 동일하지 않다. 즉, 어떤 변형에 대한 query는 다른 것을 찾을 수 없다.

Fortunately, it is possible to sort out this mess with the mapping character filter, which allows us to replace all instances of one character with another. In this case, we will replace all apostrophe variants with the simple U+0027 apostrophe:

다행히도, mapping character filter를 이용해 이런 혼란을 정리할 수 있다. 어떤 문자를 모두 다른 문자로 대체하기 위해 이 filter를 사용한다. 이 경우에는, 모든 아포스트로피의 변형을 단순한 U+0027 아포스트로피로 대체할 것이다.

PUT /my_index
{
  "settings": {
    "analysis": {
      "char_filter": { 
        "quotes": {
          "type": "mapping",
          "mappings": [ 
            "\\u0091=>\\u0027",
            "\\u0092=>\\u0027",
            "\\u2018=>\\u0027",
            "\\u2019=>\\u0027",
            "\\u201B=>\\u0027"
          ]
        }
      },
      "analyzer": {
        "quotes_analyzer": {
          "tokenizer":     "standard",
          "char_filter": [ "quotes" ] 
        }
      }
    }
  }
}

모든 아포스트로피의 변형을 단순한 아포스트로피로 mapping하는, quotes 라는 사용자 정의 char_filter 를 정의한다.

명확하게 하기 위해, 각 문자에 대해, JSON Unicode escape 구문을 사용했다. 그러나 문자 자체를 사용했을 뿐이다. "‘=>'"

quotes_analyzer 라 불리는 새로운 analyzer를 생성하기 위해, quotes 라는 사용자 정의 character filter를 사용한다.

As always, we test the analyzer after creating it:

항상 그랬듯이, analyzer를 만든 후에는 테스트를 해 보자.

GET /my_index/_analyze?analyzer=quotes_analyzer
Youre my favorite MCoy

This example returns the following tokens, with all of the in-word quotation marks replaced by apostrophes: You'remyfavoriteM'Coy.

위의 예제는, 단어 내의 모든 인용 부호를 아포스트로피로 대체해서, 다음 token을 반환한다: You'remyfavoriteM'Coy

The more effort that you put into ensuring that the tokenizer receives good-quality input, the better your search results will be.

좋은 품질의 입력을 tokenizer에 넣기 위해, 더 많이 노력할수록, 검색 결과는 더 좋아질 것이다.


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

3-2-3. Installing the ICU Plug-in  (0) 2017.09.24
3-2-4. icu_tokenizer  (0) 2017.09.24
3-3. Normalizing Tokens  (0) 2017.09.24
3-3-1. In That Case  (0) 2017.09.24
3-3-2. You Have an Accent  (0) 2017.09.24