체계화된 검색 시스템은 어떻게 만들어야할까?
오늘 다루는 이야기는 회사 신입 기획자 교육과정에서 '검색 시스템은 어떻게 만들어지는가' 에서 나온 내용들을 다시한번 추려서 정리한 것이다.
기본적으로 검색은 동일한 '문자'를 찾는 과정이다. 문자의 길이와 상관없이 해당 문자열이 특정 위치에 존재하는지. 아니면 존재하지 않는지를 찾는 과정이 필요하다. 그래서 실제 인터넷 브라우저나, 워드 프로그램의 CTRL + F (단어, 문장 찾기) 기능도 엄연히 '검색' 기능이라고 할 수 있다. 다만 디자이너나 기획자 입장에서는 이런 검색기능을 제대로 공부할 수 있는 곳이 많지 않다. 애초에 검색이라는 것은 개발의 영역이고, 문자열 기반의 매칭, 탐색과 관련이 있기 때문이다. 그래서 이번 시간에는 검색기능이란 무엇이고, 또 어떤 방식으로 기능을 설계할 수 있는지. 실제 사례를 들어보며 이야기해보려한다.
개발자의 시점으로 보면 검색은 아주 기초적인 기능들 중 하나다. 프론트 엔드나 백엔드 모두 - 특정 문자열을 찾는 기능 정도는 아주 기초과정에서 배우게된다. 예를 들어 'HELLOGEM' 이라는 글자 속에서 'GEM'이라는 글자를 찾아야하는 상황이라면, 아래의 그림처럼 'GEM'이라는 글자를 일일히 대조해보는 방식으로 검색을 하게된다. 이외에도 'G'와 'E' 'M' 같은 개별 문자를 하나씩 검색해보는 방법도 있겠지만, 가장 흔하게 쓰이는건 '글자 전체를' 검색어와 비교해보는 방식이다.
우리가 인터넷에서 사용하는 CTRL + F 기능이나, 인터넷 게시판 검색, 후기검색 같은 것들의 경우는 이런 단순 키워드 검색이 자주 사용된다. 이 방식은 대부분의 서비스에서 사용되는 FAQ 검색이나, 공지사항 검색, 본인이 작성한 게시글 검색 등에서도 종종 사용되곤한다. 하지만 이런 방식으로는 복잡한 키워드나, 연관성이 있는 정보들을 묶어줄 수 없다. 심지어 사용자의 오타나, 한/영을 바꿔서 쓴 검색어, 유사한 명칭의 다른 검색어를 처리할 수 없다. 실제로 키워드 검색이 매우 중요한 커머스 서비스에서는 '특이한 시나리오'를 모두 예상하고 검색결과에서 처리를 해주고있다.
1:1 매칭 형식의 문자열 검색에서는 이런 결과값이 절대 나올 수 없다. 이 부분을 풀어서 말하면 검색을 시도할 때, 개별 키워드를 분석해서, 어떤 문자에 가까운지 '유사도'를 측정하고있다는걸 알 수 있다. 그래서 사람들이 검색한 제품들 중 가장 '많이 검색한' 제품들과 유사한 것이 있는지를 분석해 - 유사도가 높은 결과를 보여준 결과다. 그렇다면 이런 문자의 유사도는 어떤 방식으로 확인할 수 있을까?
문자의 유사도를 이용한 유명한 사례가 있다. 뉴스젤리의 꼬맨틀이라는 '유사 단어 찾기' 게임의 사례다. 이 게임에서는 실제 입력한 단어와 정해진 단어가 얼마나 유사한지를 측정하는 방식이다. 그렇다면 이런 유사도는 어떤 방식으로 측정할 수 있는 걸까?
기본적으로 우리가 쓰는 문자인 한글은 '자음'과 '모음'이 합쳐진 복합형태의 언어다. 그렇기 때문에 개별 단어로 이뤄진 소문자 / 대문자 26개의 알파벳과 달리, 매우 다양한 변형언어가 존재한다. (예: 뷁, 꿹, 뚫) 이런 이유때문에 실제 검색에서도 1:1 매칭되는 유사도를 측정하기가 매우 어려운 편이다. 하지만 이 문제는 기계의 관점에서 보면 생각보다 쉽게 해결이 될 수 있는 문제다. 기계의 시점에서는 어차피 모든 언어가 '특정 언어체계'를 바탕으로 만들어진 문자들의 조합이다. 그리고 이것을 실제 컴퓨터가 이해하기 위해 특정 '코드값'을 사용하고있다. 그 대표적인 사례가 유니코드와 아스키 코드다.
유니코드는 웹개발에서 사용되는 UTF-8 과 같은 '타입선언'과도 연관이 있다. 특정 문자열을 불러와서 사용하겠다는 명령어다. 전 세계에 존재하는 다양한 언어들 중, 1:1로 매칭해둔 특정 문자열을 가져와 - 기계가 인식할 수 있도록 처리한 것이 유니코드와 아스키코드다. 그렇다면 한글의 경우도 비슷한 방식으로 '특정 문자'의 유니코드를 확인할 수 있지 않을까? 맞는 이야기다. 실제로 한글을 유니코드 기반으로 정리한 자료가 존재한다.
아스키 코드는 ASCII(American Standard Code for Information Interchange)의 약어로, 실제 미국어 자판에 해당하는 내용들만을 포함하고있다. 그래서 한국어 기준으로는 유니코드 기반의 언어들 중 '특정 위치'에 있는 범위만을 한글로서 인식할 수 있다. 결국 이 부분을 정리해보면, 모든 언어는 '유니코드' 기반으로 개별 문자를 정리할 수 있다는 것. 그리고 그 기반으로 '정확한 주소값'을 확인할 수 있다는 것을 알 수 있다. 그리고 그 사이가 가까울수록, 유사도를 측정하는 것도 가능해진다. 결국 꼬맨틀이란 서비스도 이런 '유니코드 기반'의 위치가 가까울수록, 비슷한 단어라고 인식하는 구조임을 알 수 있다.
문자의 유사도를 유니코드 형태로 분석하는 방법이 있다면, 반대로 '자음, 모음' 형태로 분해하는 방식도 있다. 이 방식은 휴대폰 전화번호 목록을 'ㄱㄴㄷ' 순서로 정리한 것만 보더라도 확인이 가능하다. 첫번째 문자가 이루는 '자음, 모음'을 분해해, 어떤 자음이 문자열에 포함되었는지. 아닌지를 분석하는 방식이기 때문이다.
영어의 경우 개별 문자열에 '특정 알파벳'이 들어있는지만 체크하면 된다. 하지만 한글의 경우는 개별 '초성'을 기준으로 검색을 진행한다. 그리고 이런 '분해'과정을 처리하기위해, 입력된 문자를 분해하여 '초성'만 별도로 저장해두는 것도 한가지 방법이다. 예를 들어 '네이버'는 'ㄴㅇㅂ'로, '현대자동차'는 'ㅎㄷㅈㄷㅊ'라고 저장되는 방식이다. 이런 자음 분해과정을 통한 간편찾기 기능은 지도나 네비게이션 서비스에서도 자주 사용되는 방식이다.
데이터가 복잡한 지도의 경우, 'ㄱㄴㄷ' 처럼 초성 기반의 값을 별도로 정리해두는 것이 편하다. 그래야 사용자가 잘못된 값을 입력하더라도, 사람들이 많이 찾은 결과값과 비교해 유사도가 높은 결과를 보여줄 수 있기 때문이다. 이런 '별도의 값'을 입력하는 검색방식을 이해하려면, 실제 DB (데이터베이스)에서 어떤 방식으로 데이터를 저장하는지를 이해해야한다.
일반적으로 우리가 눈으로 보는 '검색'은 1:1 단어매칭이나, 특정 기준점에 맞는 결과를 나열해주는 경우가 많다. 그렇다보니 실제 DB (데이터베이스) 기준에서 검색이 일어나는 과정을 이해하기가 쉽지 않을 수 있다. 실제 DB는 개별 데이터를 하나만 갖고있는게 아니라, 여러 정보의 조합을 테이블 형태로 저장하고있다. 지도 서비스의 예를 들면 다음과 같은 형태가 된다.
지도 서비스에서 데이터를 저장하는 예시 사례
- 강남역 / ㄱㄴㅇ / GPS 경도 값 / GPS 위도 값 / 실제 지번 주소 / 시설 구분
위의 예시를 기준으로 보면, 검색을 할 때 여러 테이블 값을 확인하는걸 알 수 있다. 예를 들어 명칭 뿐 아니라 초성 키워드나, 지번주소, 시설구분 등도 검색의 기준이 될 수 있다. 게다가 여기에 별도 해시태그 (#) 같은 것들을 추가해줄 경우, 관리자나 일반 사용자가 검색하기에 더 편리한 방식이 될 수도 있다. 이런 방식을 잘 사용하고있는 서비스가 바로 인스타그램이나 트위터의 해시태그 사례다. 개별 게시글을 구분하기 위한 '카테고리' 형태로도 사용되며, 동시에 동일한 태그를 사용한 다른 게시글들도 쉽게 검색할 수 있다. 이런 특징 때문에, 과거 컴퓨터 개발 역사에서는 폴더정리를 할 때 '특수문자'를 넣는 방식으로 별도 태그 시스템을 구현하는 경우도 있었다.
특정 키워드와 연결되는 유사 / 인기 태그를 찾을 수 있는 서비스
https://www.tagsfinder.com/ko-kr/
위의 해시태그 생성기를 보면, 입력한 키워드와 연관이 없는 내용들도 생성이 되어있다. 그렇다면 이런 해시태그의 '연관도'는 어떤 방식으로 처리해준걸까? 이 부분을 이해하려면 다시 '단어의 의미'와 그 '연관 단어'의 개념을 이해할 필요가 있다.
연관성이 높은 단어들은 어떻게 연결해줄 수 있을까? 일반적으로 단어의 연관성을 연결하려면, '단어 안에 들어있는 문자'가 아니라, 실제 의미하는 내용의 연관성을 정리해야한다. 이것을 손쉽게 시각화한 사례가 바로 단어구름 (Text cloud)의 사례다. 단어구름은 특정 영역에서 사용된 빈도수가 높고, 연관성이 있는 단어들을 서로 묶어서 보여준다. 예를 들어 누군가의 블로그에서 자주 사용된 단어들을 꼽는다거나, 특정 정치인이 연설할 때 자주 사용한 언어들을 꼽는다는 식이다. 하지만 이런 방식은 '실제 언어가 의미하는 내용의 연관성'과는 차이가 있다.
그렇다면 실제 '단어의 의미'에 연관성이 있는 것들을 연결하려면 어떻게 해야할까? 실제로 이 지점부터는 인간이 할 수 있는 내용이 아니라, AI가 필요한 딥러닝의 영역이 된다. 실제 '유사어'들이 서로 얼마나 비슷한 의미를 가지는지. 언어학적인 필터링을 통해 그 의미가 '동일'하거나 '매우 비슷한' 기준을 구분해야하기 때문이다. 그래서 수학적인 분석을 통해 언어가 의미하는 내용을 서로 비교할 수 밖에 없다.
카카오 IT 팀의 단어간 유사도 파악에 대한 방법론
https://brunch.co.kr/@kakao-it/189
위 문서에서도 이야기가 나오지만, 한국어의 자연어 처리 과정에서는 '형태소 분리'를 통한 벡터화 (유사도를 여러 축으로 분석하여 거리를 표현한 방식) 과정이 필요하다고 지적하고있다. 조금 쉽게 이야기하자면, 실제 일치하거나, 유사한 언어일수록 가까이 두고, 그렇지 않은 단어일수록 멀리 둔다고 보면 된다. 이런 과정을 word to vector 과정이라 말하는데, 이 영역부터는 'AI와 딥러닝'에 가까운 영역이 된다. 통계학과 언어의 연관관계를 찾아내기 위한 AI 학습이 필요해지는 지점이니, 기획자가 처리할 수 없는 지점이 되는 것이다.
Word to vector에 대한 기술적 도해본
다만 이런 과정을 그나마 유사하게 정리한 것이 - AI 기반 챗봇의 '시나리오 분기' 개념이다. 개별 시나리오를 정해놓고, 사용자의 피드백이 '어떤 정보 시나리오에 더 가까운지'를 분석하여, 해당 시나리오 문답을 시작하는 방식이다. 이 부분은 실제 AI가 사용자의 입력 텍스트를 분석해, 그 안에 어떤 의도가 담겼는지. 그리고 기존에 주어진 시나리오들 중에 무엇과 가장 가까운지를 파악하게된다. 결국 특정 단어와 문장이 '무슨 의도'를 가졌는지를 파악해야 이런 과정이 가능하니. 사람이나 AI가 아니고서는 파악이 어려운 지점들이 생길 수 밖에 없다. 이런 내용을 좀 더 자세히 알고싶다면, 네이버의 개발 컨퍼런스 관련 자료를 참조하면 좋다.
네이버 데뷰 2021 : 사용자의 의도와 취향을 이해하는 네이버 통합검색
https://blog.naver.com/PostView.naver?blogId=lcs5382&logNo=222765204382
결국 검색 시스템을 다루려면, 어떤 형태로 무슨 결과들을 묶어서 보여줄 것인지. 하나하나 시나리오를 설계하고, 분류하는 과정이 필요하다. 그리고 그 과정에서 얼마나 다양한 '기괴한 입력'들까지 처리할 수 있는지에 따라 완성도가 달라질 수 있다. 가장 핵심적인 방식은 모든 검색어 결과를 저장해서, 어떤 결과를 찾아내려했는지. 통계를 만드는 것이다. 그리고 이런 통계가 일정한 수준으로 쌓였을 때, '추천 키워드'를 검색 빈도수 기준으로 설정하는 것도 한가지 방법이다. 다만 실제 검색결과에 사용자가 만족했을지, 그 키워드를 찾으려한 것이 맞는지는 별도로 고려해주어야한다.
오늘은 '검색'을 어떻게 설계할 것인지. 그 기능이 무엇으로 이뤄져있는지에 대해서 다뤄보았다. 사실 일반인이 이해하기는 쉬운 내용이 아니기 때문에, 내부 교육 과정에서도 너무 어렵다는 평가가 많았다. 다만 이 부분을 제대로 이해하지 못하면, 검색 설계를 진행할 때에도 단순한 기능만 사용할 수 밖에 없다.1:1 문자일치 기능을 넘어서, 어떤 방식으로 컨텐츠를 묶어줄 것인지. 어떤 데이터를 끌어와서 사용자가 만족스러운 결과를 찾게 할 것인지. 다양한 지점을 고민할 수 있는 기획자 / 디자이너들이 더욱 많아지면 좋을 것 같다.