11번가 추천 엔진 교체 (RecoPick -> Colloseo)

안녕하세요. Data Infrastructure팀(이하 DI팀)에서 Data Infra/Application 개발을 하고 있는 Data Programmer 엄태욱 입니다.

이번 글을 통해 지난 글에 공유 드렸던 실시간 데이터 처리 결과와 함께 Spark으로 재구현한 xTogehter를 이용해, 기존에 11번가에서 사용하던 레코픽(이하 RecoPick) 추천 엔진을 Colloseo 추천 엔진으로 교체한 과정을 공유하겠습니다.

11번가의 추천 서비스

11번가는 RecoPick에서 제공하는 두 가지 추천 서비스를 사용합니다. 먼저, “실시간 개인화 추천” 서비스로 다음과 같이 11번가 앱에 접속하면 홈 화면의 중간 쯤에 “최근 본 상품의 연관 상품” 또는 “내 쇼핑 성향에 맞는 상품”이라는 제목으로 사용자의 최근 성향을 실시간으로 분석하여 상품을 추천합니다.

11번가 실시간 개인화 추천 서비스

또 다른 추천 서비스로, “함께 본 상품(View Together)” 추천 서비스는 다음과 같이 11번가에서 특정 상품을 볼 경우 화면 가장 아랫부분에 “이 상품과 함께 본 상품”이라는 제목으로 현재 보고 있는 상품과 관련된 상품을 추천합니다.

 11번간 함께 본 상품 추천 서비스

Colloseo 추천 엔진

새롭게 개발한 추천 엔진의 이름은 Colloseo 입니다. Colloseo는 누구나 11번가용 추천 알고리즘을 만들면 A/B 테스트를 통해 알고리즘을 실험 할 수 있고, 기존 추천 알고리즘 보다 높은 성과를 내면 그 알고리즘이 채택된다는 의미로 이름 지어졌습니다. 즉, 데이터 기반으로 판단하고 채택할 수 있는 추천 플랫폼 개발을 목표로 합니다.

아직은 자유롭게 경합을 벌일 만큼 다양한 추천 엔진을 개발하지 않았지만, 이미 서비스 중인 RecoPick 실시간 개인화 추천 엔진을 개선한 Colloseo 엔진을 가장 먼저 개발했습니다. 실시간 개인화 추천은 크게 서비스 서버, 추천 결과 저장소, 추천 결과 배치 작업으로 나뉩니다. 서비스 서버는 기존과 같이 node.js 로 개발하고, 추천 결과 저장소는 실시간 데이터 처리에서 저장소로 썼던 Apache Phoenix로 바꿨습니다. 추천 결과 배치 작업(BuyTogether와 ViewTogether)은 Hadoop MapReduce로 각각 개발됐었는데, 성능을 높이기 위해 두 가지를 합치고 Spark으로 재개발하여 xTogether라는 이름으로 만들었습니다.

RecoPick 실시간 개인화 추천과 초기 Colloseo 실시간 개인화 추천을 비교하면 다음 표와 같습니다.

RecoPick vs. Colloseo 비교표

초기 버전의 Colloseo 실시간 개인화 추천은 다음 같은 변경으로 RecoPick 보다 조금 더 나은 추천 결과를 기대했습니다.

크로스 브라우저, 크로스 플랫폼을 통합한 사용자 기록

Cookie 기준의 사용자 구분 방식은 11번가를 접하는 다양한 채널인 데스크탑 웹, 모바일 웹, 모바일 앱 마다 사용자를 다르게 구분하고, 같은 플랫폼에서도 웹 브라우저가 다를 경우 다른 사용자로 인식합니다. 하지만 최근 사용자들은 결제 편리성으로 인해 웹에서 상품을 보고 모바일에서 결제하는 방식처럼, 두 가지 이상의 채널을 사용하는 경우가 많아 졌습니다. 또한 하나의 스마트폰에서도 메신저에 따라 상품 링크를 다양한 브라우저로 열어보는 경우가 많아졌습니다. 이러한 크로스 브라우저, 크로스 플랫폼 환경의 사용자 경험을 더 살리기 위해, Cookie를 사용하더라도 한 번이라도 11번가에 로그인 할 경우, 모든 Cookie를  하나의 사용자 기록으로 묶었습니다. 이렇게 사용자 경험에 대한 연속적인 추적이 가능해져 더 정확한 추천이 가능할 것으로 기대했습니다.

IDC 내 클러스터로 대용량 데이터 처리 환경 이전

AWS EMR에서 Hadoop MapReduce로 처리하던 ViewTogether를 플래닛IDC 내 DI클러스터(이하 DIC)에서 Spark으로 처리하도록 변경함으로써, 이미 다양한 데이터 처리를 위해 구축한 DIC의 풍부한 클러스터 자원을 활용할 수 있습니다. 실제로 기존 30일치에서 2배인 60일치로 처리 기간을 늘렸음에도 불구하고 더 짧은 시간 내에 계산을 완료할 수 있습니다. 이러한 변화는 하루에도 몇 번씩 상품이 변경되는 오픈마켓 환경에서 사용자의 반응을 더 빠르게 반영할 수 있을 것으로 기대했습니다.

ViewTogether와 함께 BuyTogether도 활용

BuyTogether는 ViewTogether에 비해 더 구매할만한 상품을 추천해 줄 수 있지만, BuyTogether는 구매 관련 기록만 사용하기 때문에 ViewTogether에 비해 추천할 수 있는 상품 수가 적은 문제점이 있습니다. 이런 문제점을 보완하려고 ViewTogether 보다 더 긴 기간(90일)의 사용자 기록을 사용해서 추천 상품 수를 늘렸습니다. 또한  BuyTogether를 ViewTogether와 함께 사용하면 60일치의 ViewTogether를 보완 할 수 있다고 생각했습니다.

서비스 서버의 연산 최소화

RecoPick의 실시간 개인화 추천은 하루에 한 번만 계산하는 ViewTogether에 의존했기 때문에, 최신 사용자 기록에 따른 ViewTogether의 변화를 적용할 수 없었습니다. 이를 보완하기 위해 실시간 사용자 기록을 더 복잡하게 사용했습니다. 즉, 사용자의 기록은 실시간으로 알 수 있지만 ViewTogether를 실시간으로 계산할 수 없어서, 사용자가 최근 본 상품들을 구하고, 해당 상품들을 본 다른 사용자를 다시 구하고(Item2User), 그 사용자들이 최근에 본 상품들을 구해서(User2Item), 그 상품들 내에서 작은 CF(Collaboration Filter)를 서비스 요청마다 실시간으로 계산했습니다. 이 과정은 매우 복잡하고, 실시간에 처리할 내용이 많아 서비스 서버에 많은 부담을 줬습니다.

이를 개선하기 위해 ViewTogether를 최신 사용자 기록을 반영해서 최대한 빨리 재계산 할 수 있도록 DIC로 이전하고 Spark으로 재개발했습니다. 그리고 Colloseo의 서비스 서버에선 단순히 사용자의 실시간 기록만 조회하고, ViewTogether와 BuyTogether를 조회해서 상품들을 재조합 하기만 하도록 단순화했습니다. 이처럼 비싸고 복잡한 런타임 연산을 최소화하고, 대신 그 부담을 짧은 주기의 배치로 이전해 전체 성능이 좋아지길 기대했습니다.

실시간 개인화 추천 A/B테스트

초기 버전의 Colloseo 실시간 개인화 추천 개발을 완료하고, 컨텐츠 기반 A/B 테스트 구현 사례에 소개된 CES(Contents-based Experiment System)를 이용해 A/B 테스트를 진행하였습니다. A/B테스트는 모바일 11번가 전체 트래픽을 사용자 기반으로 9:1로 나누는 1차 테스트, 5:5로 나누는 2차 테스트로 진행하였습니다.

1차 9:1 A/B테스트 (2016-12-02 10:00 ~ 2016-12-08 10:00 6일간 144시간)

실시간 개인화 추천 1차 9:1 A/B테스트 결과

1차 A/B테스트 결과 CTR이 2.5배 이상이 나왔습니다. 단순히 노출 대비 클릭 뿐만 아니라, 추천 경유 구매 건수를 비교했을 때 트래픽처럼 9배의 차이가 아닌 3.7배의 차이만 발생했습니다. 추천 경유 구매 수를 공개할 수 없지만, CTR 비(2.528) 만큼 실제 구매에도 영향을 끼쳤음을 추천 경유 구매 건수 비(3.714)를 통해 간접적으로나마 알 수 있습니다.

1차 A/B테스트의 결과가 좋았던 만큼 이어서 2차 A/B테스트를 진행했습니다.

2차 5:5 A/B테스트 (2016-12-13 10:00 ~ 2016-12-16 18:00 80시간)

실시간 개인화 추천 2차 5:5 A/B테스트 결과

5:5로 동일한 트래픽 분배가 이루어졌을 때라 두 추천 엔진의 비교가 좀 더 명확합니다. CTR의 향상만큼 추천 경유 구매 건수도 향상되었음을 알 수 있습니다. 내부 기밀에 해당하는 사항이라 CTR 이외의 많은 지표를 외부에 공개할 수 없지만, 다양한 지표(추천 경우 구매 건수, 추천 경유 매출 등)에서 Colloseo 실시간 개인화 추천이 월등한 결과를 보였습니다.

이에 따라 2차 5:5 A/B테스트가 끝난 2016-12-16 18시에 11번가의 실시간 개인화 추천은 RecoPick에서 Colloseo로 전환하였습니다.

실시간 개인화 추천 전환의 의의

RecoPick과 비교했을 때 Colloseo는 여러 가지 변경을 한 번에 적용했기 때문에, 어떤 변화가 어떤 영향을 끼쳤는지 정확히 알 수 없습니다. 다만, 이번 A/B테스트를 통해 다음 변화들이 추천 서비스에 긍정적인 영향을 끼쳤다고 생각합니다.

  • 크로스 브라우저, 크로스 플랫폼을 통합한 사용자 기록 활용이 추천에 도움
  • 짧은 주기의 ViewTogether, BuyTogether 계산이 추천에 도움
  • ViewTogether에서 더 오랜 기간의 사용자 기록을 사용하여 추천 상품 수를 늘림
  • ViewTogether 보다 추천 상품 수는 적지만, 더 오랜 기간의 사용자 기록을 사용한 BuyTogether를 ViewTogether와 함께 활용하여 추천 보완
  • 복잡한 계산을 런타임 연산에서 배치 연산으로 이전함에 따라 추천 서비스 서버의 부담 감소

함께 본 상품(ViewTogether) 추천 A/B테스트

실시간 개인화 추천 전환 이후 11번가의 또 다른 추천 서비스인 “함께 본 상품” 추천 서비스를 Colloseo xTogether로 교체하는 것이 좋은지 판단하기 위해 A/B 테스트를 진행했습니다. 실시간 개인화 추천과 마찬가지로 A/B테스트는 11번가 전체 트래픽 사용자 기반으로 9:1로 나누는 1차 테스트, 5:5로 나누는 2차 테스트로 진행했습니다.

1차 A/B테스트에 앞서 지난 실시간 개인화 추천 A/B테스트 때와 달리 RecoPick ViewTogether와 Colloseo xTogether에 변화가 있었습니다. 실시간 개인화 추천의 결과에서 Colloseo xTogether의 2시간 배치가 효과가 있었다고 생각해서 RecoPick ViewTogether도 Colloseo xTogether처럼 2시간 간격 배치로 변경했습니다. 그리고 Colloseo xTogether도 실제 서비스 기간이 짧아 추천 결과가 부족할 경우를 대비해 모바일 11번가 추천 결과가 없을 경우, 웹 11번가 추천 결과로 대체하도록 했습니다(당시 Colloseo xTogether의 ViewTogether 결과 중 모바일은 455만건, 웹은 235만건). 이에 따라 A/B테스트를 시행한 RecoPick ViewTogether와 Colloseo xTogether의 ViewTogether의 차이는 다음과 같습니다.

RecoPick ViewTogether vs. Colloseo xTogether 비교표

1차 9:1 A/B테스트 (2016-12-20 15:00 ~ 2016-12-27 15:00 7일간 168시간)

함께 본 상품 추천 1차 9:1 A/B테스트 결과

1차 A/B테스트의 결과는 근소한 차이(약 10%)로 Colloseo xTogether의 결과가 좋았습니다. 2배로 긴 기간의 사용자 기록이 조금 더 좋은 추천 결과를 만들었다고 생각할 수 있습니다.

1차 A/B테스트에서 Colloseo xTogether의 대체 가능성이 보임에 따라 2차 5:5 A/B테스트를 진행했습니다.

2차 5:5 A/B테스트 (2017-01-05 15:00 ~ 2017-01-12 15:00 7일간 168시간)

함께 본 상품 추천  2차 5:5 A/B테스트 결과

2차 A/B테스트의 결과를 이틀간 본 후, 여전히 Colloseo xTogether의 추천이 더 좋다는 결과를 확인하고, 2차 실험 도중 추가 실험을 시도했습니다. DIC 상황에 여유가 생기면서 Colloseo xTogether의 실행 시간이 1시간 이내로 줄어들고 있어서 굳이 2시간마다 배치 작업을 실행할 필요가 없었습니다. 그렇다고 1시간 배치 작업으로 만들 필요도 없어, 아예 끊임없이 배치 작업을 반복하도록 변경하였습니다. 이는 더 잦은 배치 작업이 추천에 어떤 영향을 끼치는지 알아보기 위함이었습니다. 2017-01-06 15시부터 변경을 적용하였는데, 저의 운영 실수로 인해 2017-01-07 05:00 ~ 10:00 사이에 배치가 동작하지 않았습니다. 그 결과인지 2017-01-07의 추천 결과는 전 날에 비해 좋지 않았습니다. 하지만 다음 날인 2016-01-08 부터의 추천 결과는 이전보다 훨씬 더 좋아졌음을 확인했습니다.

이 과정에서 “오전의 배치 중단으로 인한 추천 성능 감소가 왜 하루 종일 영향을 끼쳤을까” 라는 의문이 생겼습니다. 이는 다음과 같은 11번가의 트래픽 특성을 보면 알 수 있습니다.

2017-01-07 모바일 11번가 실시간 로그 처리 현황

2017-01-07 은 토요일임에도 불구하고 오전 9시 부근의 트래픽이 매우 높습니다. 이는 11번가는 매일 오전 9시에 긴급 공수 상품을 공개하거나 선착순 이벤트를 하기 때문에, 사용자들도 해당 시간대에 많이 11번가를 이용합니다. 따라서 이 시점에 새로 올라온 이벤트 상품들과 연관된 상품들을 추천하면 그 영향력이 매우 커집니다.

ViewTogether에 대한 A/B테스트를 통해 다음과 같은 노하우를 얻었습니다.

  • 짧은 주기의 배치 작업으로 사용자들의 관심사 변화를 빠르게 추천에 반영하면 더 좋은 추천 결과를 얻음
  • 오픈마켓의 특성 상 오래된 사용자 기록을 더 반영하기 보다 최신 사용자 기록을 빨리 반영하는 방법이 더 좋음
  • 짧은 주기의 반영도 중요하지만, 새로운 상품이 반영되는 시점을 놓치지 않아야 함

Colloseo xTogeher를 이용한 11번가의 ViewTogether 전환은 인프라 상의 변화로 인해 2017-02-13에 적용됐습니다.

맺음말

이로써 Spark Streaming을 이용한 실시간 추천 데이터 처리와 Spark을 이용한 추천 배치 처리가 모두 AWS에서 DI클러스터로 전환되어 AWS 비용 감소 효과와 DI클러스터 활용 증대를 모두 달성하였습니다. 또한 더 나은 추천 결과를 통해 매출 기여와 사용자 만족도 향상에도 기여하였습니다.

올해도 Colloseo 추천 엔진은 다양한 실험을 통해 11번가에 다양한 추천을 제공할 예정입니다. 많은 관심 부탁 드립니다.

끝으로, Colloseo의 아버지로서 많은 도움을 주신 정재훈 개인화TF장님과 A/B테스트를 통해 11번가 추천 엔진 교체에 힘써주신 조준호 Data Platform본부장님께 감사의 말씀을 전합니다.

엄태욱 Data Infrastructure 팀

Data Infrastructure팀 Data Programmer

공유하기

  • 조동환

    Traditional A/B 테스트보다는 Bayesian A/B 테스트를 추천드립니다. 보다 직관적이고 Sequential Bayesian Update를 통해서 (이전 실험의 결과를 다음번 실험의 Prior로 업데이트) 훨씬 빠른 시점에 결정을 할 수 있습니다. 다음은 R 패키지인데 Python 패키지도 검색해보면 나오는 것 같습니다. https://cran.r-project.org/web/packages/bayesAB/vignettes/introduction.html