1.  시작하며


용어의 혼란을 줄이기 위해서 먼저 정리하겠다.

단어로 구성된 짧은 문자열을 "단문" 혹은 "문자열"이라고 할 것이고, 

여러단어로 구성된 긴문자열은 "텍스트"라고 하겠다.


텍스트를 색인하는 기술은 더 더양한 기술이 필요하다.

사실 단문 검색을 위한 색인은 정규화와 인덱스를 통해 DB로도 처리가능한 수준이다.
하지만, 텍스트의 경우는 검색엔진이 아니면 처리할 수 없는 속도와 품질의 격차가 생긴다.

그 이유는 쿼리로 만든다면 아래와 같은데, 좌절단 검색이기 때문에 인덱스를 쓸수가 없다. 

select * from 테이블 where body like '%맛집%' and body like '%종로%';





2. 문장을 색인하려면?


아래와 같은 문장이 있다고 치자. 그럼 어떻게 색인해야 할까?

우리는 일반적으로 단어를 검색어로 사용한다. 즉, 문장을 단어 위주로 색인을 해야한다는 말이다.

여기서부터는 2부2편에서 이야기 했던 여러가지 기술들이 복합적으로 쓰이기 시작한다.


아래와 같은 문장이 있다고 하면, 어떻게 색인어를 뽑아야 할까?  


공백으로 단어 나누기 (문장을 단어로 만들기)

문장을 단어로 바꾸는 가장 손쉬운 방법은 공백(space)로 쪼개는 방법이다.
이 방법은 어디서 많이 보지 않았는가? 색인어 많이 만들기로 말했던 방법과 같다. (태그 언급하며 이야기 했던)
영어나 한글의 경우는 띄어쓰기가 존재해서 단어로 쪼개는것이 가능하다.
물론 특수문자인 쉼표(,) 쩜(.) 같은것에 대한 제거 처리도 필요할것이다.

원본 

 This manual is under constant development.

색인어

 this           <--  tip.대소문자 검색문제를 피하기위해서 색인어 변경(소문자로 변경

 manual 

 is 

 under 

 constant 

 development



물론, 위와같이 색인어를 뽑으면 대소문자 구분을 해야하기 때문에, 소문자로 일치화 시키면 더 베스트.
근데 이것도 기억나는가? "2부 2편 4. 색인어 변경하기" 에서 다뤘던 내용이다.
필자가 전편에 왜 그 내용을 다뤘는지 이젠 알고 있을까? 이런 나의 마음을 ... (부끄)



3. 스태밍 

영어같은 경우는 어미의 변화가 많다. (어미는 '엄마'를 말하를게 아니라 '단어의 뒷부분'을 말하는것이다)
-able -tion -ly -ed -ing -s   같이 어미에 따라서 복수도 되고 단수도 되고,  과거형도 되고 다양하게 표현된다.
하지만, 뒤에 붙는 어미가 달라져서 용도가 바뀐다고 검색할때 안된다면 먼가 찝찝하고 조치가 필요할것 같다.




스태밍의 아이디어

문제를 하나 내겠다. 지금 7명중 현금을 가진건 홍길동뿐이다. 

1만 2천원 짜리 피자를 나눠먹었을때 얼마씩 입금해야 할까?


(계산) 12000 / 7 = 1714.2857143원


친구들한테 "1714.2857143"원 입금해 달라고 하기보다는 1700원 입금해달라고 하는게 일반적이다.

친구들이 소숫점단위까지 외운다는건,  기적에 가깝기 때문에 자질구래한 단위는 버린다. 

스태밍 방식의 아이디어도 비슷하다. 색인할때 의미가 중요하지 않은 어미부분을 잘라버리고 색인어를 뽑는 방법이다.



스태밍의 색인예제

위에 말했던 아이디어를 사용해서 아래와 같이 색인어를 추출한다.보면 어미는 버리고 의미있는 어두의 내용만 추출된걸 알 수 있다. "importan"  이라는 같은 색인어를 가지기 때문에 색인어의 갯수가 줄어드는 장점도 가진다.

(=색인어가 적다는건, 인덱스 크기가 작아질 수 있다는걸 의미한다) 

원본 

 색인어 (스태밍)

 importance

 importan 

 important

 importan 

 importantly

 importan


주로 영어에 대해서 사용하지만, 극단적으로 "한글"에도 유사하게 사용이 가능하다.

우리나라는 조사가 있어서 -을 -로 -으로 -는 -와 같은것이 뒤에 붙는데 그런 단어를 빼고 색인어로 뽑는것이다.

하지만, 우리나라말에서 규칙은 예외가 많아서 스태밍 방식이 아닌 형태소분석이라는 기술을을 사용한다.




4. N-GRAM  

지금까지 위에 다룬 기술들은 사실 like 검색의 결과를 모두 커버하지 못한다.
예를 들어, 상품코드명을 찾는다고 하자. 이런경우는 영어사전에 있는 단어가 아니다.
MDR V시리즈를 찾는다고 하면  DB 에서는 이런 쿼리를 사용할것이다.
물론, Full scan을 하겠지만  우리가 원하는 결과를 찾을 수는 있을것이다.

select * from product where 제품명 like '%MDR-V%';

그런데 우리가 배웠던 기술들로는 인덱스를 쓰는 방법이 안떠오른다.





해결법

배가 고픈데 "짜파게티를 먹을까? 라면을 먹을까?" 고민이 되는경우가 있다.

그때 내친구가 해준말이 생각난다.         


친구 : "왜 고민을 해? 둘 다 먹으면 되지" 


그럼 여기선 어떻게 하면 해결될까? 왜 고민을해 다 만들면 되지...

NGRAM의 아이디어는 간단하다.  모든 경우의 색인어를 만들면 된다. .

참고로 Ngram 의  N 은 단어를 몇 글자로 쪼개는가 하는 값을 의미한다.



NGRAM 을 사용해보기

2gram(=Bigram)이라고 하면, 2개의 글자로 쪼개는걸 의미한다. (N의 크기는 어떤값이든 올 수 있지만 2~4정도)

예를 들어 "소니 MDR-V55" 라는 것을 bigram으로 색인한다고 해보자.  그러면 아래와 같이 색인어를 만든다. 

"MDR-V" 라는 값을 찾는다고 할 때, 동일하게 bigram 처리하면 오른쪽과 같은 색인어를 만들수 있다.


그러면 두 색인어를 비교해서 본문의 색인어가 모두 존재하는 결과를 던져주면된다.

옛날과 다른건 색인어랑 1:1 매칭 개념이 아니라, 모두 포함되어 있느냐의 개념이다.


 

본문

 

검색어


다시 말하면 아래와 같이 부분집합인 녀석을 찾는것이다.

N-gram의 문제

ngram 의 가장큰 단점은 색인어 갯수가 많아진다는것이다.

색인어가 많아진다는건 그만큼 인덱스 크기가 커지고, 만드는데도 오래걸린다걸 의미한다.


그리고, N의 숫자가 낮을경우 텍스트 검색을 한다면 품질의 문제가 발생할수 있으니 주의하자.

예를 들어 "father" 라고 검색한다고 하자. bigram(N=2) 으로 검색한다면

전혀 매핑될만한 단어가 아닌데, bigram방식에는 오른쪽 결과가 나온다.

(이럴경우는 N 의 값을 올리는것도 도움이 된다)


 검색어

 본문

 father

 the fat player

 fa

 at

 th

 he

 er


th

he

fa

at

pl

la

ay

ye

er




5. 마무리


지금까지 배웠던 지식은 기계적으로 처리가 가능한 어떻게 보면 Rule 베이스로 뽑았다.

그래서 중국어, 스페인어 같은 다양한 언어에서도 동일하게 처리가 가능하다. 그래서 Ngram은 어떤 언어에도 대응이 가능한 장점을 가졌으나 텍스트같이 긴 문장에 대해서 검색 품질이 나빠질수 있는 한계점을 지녔다.

그래서, 그런 문제를 해결하기 위해  형태소 분석이라는 대단한 녀석(?)이 기다리고 있다.


문장의 색인기법에 대한것을 설명하면서 이제 어느정도 감이 왔을거라 믿고
이제서야 형태소 분석에 대한 이야기를 시작할 수 있지 않을까 생각한다.

그럼 2부 4편.. 형태소분석편에서 글을 계속 잇도록 하겠다.
(사족으로 말하면 형태소 분석편이 2부의 끝입니다)







+ Recent posts