하이라이팅 구문을 통한 추천 API 구현

새로운 아하 모먼트를 위해

추천 기술이 개발되며 라이너가 플랫폼으로 새롭게 변해가는 과정에 있습니다. 기존에 유틸리티로서 충실히 역할을 해주었던 라이너의 하이라이팅 기능에도 새로운 변화를 주자는 이야기가 나왔습니다. 바로 유저가 콘텐츠를 하이라이팅할 때마다 추천되는 페이지를 동적으로 변화시키는 기능입니다.

포켓에서는 스크랩할 때마다 관련 페이지를 데스크탑 브라우저 우측 상단에 띄워줍니다. 라이너에서는 그것에서 한발 더 나아가 하이라이팅을 할 때마다 추천 페이지가 바뀌는 것을 생각했습니다. 아무래도 라이너의 가장 큰 매력 중에 하나는 하이라이팅을 하는 행위이고 라이너 안에는 고품질의 콘텐츠가 가득하기 때문입니다.

라이너 추천 엔진이 할 수 있는 일

라이너의 추천 엔진은 두 가지 일을 할 수 있습니다.

  • 어떤 문서와 유사한 문서를 찾는다
  • 문서 목록을 유저가 선호하는 순서대로 정렬한다

첫 번째 기능을 통해서 포켓과 같은 종류의 추천을 할 수 있습니다. 문서의 벡터를 활용하여 유사 문서를 찾는 일입니다. 문제는 이 두 가지 기능을 어떻게 활용해야 하이라이팅할 때마다 바뀌는 문서 추천을 구현할 수 있을지에 대한 것이었습니다.

후보군을 추출하자

라이너 추천 엔진은 특정 유저와 특정 문서간의 선호 관계를 숫자로 표현할 수 있습니다. 따라서 하이라이팅을 할 때마다 변하는 추천의 경우 하이라이팅 되는 문장들과 비슷한 내용을 가진 문서들을 찾을 수만 있다면, 이후에는 해당 문서들을 개인화 정렬하여 서빙만 하면 됩니다. 따라서 문제는 과연 어떻게 유저가 하이라이팅한 문구와 비슷한 내용의 문서들을 찾을 수 있을까?로 바뀌게 되었습니다.

사실 이것은 검색?

문구와 비슷한 내용의 문서를 찾는 것은 결국 검색과 유사합니다. 라이너에는 이미 검색 기능이 구현되어 있었습니다. 따라서 처음에는 기존 검색 API를 이용하여 후보군을 추출하고, 이를 개인화하여 전달하도록 구현했습니다. 그리고 다음과 같은 두 가지 문제를 만나게 되었습니다.

1. 퍼포먼스 이슈 발생

문구가 길어지는 경우 기존 검색 API의 방식으로는 기대했던 퍼포먼스가 나오지 않았습니다. 라이너는 문서 인덱싱에 엘라스틱 서치를 사용하고 있었는데 사용되고 있는 search query는 문구가 길어지면 실행 시간이 기하급수적으로 늘어났습니다. 이에 검색되는 문구의 길이를 제한을 해야했습니다.

더 좋은 방법은 문구에서 핵심 키워드를 뽑는 방식이지만 현재는 키워드를 뽑는 장치가 없기 때문에 퍼포먼스가 허용하는 최대한의 길이까지 자르는 형식으로 대응했습니다.

2. 안 비슷한 정보들이 검색됨

기존 검색 로직은 매칭에 대한 최소 요건으로 필터링한 뒤, 문서의 스크랩 수로 정렬하여 상위 결과만 가져오게 됩니다. 필터링의 경우 엘라스틱 서치 match query의 minimum_should_match라는 값을 통해 구현하였습니다.

minimum_should_match parameter | Elasticsearch Reference [7.9] | Elastic

입력되는 문구가 문서의 내용에 얼마나 매칭 되어야 하는지 정해 줄 수 있습니다. 입력되는 문구의 길이에 따라 매칭 되는 비율을 동적으로 정했습니다. 하지만 문구 검색의 경우는 질의되는 단어의 수가 많아 핵심이 아닌 단어들 때문에 검색 조건을 통과하는 문서들이 많았습니다. 최종 정렬은 스크랩 수로 했기 때문에 하이라이팅된 문장의 내용과는 상관이 없지만 인기가 많은 문서들이 추천 후보군으로 들어오는 경우가 빈번하게 일어났습니다.

이에 스크랩 수 기준의 정렬에서 문구와의 유사도 정렬로 변경하였습니다. 이는 _score라고 하는 엘라스틱 서치의 기본 점수 계산에 의한 정렬입니다. 엘라스틱 서치는 단어의 출현 빈도, 단어간 유사도 등을 고려하여 종합적으로 _score를 계산합니다. 유저가 좋아할만한 문서를 정렬하는 일은 추천 엔진이 잘 판단해줄 것이라고 믿고, 후보군은 내용의 유사도를 통해 가져오는 방식으로 바꾸었습니다. 그리고 이를 통해 확실히 유사한 문서가 추천이 되는 것을 확인할 수 있었습니다.

유사한 문서가 추천되는 결과 값

추후 과제

1. 질의 키워드 추출

입력되는 문구의 핵심 키워드가 뽑힐 수 있다면 검색 품질과 퍼포먼스 모두 향상될 수 있습니다.

2. 키워드 벡터 추출

추출된 키워드를 엘라스틱 서치를 통해 단순히 매칭을 하는 방법보다는 키워드 자체의 벡터를 추출하여 더 빠르고 정확한 검색이 가능합니다.

조금 더 나아가 질의어 내 단어들의 벡터를 조합하여 질의어 자체의 벡터를 추출하는 방법도 있습니다.

라이너는 채용 중

#we’re_hiring

라이너 팀에서는 의미있는 관계 속에서 빠르게 성장하며 의미있는 일을 함께 하실 똑똑한 분들의 합류를 기다립니다!

자세한 내용은 아래 채용 사이트 링크를 통해 확인하실 수 있습니다.