Code Sprint 2015 Round 2 – VOD 추천 출제 후기

안녕하세요, Round 2의 출제를 맡았던 홍금원입니다. Round 2문제는 신동훈, 백종범 님과 함께 공동 출제를 했습니다.

저희는 디지털 컨텐츠 추천시스템 개발을 담당하고 있습니다. 개인적으로는 작년 Round 1의 출제를 하고 두 번째입니다만, 작년보다 여러모로 아쉬움이 많이 남는 대회였던 것 같습니다.

출제의도

Round 2는 VOD 추천 알고리즘을 개발하고 성능을 평가하는 문제입니다. 보다 정확히는 2014년 9월부터 2015년 2월까지의 VOD 컨텐츠 정보와 구매 이력을 제공하고 각 고객의 3월 영화 구매를 예측하는 방식이었습니다.

여기서 한가지 문제가 발생합니다. 관찰력이 뛰어나신 분들께서는 이미 눈치를 채셨겠지만, 과연 구매 예측문제가 컨텐츠 추천문제와 동일한가라는 질문입니다. 제 생각으로는 구매 예측과 컨텐츠 추천이 차이가 있다고 생각합니다.

만약 고객이 이미 사기로 마음먹은 컨텐츠를 시스템이 예측한다면, 어떤 측면에서는 서비스 제공자나 고객에게 큰 의미가 없을 수 있습니다. 이와 달리, 고객의 취향에는 부합하지만 고객이 미처 모르고 있는 좋은 컨텐츠를 찾아서 제공하는 것이 추천으로 더 가치 있는 일이 될 수도 있을 것입니다.

하지만, 서비스 제공자 입장에서 그것이 고객에게 정말로 좋은 추천이고 도움되는지를 파악하는 것은, 즉 추천 알고리즘을 평가하는 것은 쉽지가 않습니다. 아마도 이를 위해서 가장 좋은 방법 중 하나는 고객에게 자신이 추천 받은 내용에 대해 만족했는지를 매번 직접 물어보는 것일 텐데요.

Are you satisfied with your care

신뢰성 있는 샘플 설정, 조사 시간/비용, 고객의 불편함을 고려할 때 쉽지 않은 부분이 많습니다.

따라서 종종 간편하게 추천된 아이템 중에서 실제 고객이 소비한 아이템의 비율을 측정하여 사용합니다. 결론적으로 Round 2에서는 VOD 추천과 구매 예측을 동일하다고 가정하였습니다.

문제에는 다음과 같은 내용이 있습니다.

  • 특정 기간 동안의 고객별 컨텐츠 구매 기록이 주어지고, 해당 고객이 향후 어떤 컨텐츠를 구매할지 예측하는 문제입니다.
  • 2014년 9월 1일부터 2015년 2월 28일 까지의 컨텐츠 구매 이력을 바탕으로 2015년 3월 1일부터 2015년 3월 31일까지의 구매를 예측합니다.
  • 데이터는 학습 데이터와 테스트 데이터 두 가지로 구분하고, 또 학습 데이터는 다시 구매이력과 컨텐츠 정보 두 가지로 구분합니다. 테스트 데이터는 학습 구매이력에 포함된 전체 사용자 ID를 대상으로 하기 때문에 별도로 제공하지 않습니다.

본 내용으로부터 문제의 출제의도는 기존 데이터의 분석을 통해 향후 unknown 데이터의 예측 문제라는 것을 알 수 있습니다. 대부분의 참가자 분들께서는 이러한 출제 의도와 평가 방식을 정확히 이해하시고 문제풀이 시도를 하셨습니다. 하지만, 일부 참가자 분들께는 모호했던 부분이 존재했던 것 같습니다. “과연 3월 데이터가 우리에게 unknown한가?”라는 부분입니다.

출제 당시 정말로 unknown한 데이터를 제공하고 평가를 한다면, 정답을 알 수 없어 평가가 힘들기 때문에, 3월 데이터는 8월 현재의 시간적으로는 과거이지만 2월까지의 데이터를 활용하는 참가자에게는 unknown하다고 가정을 한 것입니다.

접근 방법

본 문제는 기계학습으로 풀 수 있는 문제입니다. 기계학습이 항상 복잡한 수학적, 통계 과학적 접근을 통해서만 해결 가능한 방법론으로 생각하실 수 있지만, 꼭 그렇지만은 않습니다.

예컨대, 작년 Round 1은 문자열 segmentation 관련된 문제였는데요. “할수있다”라는 문자열을 “할 수 있다”로 올바르게 띄어쓰기 위한 가장 간단한 학습방법으로 각 음절간 띄어쓰기 확률모델을 사용할 수 있습니다.

만일 ‘할’과 ‘수’가 띄어 쓸 확률 P(할 수|할,수)가 ‘할’과 ‘수가’ 붙여 쓸 확률 P(할수|할,수)보다 크다면, 띄어쓰기 조합 중 “할 수”를 선택함으로써 간단히 띄어쓰기를 진행할 수 있습니다. 이와 다른 방식으로, “할과 수는 무조건 띄어 쓴다”라는 규칙을 추가함으로써 규칙기반의 모델을 활용할 수도 있습니다. 다만 그 규칙은 example input으로부터 생성 가능한 것이어야 합니다.

현재 Wikipedia를 보면 기계학습을 다음과 같이 정의하고 있습니다.

“Machine learning explores the construction and study of algorithms that can learn from and make predictions on data. Such algorithms operate by building a model from example inputs in order to make data-driven predictions or decisions, rather than following strictly static program instructions.”

여기서 중요한 두 가지 요소는 “building a model from example inputs”라는 것과, “rather than following strictly static program instructions” 두 가지입니다.

우리는 example inputs을 학습 데이터 (training data)라고 부릅니다. 테스트 데이터 (test data)는 학습 데이터에 포함된 전체 사용자를 대상으로 구매 (Yes)와 비구매 (No)에 관한 label이 달린 데이터입니다. 따라서 예측 알고리즘 입장에서는 unknown 데이터입니다.

일반적으로 학습데이터로부터 이용자의 구매패턴에 관한 여러 특성을 파악하고 예측에 활용한다면 문제가 되지 않습니다만, 테스트 데이터의 특성을 어떤 방식으로든 직접 파악하고 예측에 활용할 수 없다는 것은 이미 널리 알려진 불문율입니다.

예컨대, 띄어쓰기 문제에서 test data에 담긴 띄어쓰기 대상 문장을 미리 알고 있다면, 우리는 그 문장에 해당하는 규칙만을 프로그램에 달아서 실행할 수도 있을 것입니다. 하지만 이러한 방법은 일반화 (generalization)가 되어 있지 않아서 테스트 문장이 달라지면 사용할 수가 없습니다.

추천 알고리즘

추천 문제도 이와 비슷합니다. 많이 사용하는 알고리즘은 “사용자 X가 구매했던 과거의 데이터를 바탕으로 이와 구매 관점에서 관련된 영화 리스트 Y를 생성”하는 방법에 기반을 두고 있습니다. 대부분의 참가자 분들께서 사용하신 방법도 모두 위 방법에 기반을 두고 있습니다. 다만, “관련된 영화”라는 것을 정의하는 방식에서 조금씩 차이가 납니다.

널리 알려진 방법은 아마도 user-based collaborative filtering (user-based CF) 알고리즘 입니다. 이 방법은 사용자 x의 추천 리스트를 만들기 위해, x와 유사한 사용자 집합 Y를 구하고, Y에 속한 사용자들이 구매했던 아이템을 x의 추천리스트로 만들어주는 방식입니다. 비슷한 방식으로 item-based collaborative filtering (item-based CF) 알고리즘은 사용자간 유사도를 구하지 않고, 직접 아이템과 아이템간의 유사도를 계산한 뒤, 유사한 아이템을 추천하는 방식입니다.

관련된 내용을 보시려면 MapReduce 기반 대용량 추천을 참고하시면 됩니다. 두 방법 중 어떤 방식이 더 적합한지는 application의 종류와 추천 전략에 따라 달라집니다. 본 문제의 경우 사용자는 9만여명이고 아이템은 8천여건으로 상대적으로 적습니다. 속도 면으로는 item-based 방식이 유리하다고 볼 수 있어서, 실제로 많은 참가자들께서 item-based 방식으로 문제를 푸셨습니다. 여기서 좀더 나아가 대용량 데이터를 다룰 경우에는 고려해야 되는 경우의 수가 기하급수적으로 커지기 때문에 이를 효과적으로 처리하기 위해 다루고자 하는 정보의 종류와 수를 줄여서 좀더 효율적으로 데이터를 처리할 수도 있습니다.

본 대회에서는 위와 같은 전통적인 방식에서 벗어나 색다른 방식으로 문제에 접근하신 분들이 계셨습니다. 아마 본 README에서 소개가 될지는 모르겠으나, 다음과 같은 아이디어들이 있었습니다.

  • 영화 X구매 직후 바로 구매하는 영화 Y는 관련성이 더 높다고 보고 이를 찾아 다른 사람에게 추천한다.
  • 사용자 별로 장르/감독/국가/배우/단가 등의 영화 선호도를 설정하고 선호도에 맞는 영화를 추천한다.
  • 컨텐츠의 텍스트로부터 언어적이고 내용적인 정보를 직접 추출하여 컨텐츠와 컨텐츠 사이의 유사도 계산에 활용한다.
  • 컨텐츠의 인기도, 최신성, 등급 등을 고려하여 가중치를 매기고 이를 사용자 별 컨텐츠를 순위화하는데 활용한다.

참가자 통계

Round 2에서는 총 86명이 참가를 하셨고 그 중 최종파일을 제출하신 분들은 22분입니다. 이 분들 중, 최종 스코어 외에 소소코드, 실행여부, 실행시간을 종합적으로 고려하여 최종 순위에 등록되신 분들이 총 10분입니다.

이 분들 중, 5분이 python, 3분이 C/C++, 그리고 두 분은 java와 Scala를 사용 하셨습니다. 아마 Python이 사용 가능한 machine learning library가 풍부하기 때문이 아닐까 생각됩니다. 실행 속도는 알고리즘마다 다양합니다. 가장 빠른 분은 학습 및 실행시간을 포함하여 1분이 되지 않습니다. 평균적으로는 학습 및 실행에 30분 정도 소요되었습니다.

마치며

문제를 준비하며 어려웠던 부분 중 하나는 데이터를 준비하는 일이었습니다. 올해 참가자에게 제공되지는 않았으나, 실제로는 B급 19금 영화구매가 많이 일어나는 서비스 특성상, 일반인에게 이러한 구매이력을 그대로 제공하면 실제 구매예측에 side-effect가 일어날 것으로 파악이 되었습니다. 따라서, Round 2를 위해 이들을 제거하는 작업을 거쳐 새롭게 데이터를 준비하게 되었습니다.

또한 기존의 추천 경진대회와는 다르게 Round 2에서는 컨텐츠 메타정보를 학습데이터로 함께 제공했습니다. 이렇게 한 이유는 추천에 관한 아이디어나 intuition을 얻으려면 제공 드린 데이터를 좀 더 많이 naked-eye로 살펴봐야 한다고 생각을 했기 때문입니다. 이를 통해서 textual 정보가 효과적으로 활용될 수 있을지 참가자 분들을 통해서 확인하고 싶기도 했습니다.

물론 많은 참가자 분들이 이런 고민을 하시고 이를 활용하여 문제풀이를 시도하신 분들도 계십니다. 다만, 일부 참가자 분들은 이 과정에서 공개된 메타정보를 순수 알고리즘에 활용한 것이 아니라, 테스트 데이터의 특성을 외부로부터 직접 얻어오는 데만 활용을 시도하신 분들도 계셨습니다. 사실 이런 부분까지는 저희가 미처 예상하지 못한 부분이었습니다. 이로 인해 순수하게 문제풀이에 접근하신 분들이 만에 하나 피해를 보실 수도 있다는 생각이 들었고, 본 후기를 통해서 죄송하다는 말씀을 드리고 싶습니다.

마지막으로 올해로 네 번째를 맞이한 Code Sprint에 참여해 주신 모든 개발자 분들께 깊은 감사를 드립니다. 개인적으로는 두 번째 대회였으나, 첫 번째보다 오히려 더 힘들었다는 기억이 남습니다. 다음에는 말씀 드린 부분을 보완하여 완성도 높은 문제로 참가자 분들께 다시 한번 다가가겠습니다.

감사합니다.

홍금원 Text Analytics팀

Text Mining 활용 시스템 발굴 및 적용 업무를 담당하고 있습니다.
Digital Contents 추천시스템 개발을 담당하고 있습니다.

공유하기