시작하며
그 동안 저희 블로그를 꾸준히 보셨던 분은 이미 아시겠지만 엔씨소프트에서는 2017년부터 외부에 있는 데이터 분석가들을 대상으로 한 데이터 분석 경진 대회를 매년 개최해왔습니다. 2019년에는 빅콘테스트라고 하는 한국정보화진흥원과 빅데이터포럼에서 공동으로 주최하는 데이터 분석 경진 대회에 공동 주관사로 참여하여 ‘기대 이익을 고려한 고객 이탈 예측’ 이라는 주제로 대회를 진행했습니다.
빅콘테스트는 올해로 7회째를 맞이한 국내 대표적인 데이터 분석 경진 대회인데, 이미 2018년에 한 차례 참여한 적이 있었습니다 (관련링크1: 2018 빅콘테스트 문제 소개, 관련 링크2: 2018 빅콘테스트 후기). 당시 대회를 통해 우수한 분들을 채용할 수 있었고, 대회를 준비하고 진행하는 과정에서도 여러 가지 배운 것이 많았기에 2019년에도 참여를 하게 되었습니다. 그래서 2019년 7월 17일 설명회를 시작으로 9월 10일까지 약 2개월 간 대회가 진행되었으며, 1차 예선 서류 심사와 2차 본선 PT 심사를 거쳐 11월 26일에 진행한 시상식을 끝으로 약 4개월 간의 긴 여정을 마쳤습니다.
이번 포스팅에서는 2019 빅콘테스트 결과 및 대회를 진행하면서 느낀 점을 정리해 볼까 합니다.
문제의 의도
대회에 대한 자세한 소개 및 문제 설명은 작년에 이미 관련 글을 작성한 적이 있으니 여기서는 개략적인 내용과 이렇게 문제를 설계한 의도에 대해서 간략하게 정리해 볼까 합니다. 대회 문제에 대한 자세한 내용은 2019 빅콘테스트 글을 참고하시기 바랍니다.
저희가 제시한 문제는 온라인 게임 고객들의 과거 게임 활동 데이터를 이용해서 향후 언제 이탈할지를 예측하고 이 예측한 정보를 서비스에 활용했을 때 어느 정도의 기대 이익을 얻을 수 있을지를 추정하는 예측 모델을 만드는 것입니다. 사실 ‘고객 이탈 예측’은 다소 진부하고 전형적인 예측 문제이기 때문에 저희는 좀 더 문제를 흥미롭게 만듦과 동시에 좀 더 실전에 가까운 상황을 만들고자 아래와 같은 몇 가지 조건 및 상황을 추가했습니다.
시간의 변화에 강건한 모델 구축
온라인 게임은 컨텐츠 업데이트나 게임 밸런스 변화 혹은 각종 프로모션 및 이벤트 등의 사업 활동으로 인해 다양한 변화가 빈번하게 발생합니다. 그리고 이런 변화로 인해 유저들의 게임 활동 패턴 역시 영향을 받습니다. 예측 모델은 고객의 과거 활동 패턴을 학습하여 활용하는 방식이기 때문에 이런 변화를 고려하지 않고 만든 예측 모델은 실전에서 사용할 수 없습니다. 따라서 저희는 이런 상황을 고려한 문제를 만들기 위해 학습 데이터와 평가 데이터의 집계 기간을 다르게 하였고 더 나아가 평가 데이터의 경우 각기 다른 시기에 집계한 두 세트를 준비했습니다. 이를 통해 저희는 참가팀들이 우수한 성능을 얻으려면 특정 시기의 활동 패턴에 과적합되지 않는 모델링 기법을 제안하기를 기대했습니다.
<그림 1> 학습 데이터와 평가 데이터 집계 시기
기대 이익을 고려한 예측 성능 평가
참가팀들은 저희가 제공한 고객별 다양한 게임 활동 정보를 이용해서 앞으로 각 고객별로 향후에 게임을 얼마나 더 할지에 대한 ‘생존 기간’과 앞으로 예상되는 ‘일별 결제 금액’ 을 예측하게 됩니다. 그러면 해당 예측 결과를 실제 관측 결과와 비교해 보고 예측 모델의 성능을 측정하게 되죠. 보통 이런 류의 경진 대회에서는 예측 모델의 성능을 평가할 때 RMSE 나 AUC, F1-score 등의 지표를 이용해서 얼마나 정답을 잘 맞추는지 혹은 얼마나 정답과의 오차가 작은지에 초점을 맞춥니다. 하지만 저희는 여기서 한 걸음 더 나아가 예측 모델을 실제 서비스에 적용했을 때 얻을 수 있는 ‘기대 이익’을 측정하는 방법을 시도했습니다. 이를 위해 저희가 사용한 성능 측정 공식은 다음과 같습니다 (위 공식에 대한 자세한 설명은 2019 빅콘테스트 에 나와 있습니다).
기대이익=전환율×(추가생존기간×일별평균결제금액)−인센티브기대이익=전환율×(추가생존기간×일별평균결제금액)−인센티브
우연히 어떤 참가자가 작성한 글을 본 적이 있는데, 저희가 제공한 자율 평가 사이트를 통해 테스트를 해보니 모든 고객을 이탈한다고 예측하는 것이 예측 모델을 만들었을 때보다 더 기대 이익이 높게 나오더라는 내용이 있었습니다. 정확한 의도는 잘 모르겠지만 뭔가 ‘왜 그냥 정확도를 측정하게 만들지 않고 이런 어뷰징이 가능한 평가식을 설계했느냐’ 란 원망이 느껴져서 이에 대해 간략히 변명을 해볼까 합니다.
제가 생각하기에 예측 모델의 궁극적인 목적은 단순히 정답을 잘 맞추는 것이 아닙니다. 예를 들어, 단순히 모든 고객이 이탈한다고 가정하고 마케팅을 하는 것이 예측 모델을 이용해서 차별화된 마케팅을 하는 것보다 결과가 더 좋게 나온다면 이건 마케팅에 문제가 있는 것이 아니라 예측 모델에 문제가 있는 것이겠죠.
이건 마치 월스트리트저널에서 개최한 주식 투가 수익률 대회에서 주식 전문가들의 예측이 원숭이 보다 못하더라는 이야기를 연상케 합니다. 이런 문제를 피하려면 예측 모델을 잘 만드는 것도 중요하겠지만 애초에 모델의 목표를 정확도가 아니라 원래의 활용 의도에 맞는 기대 이익으로 설정하는 것이 대안이 되지 않을까 생각했습니다.
더 나아가 기존에 흔히 사용하는 RMSE 나 AUC 같은 측정 지표는 학습 알고리즘의 일반적인 성능을 평가하는 용도로는 적합할지 모르지만, 구체적인 목표가 정해진 예측 분석의 결과를 평가하는데에는 부적절하지 않나 라는 생각도 들었습니다. 좀 과장하자면, 위와 같은 측정 지표를 이용해서 예측 모델의 성능을 평가하는 것은 마치 프로그램 로직의 실행 성능을 측정하는데 big-O notation을 이용하는 것과 비슷하지 않나 싶습니다 (참고로 big-O notation은 전산학에서 알고리즘의 복잡도를 비교하기 위한 수학적 표기법입니다).
결국 이런 저런 이유로 인해 이번 대회에서는 위와 같이 자체적으로 성능 평가 측정식을 만들어 봤습니다.
재현성 평가
2018년 빅콘테스트를 진행했을 때, 참가팀들에게 결과 제출 시 발표 문서 외에도 분석 및 모델링에 사용한 소스 코드 를 제출해 달라고 요청했습니다. 그러나 실제 결과를 받아 보니 대부분의 참가팀들이 발표 문서는 굉장히 잘 만든 반면, 데이터 전처리 및 모델링을 위해 작성한 소스 코드는 거의 정리가 되어 있지 않아 결과 재현은 커녕 제대로 실행이 되는 경우가 거의 없었습니다.
대개 분석가는 분석 결과를 잘 정리해서 다른 사람을 설득할 수 있는 문서를 잘 만드는 것이 중요하다고 얘기합니다. 그래서 데이터 분석가가 가져야 할 가장 중요한 역량으로 ‘스토리텔링’을 꼽는 경우가 많습니다. 하지만 제가 경험한 바에 의하면 많은 분석들이 그저 그럴듯하게 잘 꾸며진 문서만을 남기고 일회성 프로젝트로 산화하는 경우가 많았습니다. 저는 그 이유가 데이터 분석 프로젝트의 최종 산출물이 ‘문서’가 되기 때문이라고 생각했습니다.
분석 결과가 실전에서 유의미하게 활용되려면, 제 생각에 데이터 분석의 최종 산출물은 ‘프로덕트’ 나 ‘서비스’가 되어야 합니다. 이를 위해선 데이터 분석가들도 개발자들처럼 본인이 작성한 소스 코드 및 중간 결과물을 다른 사람이 쉽게 재현할 수 있도록 깔끔하게 정리할 수 있는 소프트웨어 엔지니어링 능력이 필요합니다.
특히, 데이터 분석 분야에서는 최근에 ‘재현성의 위기’에 대해 문제 의식을 갖고 이를 극복하려는 노력이 학계를 중심으로 퍼져 나가고 있죠. 엄밀히 말하면 소스 코드를 깔끔하게 정리하는 것과 과학에서 얘기하는 재현성은 다소 차이가 있지만 최소한 서비스에서의 활용을 생각해 볼 때 엔지니어링 단계에서라도 결과가 쉽게 재현되도록 만드는 것은 중요하다고 생각했습니다.
그래서 이번에는 결과 제출 시 요구되는 코드 및 모델링 결과물의 형식을 <그림 2>와 같이 엄격하게 정의하였고, 결과 재현이 잘 되는지 여부를 심사 결과에 반영하겠다고 안내했습니다.
<그림 2> 분석 코드 및 모델링 결과 제출 양식
심사 결과
대회 심사는 1차 예선 심사와 2차 본선 심사로 나뉘어 진행되었습니다. 1차에서는 예측 성능과 재현성 평가 결과 그리고 제출한 발표 문서를 이용해서 진행했으며 이를 통해 1차 선정된 16개 팀을 대상으로 발표 심사를 통해 최종 수상팀을 선정했습니다. 이번 대회에 참가한 팀은 총 531개 팀으로 2018년과 정확하게 같았으나, 최종 결과를 제출한 팀은 38개 팀으로 2018년의 93개 팀에 비해 크게 줄었습니다. 아무래도 좀 더 문제가 어려워졌고 제출 조건도 더 까다로워진 것 때문이지 않나 생각합니다.
이번 대회를 위해 담당자들이 문제를 설계할 때 나름 창의적이면서도 실전에서 겪게 될 여러 가지 이슈들을 최대한 반영하려고 꽤 많은 시간과 노력을 들였고 제공 데이터 역시 지난 해보다 더 다양한 종류를 신경써서 준비했기 때문에 참가 규모가 줄어든 점은 다소 아쉬웠습니다.
각 주요 심사 항목별 결과를 정리하면 다음과 같습니다.
예측 성능
예측 성능은 앞서 언급했듯이 참가팀이 제출한 예측 모델을 저희가 제시한 시나리오에 적용했을 때 예상되는 기대 이익을 측정한 후 이 값이 높을 수록 높은 점수를 얻는 방식입니다. 또한 평가 데이터가 두 세트이기 때문에 각각의 세트에서 측정된 기대 이익의 합이 최종 결과가 됩니다. 그런데 최종 결과를 살펴보니 몇 가지 흥미로운 점이 눈에 띄였습니다.
첫째, 상/하위 팀들 간에 점수 분포가 뚜렷하게 구분되었습니다. 2018년에는 일부 팀을 제외하면 대다수가 상위권 점수를 얻는 것에 비해 이번 대회에서는 상위팀 그룹과 하위팀 그룹 사이에 점수 차이가 컸습니다.
둘째, 두 개의 평가 세트의 성능을 비교해 보면 상위 그룹과 하위 그룹이 정반대의 특징을 보였습니다. 상위 그룹은 Test set 1 성능이 Test set 2 성능보다 더 높은 반면, 하위 그룹은 반대로 Test set 2의 성능이 Test set 1 성능보다 더 높게 나왔죠. 앞서 소개했듯이 Test set 1 이 Test set 2에 비해 라벨이 제공된 학습 데이터와 시기적으로 더 가깝기 때문에 고객의 활동 패턴이 좀 더 유사할 것이고 따라서 직관적으로 보자면, Test set 1의 성능이 더 높은 것은 자연스럽습니다. 그런데 하위 그룹은 오히려 Test set 2의 성능이 더 높은 점은 꽤 흥미로운 현상이었습니다.
<그림 3> 참가팀들의 예측 성능 결과 – 빨간색 대각선은 Test set 1과 Test set 2의 성능이 같은 경우를 나타내는 선이다. 하위 그룹은 빨간색 선을 기준으로 좌측 (Test 2 성능이 더 높음) 에 주로 위치한 반면, 상위 그룹은 우측 (Test 1 성능이 더 높음) 에 주로 위치해 있다.
재현성 평가
참가팀들이 제출한 분석 코드의 재현성을 평가하기 위해 저희는 아래와 같은 채점 기준을 만들고, 25점 만점을 기준으로 감점해 나가는 방식을 이용했습니다.
<그림 4> 재현성 평가 기준 도식
위 기준으로 채점한 점수는 다시 (다른 평가 항목의 배점 방식과 통일하기 위해) 아래 배점표에 맞게 점수를 올림 처리하여 최종 점수를 책정했습니다.
<표 1> 재현성 평가 배점표
실제 점수 | 최종 배점 |
---|---|
0≤x≤20≤�≤2 | 2 |
3≤x≤53≤�≤5 | 5 |
6≤x≤96≤�≤9 | 9 |
10≤x≤1310≤�≤13 | 13 |
14≤x≤1714≤�≤17 | 17 |
18≤x≤2118≤�≤21 | 21 |
22≤x≤2522≤�≤25 | 25 |
코드 제출 양식을 정확히 정하고, 재현성 평가를 심사 기준에 포함한다고 안내한 덕분인지 2018년과 비교했을 때 참가팀 대부분이 결과를 잘 정리했으며, 사소한 수정 및 디버깅만으로도 결과가 잘 재현되었습니다.
1차 예선 심사 및 2차 본선 심사
1차 예선에서는 참가팀이 제출한 발표용 문서와 앞서 언급한 평가 결과를 종합하여 심사를 진행한 후 최종적으로 16개 팀을 선정하는 작업을 진행했습니다.
<그림 5> 1차 예선 통과팀의 예측 성능 및 재현성 평가 결과
이렇게 선정된 16개 팀에 대해서는 2차 본선 심사를 통해 기 제출했던 발표 문서를 이용해 발표를 진행하고 이에 대한 질의 응답을 하는 방식으로 진행했습니다. 본선 심사는 외부 심사 위원분들의 정성 평가를 통해 진행되었기 때문에 상세한 기준을 정리하기는 힘들고 대신 제가 발표 문서를 심사하면서 느꼈던 소감을 간략히 정리하자면 다음과 같습니다.
우선 2018년에는 탐사 분석이나 이탈 원인에 대한 추정, 이탈을 방지하기 위한 방안에 대한 서비스 기획적인 제안 등 정성적인 분석에 신경 쓴 팀들이 많았습니다. 반면, 이번 대회에서는 데이터 전처리나 모델링 및 튜닝 등 좀 더 공학적인 내용 위주로 발표 문서가 이뤄져 있었습니다. 때문에 솔직히 문서를 읽는 입장에서는 2018년 자료가 좀 더 다양하고 흥미로운 내용이 많았던 반면, 2019년 자료는 전반적으로 내용이 다소 딱딱하여 심사 과정 자체가 그리 재미있지는 않았습니다. ^^;
하지만 참가자 대부분 해당 업계의 도메인 지식이 부족한 학생들인 점을 고려하면, 다소 억지스러울 수 있는 분석이나 제안을 하기 보다는 차라리 제시한 문제를 해결하기 위한 기술적인 부분에 집중하는 것이 좀 더 현실적이지 않나 라는 생각도 들었습니다.
앞서 잠깐 언급했듯이 전 ‘스토리텔링’에 의존한 분석이 갖는 문제가 많다고 생각합니다. 자칫하면 번뜩이는 아이디어나 기발한 상상력, 유려한 말솜씨에 의존하게 되어 듣는 사람은 현혹시키지만 현실과는 동떨어진 분석이 높게 평가받을 가능성이 높기 때문입니다. 우리가 흔히 책이나 언론 등을 통해 접하는 데이터 분석 성공 사례들이 대부분 일회성의 이벤트로 그치는 이유는 바로 이렇게 그럴듯한 스토리에 의존하여 분석이 진행되기 때문이 아닌가 생각합니다. 데이터 분석이 소위 말하는 ‘데이터 과학’이 되려면 화려하고 흥미로운 분석이 아니라 근거와 논리에 기반한 분석이 필요한 것이죠.
한편 그런 측면에서 볼 때, 많은 참가팀들이 본인들의 분석 자료를 설명할 때 왜 이런 기법을 사용했는지에 대해 ‘이렇게 시도해보니 가장 예측 성능이 좋게 나왔다’ 라는 식으로만 답변하고 좀 더 체계적이고 논리적인 근거를 제시하지 못해서 다소 아쉬웠습니다. 실제 본선 심사 때에도 이런 점들을 심사위원분들에게 가장 많이 지적 받았습니다.
참가팀들이 사용한 주요 기법들
참가팀들이 사용한 기법들은 2018년과 비교했을 때 큰 차이가 없었습니다. 여전히 XGB나 GBM 같은 부스팅 알고리즘이나 랜덤 포레스트 같은 앙상블 기법을 가장 선호했습니다. 다만 2018년에 비해 딥러닝 기법을 시도한 팀이 다소 늘었고 사용한 방식 역시 좀 더 능숙해 진 것 같습니다. 특히, 2018년에는 단지 딥러닝 한번 시도해 봤다 정도였다면 이번에는 실제 의미 있는 결과를 도출한 팀들이 제법 있었습니다. 심지어 대상 수상팀은 딥러닝을 주요 학습 알고리즘으로 사용한 팀이었죠.
또한 기존에 다른 문제들처럼 정답을 잘 맞추는데에만 집중한 팀들보다 기대 이익 최적화 측면에서 다양한 시도를 했던 팀들이 대부분 좋은 예측 성능을 보였던 점이 인상적이었습니다. 처음 문제를 설계할 때는 저희 역시 처음 해보는 작업이었기 때문에 걱정을 많이 했는데 다행히 문제의 의도대로 결과가 잘 나온 것 같아 안도했습니다.
반면, concept drift를 해결하기 위해 그다지 눈에 띄는 시도가 없었던 점은 다소 아쉬웠습니다. 여러 가지 시도를 하기는 했지만 실제 그런 방법들이 강건한 모델을 만드는데 도움이 되는지 명확하게 근거를 제시하는 팀은 없었습니다. 한편으로는 저희가 이에 대해서는 문제를 잘 설계하지 못했단 반성이 들었습니다. 가령, 학습 데이터도 평가 데이터처럼 여러 개의 시차를 둔 자료를 만들어 제공하는 식으로 좀 더 문제 설계에 신경을 썼어야 하지 않았나 라는 생각이 들었습니다.
어쨌든 위와 같은 이유로 인해 2019년 참가팀들의 기법들을 단순히 쭉 정리하는 것은 자칫하면 ‘2018 빅콘테스트 후기’ 의 동어 반복이 될 것 같습니다. 그래서 이 글에서는 문제의 핵심이었던 ‘시간에 대한 강건성’과 ‘기대 이익 최적화’를 위해 사용했던 방법들 위주로 정리해 봤습니다.
시간에 대한 강건성
1) 비율 변수 생성
유저 활동량 관련 데이터를 직접 사용하지 않고 직전 시간 대비 변화율로 치환한 파생 변수를 생성하여 학습에 활용하는 팀들이 다수 있었습니다. 특정 수치가 아니라 시간에 따른 변화량을 이용하면 시간의 흐름에 대해 좀 더 강건할 것이라는 가정을 이용한 것이죠.
2) 시간에 따른 변화가 적은 변수만 선택
저희가 제공한 데이터는 수십 가지의 유저별 활동변수들이 일단위로 집계된 자료입니다. 어떤 참가팀은 세 가지 데이터셋 (train set, test set1, test set2) 에서 평균 결제 금액이 안정적인 날짜의 데이터만 추려서 학습하는 방법을 사용했습니다.
<그림 6> 시간에 대한 강건성을 고려한 변수 선택 시도 (출처: ‘우리팀화이팅’ 팀 분석자료)
3) 추세 관련 파생 변수 생성
어떤 참가팀은 각 변수들에 대해서 – 주로 시계열 경제 지표를 분석할 때 많이 사용하는 – 일자별 추세나 변화량을 나타내는 다양한 파생 변수들을 생성하여 학습에 활용했습니다. 이들이 사용한 파생 변수들에는 다음과 같은 것들이 있었습니다.
- DMI (Directional Movement Index) & ADX (Average DMI)
- CCI (Commodity Channel Index)
- MACD (Moving Average Convergence Divergence)
- SONAR
- Chaikin’s Volatility
- RSI (Relative Strength Index)
- William’s %R
4) 예측 시점이 각기 다른 다수의 예측 모델 생성
제공된 학습 데이터는 모두 예측 시점이 통일된 데이터인데, 한 참가팀은 좀 더 다양한 예측 시점을 만들기 위한 변형을 통해 시간의 변화에 강건한 모델을 만들려는 시도를 하였습니다. 개인적으로는 나름 참신한 시도라고 생각했습니다만 예측 성능 자체는 그리 좋지않았습니다 (만약 데이터가 좀 더 풍부했다면 어땠을까 궁금합니다).
<그림 7> 인위적으로 예측 시점에 변화를 준 예측 모델 생성 (출처: ‘from bigcon import prize’ 팀 분석자료)
5) Semi-supervised learning
학습 데이터로 생성한 예측 모델의 결과를 평가 데이터에 적용해 새로운 라벨을 만든 후 다시 학습에 활용하는 반지도 학습을 이용한 팀이 있었습니다. 전 나름 참신한 시도라고 생각했습니다만, 한 심사위원 분께서 이 방법은 오버 피팅을 야기할 수 있어 그리 좋지 않은 것 같다는 비판적인 의견을 주셨습니다.
6) 학습 데이터와 평가 데이터 통합한 데이터 전처리
학습 데이터와 평가 데이터의 변수들을 합쳐서 스케일링을 하거나 PCA 혹은 AutoEncoder 등의 알고리즘을 써서 변형하는 방법을 시도한 팀들이 많이 있었습니다. 그러나 사실 이것은 실제 서비스 단계에서는 사용할 수 없는 방법입니다. 왜냐하면 모델을 학습하는 시점에서는 평가 데이터를 확보할 수 없기 때문이죠.
<그림 8> Sequence Autoencoder 를 이용하여 학습 데이터와 평가 데이터의 공통 특징 추출 (출처: ‘규복동’ 팀 분석 자료)
기대 이익 최적화
1) 라벨 데이터 변형
저희가 제시한 기대 이익 계산 수식에서는 비이탈 고객이나 무과금 이탈 고객은 예측을 통해 얻을 수 있는 이익이 없는 것으로 가정하고 있습니다. 따라서 이런 고객을 정확히 예측하는 것은 예측 성능 개선에 아무런 도움이 되지 않죠. 따라서 이런 점을 이용하기 위해 아예 비이탈 고객과 무과금 고객을 ‘기대 이익이 0인 고객’으로 묶어서 라벨을 만든 후 학습을 하는 팀이 있었습니다. 또 다른 팀은 비이탈 고객의 결제 금액을 0으로 일괄 적용하여 무과금 고객으로 바꿔서 학습하는 팀도 있었습니다. 이 역시 비슷한 의도입니다.
둘 다 단순히 라벨 데이터를 최대한 정확히 학습하겠다는 것 대신, 철저히 기대 이익 관점에서 데이터를 재해석해서 라벨 정보를 단순화함으로써 학습 복잡도를 낮추겠다는 의도였다고 해석할 수 있겠습니다.
2) 의도적인 과소/과다 추정
몇몇 참가팀들은 여러 시도를 통해, 문제에서 주어진 기대 이익 추정 공식의 특성 상 생존 기간은 과소 추정하는 것이 과다 추정하는 것보다 유리하고 반대로 일별 결제 금액은 과다 추정하는 것이 과소 추정하는 것이 유리하다고 판단해서 이런 특징을 모델링 단계에서 이용하였습니다.
가령 ‘라이온킹’ 이란 팀은 일반적으로 평균치를 추정하는 회귀 모델링 대신 quantile regression 기법을 이용해서 생존 기간과 결제 금액 예측 시 평균보다 과다/과소 추정이 되도록 학습하였습니다.
<그림 9> Quantile regression 을 이용한 의도적인 과소/과도 추정 (출처: ‘라이온킹’ 팀 분석 자료)
3) 기대 이익 최적화에 맞게 loss function 재정의
대부분의 참가팀들이 ‘생존 기간’과 ‘일 평균 결제 금액’ 을 각각 예측하는 모델을 따로 만든 반면, 대상을 수상한 ‘규복동’ 팀은 ‘생존 기간’과 ‘일 평균 결제 금액’을 한번에 예측하는 (즉, 종속 변수가 두 개인) 딥러닝 모델을 만들었습니다. 그리고 이 모델을 학습할 때 가중치를 업데이트하는 loss function을 지정할 때 예측 오차를 계산하는 방법 대신 문제에서 제공한 기대 이익 추정 공식을 참고해서 기대 이익을 최대화할 수 있도록 loss function을 재정의했습니다.
특히, 이렇게 기대 이익 추정 공식을 직접 적용할 경우 발생할 수 있는 문제를 해결하기 위한 몇 가지 트릭을 적용한 점이 인상적이었습니다. 이런 노력 덕분인지 이 팀은 예측 성능 항목에서 가장 높은 점수를 획득했습니다.
<그림 10> 기대 이익을 고려한 loss function 설계 (출처: ‘ 규복동’ 팀 분석 자료)
대회 심사 및 운영 과정에서 느낀 점
2018년 빅콘테스트를 진행하면서 데이터 분석가를 꿈꾸는 우수한 학생들이 이렇게나 많다는 점에 정말 크게 놀랐었는데 이번 대회에서도 역시 이 점을 다시 확인할 수 있었습니다.
개인적으로는 이번 대회를 통해 과도한 예측 성능에 대한 집착이 갖는 문제점을 생각해 보는 계기가 되었습니다. 이런 류의 경진 대회 특성 상 예측 성능을 이용해 순위를 매길 수 밖에 없는데 대부분 비슷한 실력의 참가자들이 경쟁을 하다 보니 1~2% 정도의 근소한 차이로 순위가 바뀌는 경우가 빈번했습니다. 그런데 사실 실제 서비스에서는 대개 이런 정도의 차이는 그리 중요하지 않습니다.
물론 1%의 성능 향상이 서비스의 품질을 결정짓는 분야도 있습니다. 그러나 실전에서는 약간의 성능 저하는 감수하더라도 다른 측면을 고려하는 것이 더 이득인 경우가 많습니다. 가령, 한 본선 참가팀은 수십 개의 모델을 조합해서 예측하는 방법을 통해 예측 성능을 극대화한 점을 강하게 어필했었죠. 실제로 이런 노력 덕분에 이 팀은 자율 평가에서나 최종 결과에서나 전체 팀 중에서 최상위 수준을 기록했습니다. 하지만 실전에서 사용하기에는 전체 학습 과정이나 튜닝 과정이 복잡해서 다소 오버 엔지니어링이라는 생각이 들었습니다. 반면, 또 다른 참가팀의 경우 앞선 팀에 비해 예측 성능은 약간 떨어졌지만 본인들이 사용한 PC에서 학습에 불과 15분 밖에 안 걸릴 정도로 가벼운 모델이란 점을 어필하였죠. 극단적인 성능을 요구하는 분야가 아닌 이상 저라면 후자의 기법을 사용할 것 같습니다.
2012년에 스트라타 컨퍼런스를 참석했을 때 넷플릭스의 분석가의 발표를 들은 적이 있습니다. 발표 내용은 넷플릭스에서 2006년부터 2009년까지 3년간 100만달러의 상금을 걸고 진행했던 Netflix prize 에 대한 후기였었는데 당시 대회 최종 우승팀은 대략 백가지가 넘는 모델을 조합해서 만든 앙상블 모델이었다고 합니다. 그런데 발표자의 말에 따르면 우승팀의 기법이 너무 복잡해서 서비스에 적용하지 못했고 결국 자기들이 자체적으로 비슷한 성능을 갖는 방법을 구현했다고 합니다. 이 것 역시 오버 엔지니어링의 문제점을 보여주는 사례라 생각합니다.
심지어 이번 문제의 경우 데이터 자체가 갖는 변동성이 크기 때문에 평가 데이터가 달라짐에 따른 예측 성능에 차이가 큰 편입니다. 실제 평가 데이터 중 20%만을 샘플링해서 측정한 leader board 의 순위와 전체 데이터를 이용해서 측정한 최종 순위에서도 차이가 있었습니다. 따라서 이런 상황이라면 1~2% 정도의 성능 차이는 큰 의미가 없는 것 같습니다. 그럼에도 불구하고 대회의 원활한 운영을 위해 어쩔 수 없이 이 차이로 인해 결과가 달라질 수 밖에 없는 것은 경진 대회의 한계인 것 같습니다.
데이터를 준비하는 과정에서 생기는 오류를 어떻게 극복할지에 대한 이슈도 있습니다. 2017년과 2018년 대회를 진행할 때도 데이터 공개 이후에 중요한 오류가 발견되어 다시 추출해서 제공하는 해프닝이 있었기 때문에, 이번에는 오류가 없도록 최대한 신경을 썼음에도 불구하고 또 다시 오류가 발견되어 수정 조치가 있었습니다. 아무래도 제공하는 데이터의 종류가 많고 전처리 단계가 복잡하다보니 오류를 발견하기가 힘들 수밖에 없죠. 버그가 없는 소프트웨어가 없듯이 오류가 없는 데이터를 만드는 것은 불가능하겠지만 적어도 이런 오류를 쉽게 검증하거나 발견할 수 있는 방법이 뭐가 있을지에 대해서 고민하는 계기가 되었습니다. 데이터 분석 분야에서도 단위 테스트나 정적 분석과 같은 소프트웨어 공학 기법들이 필요하겠다는 생각이 들었습니다.
발표 심사 과정에서도 몇 가지 한계가 느껴졌습니다. 아무리 심사 위원들이 경험 많고 뛰어난 분들이라 하더라도 과연 15~20분 정도의 짧은 시간 동안 참가팀들의 분석 내용을 모두 이해하고 평가할 수 있을지에 대해 저 스스로도 의구심이 들었습니다. 심사 위원 분들 중에는 1차 예선 단계에서 이미 문서 리뷰를 한 경우도 있었지만 본선 심사에만 참여한 분들도 있었습니다. 아마 이런 분들은 발표 내용 파악하기가 훨씬 더 힘들었을 것이라 생각합니다.
심지어 8시간 동안 16개 팀의 심사를 보는 것은 솔직히 체력적으로나 정신적으로나 굉장히 무리가 가는 작업이었습니다. 중간에 쉬는 시간이 있었지만 제 스스로도 온전히 집중하여 평가했다고 자신하기 힘듭니다. 주관사 입장에서는 최대한 많은 참가팀에게 발표 기회와 수상 혜택을 주겠다는 좋은 의도이기에 무턱대고 비판하면 안되겠지만 향후에는 좀 더 공정하고 생산적인 심사 및 발표 자리를 만들기 위해 개선이 되면 좋겠습니다.
마치며
매해 대회를 준비하고 진행하면서 힘든 점도 있지만 배우고 느끼는 점이 참 많습니다. 다만, 대회 운영에 대한 부담이 큰 것 또한 사실입니다. 그 동안 경험해 보니 이런 규모의 대회를 진행하려면 준비과정까지 합쳐서 거의 8개월 정도는 1~2명의 담당자가 이 업무에 집중해야 하더군요. 저희 조직의 원래 역할이 대외 활동이 아니라 데이터 분석업무인 상황에서 매년 진행하는 것은 솔직히 부담이 되었습니다. 더 나아가 그동안 대회를 통해 쌓은 노하우와 지식을 내재화하는 시간이 필요하겠다는 생각도 들었습니다. 그래서 올해에는 대회를 진행하지 않기로 결정했습니다.
대신 올해에는 지금까지 대회를 통해 쌓은 노하우를 실전에 어떻게 적용할 수 있을지 고민해 보려고 합니다. 그동안 대회에 참가하신 많은 분들께 진심으로 감사드리며 다음 번에는 데이터 분석 분야의 발전에 기여할 수 있는 다른 기회로 찾아 뵙겠습니다.