(ElasticSearch) Ngram, Edge ngram, shingle

1. Ngram

Ngram은 토큰의 각 단어 부분을 다중 서브 토큰으로 분해하는 방식이다.
Ngram과 Edge ngram둘다 min_gram과 max_gram설정이 필요하다.
이들 설정은 단어로부터 분해된 토큰의 크기를 제어한다.

예를들어, Ngram 분석길로 "spaghetti"단어를 분석한다고 가정해보자.
가장 단순한 1-grams(unigram)부터 시작하자.

1-1. 1-gram


"spaghetti"의 1-gram은 s, p, a, g, h, e, t, t, i 가 된다. ngram의 크기에 따라 문자열을 작은 토큰으로 분해한다.


1-1. Bigram


bigram(크기가 2인 문자열)로 분해한다면 sp, pa, ag, gh, he, et, tt, ti와 같은 작은 토큰을 얻을 것이다.


1-3. Trigram


spa, pag, agh, ghe, het, ett, tti토큰을 얻을 것이다.



2. min_gram과 max_gram의 설정


이 분석기를 이용할 때 두 개의 서로 다른 크기를 설정해야 한다.
하나는 생성하려는 가장 작은 ngram(min_gram설정), 다른하나는 가장 긴 ngram을 지정한다.

앞의 예제 "spaghetti"에서 min_gram을 2,  max_gram을 3으로 설정하면 다음과 같다.
sp, spa, pa, pag, ag, agh, gh, ghe, he, het, et, ett, tt, tti, ti


런 방식으로 텍스트를 분석 하는 것에 흥미를 끌 만한 점이 있는데, 텍스트를 쿼리할 떄 텍스트를 동일한 방식으로 분해할 텐데, 그래서 철자가 틀린 "spaghety"단어도 찾을수 있는 것이다.
이를 검색하는 한가지 방법은 일치를 확인하기 위해 단어의 편집거리를 지정하는 퍼지(fuzzy)쿼리를 실행하는 것이다.

  • "spaghetti" 를 bigram으로 만든 토큰 :  sp, pa, ag, gh, he, et, tt, ti
  • "spaghety"를 bigram으로 만든 토큰 : sp, pa, ag, gh, he, et, ty
6개의 토큰이 일치하는것을 볼수 있다.
그러나 더 많은 단어가 포함된 쿼리라면, 원본 "spaghetti"단어와 일치하지 않을 수 있다.
이런이유로 쿼리의 적합성을 확실히 테스트 해야한다.


Ngram의 또 다른 유용성은 어떤 언어로된 텍스트인지 모르거나 다른 유럽권 언어가 서로 다른 방식으로 결합된 단어로된 언어를 갖고 있을때에도 텍스트를 분석할 수 있다는 것이다.
이는 ㄸ한 서로 다른 언어에서 서로 다른 분서기를 정의하거나 도큐먼트의 서로 다른 필드를 사용하는 방식이 아니라 단일 분석기로 다중언어를 다룰수 있다는 장점이다.



3. Edge ngram

Edge ngram은 ngram분해의 변종은 오직 앞부분부터 ngram을 만든다.
"spaghetti"예제에서 min_gram설정을 2로 max_gram설정을 6으로 지정하면 다음 토큰을 얻을 것이다.

sp, spa, spag, spagh, spaghe

개별 토큰이 앞부분부터 만들어지는 것을 볼 수 있다. 실제로 프리픽스(prefix) 쿼리를 실행하지 않고 같은 프리픽스를 공유하는 단어를 검색하는데 도움된다.
단어의 뒷부분부터 ngram을 만드려면 side속성값을 front대신 back으로 변경한다.




4. ngram설정

Ngram은 단어 사이의 공백이 없어도 언어를 분석할 수 있기 때문에 어떤 언어인지 모를 때 텍스트를 분석하는 데 좋은 방법일 수 있다.
Min_gram과 max_gram 설정으로 edge ngram분석기를 설정하는데 예제는 다음과 같다.

{
"settings" : {
"number_of_shards" : 1,
"number_of_replicas" : 0,
"index" : {
"analysis" : {
"analyzer" : {
"ngl" : {
"type" : "custom",
"toknizer" : "standard",
"filter" : ["reverse", "ngf1", "reverse"]
}
},
"filter" : {
"ngf1" : {
"type" : "edgeNgram",
"min_gram" : 2,
"max_gram" : 6
}
}
}
}
}
}




5. Shingle


Shingle토큰 필터는 기본적으로 문자수준이 아닌 토큰수준에서 ngram이다
"foo bar baz" 텍스트를 min_shingle_size는 2로 max_shingle_sizesms 3으로 적용하면 토큰은 다음과 같아질 것이다.

foo, foo bar, foo bar baz, bar baz, baz

단일 토큰이 포함되는 이유는 shingle필터는 기본적으로 원래의 토큰을 포함한다.
Output_unigrams 옵션을 false로 설정하여 이 기능을 비활성화 할 수 있다.

{
"settings" : {
"index" : {
"analysis" : {
"analyzer" : {
"shingle1" : {
"type" : "custom",
"tokenizer" : "standard",
"filter" : ["shingle-filter"]
}
}
},
"filter" : {
"shingle-filter" : {
"type" : "shingle",
"min_shingle_size" : 2,
"max_shingle_size" : 3,
"output_unigrams" : false
}
}
}
}
}


댓글

이 블로그의 인기 게시물

(18장) WebSocekt과 STOMP를 사용하여 메시징하기

(네트워크)폴링방식 vs 롱 폴링방식

(ElasticSearch) 결과에서 순서 정렬