11.16
뉴스홈 > 칼럼
[강좌] 두 마리 토끼 잡는 검색어 교정 기법이동균 버즈니 리서치엔지니어

   
▲ 이동균 버즈니 리서치엔지니어

[컴퓨터월드] 검색에 대해 ‘구슬이 서 말이라도 꿰어야 보배’라는 말처럼 잘 설명하는 속담이 또 있을까? 인터넷이라는 바다에 데이터가 아무리 많이 있어도 누군가 꿰어주지 않으면 아무 가치 없는 섬이 되고 말기 때문이다.

최근의 검색은 단순히 데이터를 모아서 보여주는 것으로만 끝나는 것이 아니라 효과적인 마케팅 수단이자 돈을 만들어내는 수단으로 한 발짝 더 나아가있다. 검색광고는 저렴하고 효과를 정확히 측정할 수 있으며, 어쩌면 엄청난 비용을 지불하면서 매스미디어 마케팅을 하기 힘든 업체들이 거의 유일하게 자사 서비스나 제품을 홍보할 수 있는 수단이다.

버즈니가 운영 중인 쇼핑 앱 ‘홈쇼핑모아’는 대기업과 견줘도 크게 부족하지 않을 정도로 고도화된 검색서비스를 제공하고 있으며, 이를 통해 얻어지는 검색광고 매출이 회사 전체 수익의 상당부분을 차지하고 있다. 검색 정확도와 회사의 수익이 정비례하므로, 버즈니는 검색 고도화를 위해 자연어처리(NLP), 딥러닝 등 다양한 방법으로 가설-실험-검증 사이클을 반복하고 있다.

이 글에서는 검색의 정확성을 향상시키는 가장 쉬우면서도 효과적인 방법인 ‘검색어 교정’에 대해 알아보도록 한다. 글에서 사용된 코드는 http://github.com/haandol/correction에서 확인할 수 있으며, 사용된 데이터는 ‘홈쇼핑모아’의 검색패턴 중 일부를 반영한 데이터로 저장소의 ‘query_logs.csv’ 파일에 CSV(Comma Separated Values) 형태로 포함돼있다.


버즈니 활용사례 - 검색서비스

   
▲ 그림 1 - ‘홈쇼핑모아’ 검색결과 화면

버즈니에서는 현재 국내 모든 홈쇼핑 상품을 한눈에 모아 볼 수 있는 ‘홈쇼핑모아’를 서비스 중이다. ‘홈쇼핑모아’는 국내 8개 홈쇼핑사의 방송 상품 정보를 한데 모은 통합편성표 및 검색 상품 정보를 가져와 검색할 수 있는 검색서비스를 제공하고 있다. 또 최근에는 11번가, 지마켓 등 오픈마켓의 상품정보도 함께 제공해 더욱 편리한 모바일 쇼핑을 즐길 수 있도록 서비스하고 있다.


검색어 교정

‘홈쇼핑모아’에서는 하루에 수만 건의 검색 쿼리를 처리하고 있다. 사용자 대부분은 모바일 환경에서 서비스를 이용하고 있어 오탈자가 상당히 섞여있다. 예를 들어 ‘이불’을 검색하려다 ‘이줄’을 검색한 경우, 일반적인 웹서비스에서 ‘이불’은 많은 사람이 검색하기 때문에 캐싱을 해두지만 ‘이줄’은 캐싱을 해두지 않는다. 이 때문에 서버에서는 검색을 위해 상대적으로 복잡한 연산을 해야 하고, 사용자 입장에서도 상대적으로 느리게 느껴지게 된다.

   
▲ 그림 2 - 구글 검색어 교정

이를 해결하기 위해 검색어를 교정해주는 방식은 검색서비스에서 보편적으로 사용되고 있다. 구글도 예외가 아닌데, 확실한 오탈자는 일단 검색어를 교정해 검색해주고 교정되기 전의 단어는 따로 보여줌으로써 사용자 경험도 향상시키고 서버 부하도 줄이고 있음을 알 수 있다. 이러한 검색어 교정기를 만드는 간단하지만 효과적인 방법을 알아본다.


유니코드 자모음 분리

‘이불’과 ‘이줄’이 비슷하다는 것은 ‘이불’과 ‘이놈’이 상당히 다르다는 것만큼이나 명확하게 알 수 있다. 검색어를 교정하기 위해 먼저 할 일은 ‘이불’과 ‘이줄’, 그리고 ‘이불’과 ‘이놈’이 얼마나 다른지 컴퓨터에게 알려주는 일이다. 글자가 서로 다를수록 높아지는 점수를 diff_score라고 할 때, ‘이불’과 ‘이줄’의 diff_score는 ‘이불’과 ‘이놈’의 스코어보다 반드시 낮아야 한다.

이때 글자의 차이만 보게 되면 둘 다 한 글자씩 다르기 때문에 같은 diff_score를 갖게 된다. 따라서 글자 단위가 아니라 자모음 단위로 비교해야 한다. 유니코드 이전에는 조합형과 완성형을 따로 처리했지만, 유니코드를 이용하게 되면서 이러한 구분이 사라졌다.

   
▲ 그림 3 - 유니코드 V2.0에 포함된 한글 부호영역

[그림 3]은 유니코드의 현대 한글 글자 모두를 가나다순으로 정렬·배치한 것이다. 현대 한글이 사용하는 자모는 초성 19자, 중성 21자, 종성 27자로, 조합 가능한 글자 수는 19x21x28(종성 없음 포함)=11,172자다. 그림을 보면 알 수 있듯이 종성과 종성, 중성과 중성, 종성과 종성 사이의 거리는 항상 일정하다. 이를 통해 사용자의 검색어를 유니코드로 바꾸고 각 거리를 계산해주면 유니코드 한글의 시작 위치인 ‘가’를 기준으로 한 초/중/종성 간 상대 거리를 얻을 수 있다.

   
▲ 그림 4 - 유니코드를 이용한 자모음 분리

[그림 4]는 유니코드에서 한글 자모음을 분리하는 예제다. ‘췟’을 예로 들면, [그림 3]의 유니코드 테이블의 첫 글자인 ‘가’를 기준으로 종성 ‘ㅅ’까지 종성 간 거리가 19, 중성인 ‘ㅞ’까지의 중성 간 거리가 15, 초성인 ‘ㅊ’까지의 초성 간 거리가 14다. 각각 위치를 얻어 적절히 치환해주면 ‘ㅊㅞㅅ’이라는 분리된 자모음을 얻을 수 있다.


글자간 자모음 차이 계산하기

이제 자모음을 분리했으니 글자 간 차이를 계산해보자. 가장 간단한 방법은 자모음을 분리한 결과를 한 줄로 나열해두고 차이를 계산하는 것이다. 즉 ‘이불’과 ‘이줄’로 생각했을 때는 ‘ㅇㅣㅂㅜㄹ’과 ‘ㅇㅣㅈㅜㄹ’로 보고 1의 차이가 난다고 볼 수 있다. 하지만 차례대로 비교하는 방법을 이용했을 때 ‘입불’과 ‘이불’과의 차이는 1이 아니라 4다. ‘ㅇㅣㅂㅂㅜㄹ’과 ‘ㅇㅣㅂㅜㄹ’은 3번째 ‘ㅂ’을 기준으로 4개의 차이가 있기 때문이다.

자모음의 순서를 고려하면서 일치여부를 확인할 수 있는 쉬운 방법으로는 difflib에서 제공하는 ratio() 함수가 있다. difflib는 리눅스의 diff 명령과 마찬가지로 최장공통부분수열(LCS) 문제를 해결하는데 목적을 둔다. 즉 ‘ㅇㅣㅂㅂㅜㄹ’과 ‘ㅇㅣㅂㅜㄹ’이 있을 때 공통되는 가장 긴 배열을 찾고, 그 배열을 기준으로 무엇을 더하거나 빼야 하는지 찾을 수 있다. ratio() 함수는 전체 문자 길이에 대한 LCS의 비율을 반환한다. 이를 이용해 글자 간 자모음 차이를 계산하는 코드는 아래와 같다.

   
▲ 그림 5 - Diff를 이용해 글자 간 자모음 차이 계산

계산 결과 ‘이불’과 ‘이줄’ 간 점수(0.83)가 ‘이놈’과의 점수(0.5)보다 높고, ‘입불’과의 점수(0.83)와는 같다는 것을 확인할 수 있다.


사용자 검색어 교정하기

마지막으로 사용자의 검색어 로그와 해당 검색어에 대한 검색결과를 갖고 검색어 교정을 해보자. 검색어 교정을 위해 어떠한 정보가 필요할까? 먼저 아주 간단한 가설을 하나 세워보자. ‘사용자가 Aa를 검색했는데 검색결과가 거의 없고, 같은 세션 내 동일한 사용자가 AA를 검색했더니 AA에 대한 검색결과가 상당수 있었다. 이때 Aa는 AA에 대한 오탈자일 가능성이 크지 않을까?’

해당 가설을 검증하기 위해 먼저 데이터를 준비해보자.
1. 총 5만개의 쿼리를 대상으로 같은 세션 내에서 60초 이내에 사용자의 검색어 목록을 DB에서 가져온다.
2. 직전 검색어와 이후 검색어의 diff ratio가 0.7 이상인 검색어들을 저장한다.
3. 직전 검색어와 이후 검색어에 대한 각각의 검색결과 개수를 저장한다.

   
▲ 그림 6 - 최근 사용자 검색어 목록 가져오기

위 절차를 거쳐 얻어진 데이터를 query_count.csv에 저장했다. [그림 6]에서는 이렇게 저장된 검색어 목록을 pandas를 이용해 DataFrame 형태로 가져오는 것을 볼 수 있다. 여기서 사용한 pandas는 데이터 분석을 쉽게 도와주는 파이썬(python) 툴로, pandas의 데이터 구조인 DataFrame를 이용하면 데이터 객체를 RDBMS의 테이블처럼 편리하게 사용할 수 있다.

   
▲ 그림 7 - 오타 교정

마지막으로 앞서 세웠던 가설대로 먼저 검색한 결과가 10개 미만이면서 후에 검색한 결과에 비해 개수가 현저하게 적은 검색어를 출력하면 가설에 대한 검증을 할 수 있다. [그림 7]은 우리의 가설에 해당하는 검색어들에 대한 목록을 보여준다. ‘락엔락’과 ‘락앤락’, ’펏길’과 ‘퍼실’, ‘세재’와 ‘세제’ 등 오타를 거의 올바르게 수정해주고 있는 것을 확인할 수 있다.


정리하며

검색어 교정은 서비스의 품질을 결정하는 요소로 매우 정확하게 처리해야 하지만, [그림 7]을 통해 중간중간 잘못된 교정결과도 볼 수 있었다. 이 글에서 사용한 오타를 판단하는 가설에는 준비된 상품이 몇 개 없거나 독점 상품일 경우 등 예외사례들을 올바로 처리하지 못하며, 각 사례들을 해결하기 위해서는 클릭률, 이탈율과 같은 추가적인 데이터가 필요할 수 있다.

그럼에도 검색어 교정은 검색서비스의 품질을 향상시키는 가장 손쉬운 방법 중 하나다. 현재 운영하는 서비스에 검색기능이 존재하거나 앞으로 추가할 예정이라면 검색어 교정 기능의 고도화를 통해 향상된 사용자 경험과 줄어든 서버 부하를 꼭 경험할 수 있기를 바란다.

인기기사 순위
(우)08503 서울특별시 금천구 가산디지털1로 181 (가산 W CENTER) 1713~1715호
TEL : 02-2039-6160  FAX : 02-2039-6163  사업자등록번호:106-86-40304
개인정보/청소년보호책임자:김선오  등록번호:서울 아 00418  등록일자:2007.08  발행인:김용석  편집인:김선오