배경

이번 포스팅에서는 게임 고객 LTV 추정 작업 이후, 이를 직접적으로 활용하여 개발했던 예상 매출 추정 작업에 관해 소개 드리려 합니다. 고객 생애 가치를 의미하는 LTV는 특정 서비스를 이용하는 고객이 일생 동안 얼마만큼의 이익을 가져다 줄 것 인지 정량적으로 추정한 것을 의미합니다. 이와 관련하여 유저 세그먼트별 정보와 기간에 따른 단/중/장기 예상 수익 지표를 개발하였고 관련 내용을 지난 포스팅에서 다뤘습니다.

해당 지표는 일별 접속 유저들의 잔존율 정보와 ARPU 정보를 활용하여 추정한 값으로 향 후 30일, 90일, 180일, 365일 간 벌어들일 것으로 예상되는 수익을 의미했죠. 예를 들어, 2020년 8월 1일자 365일 예상 수익 지표를 조회한다면, 8월 1일에 접속한 유저로부터 향후 365일간 얼마를 벌어들일 것인지를 평균적인 값으로 추정한 것입니다. 따라서 이러한 지표를 통해 예측 기간별로 예상 수익을 비교할 수 있었고 더 나아가 유저 세그먼트 별 비교가 가능했습니다.

여기서 몇 가지 추가적으로 궁금한 사항이 생겼습니다. 일반적으로 회사는 사업 년도를 기준으로 매출 목표를 수립하고 그에 맞추어 비용 계획을 세우게 됩니다. 그렇기 때문에, 현재의 유저 수나 매출 상황이 계속된다면 사업 년도 말이 됐을 때 총 매출이 어느 정도 될지 예측하는 것은 중요합니다. 이에 따라, 기존 예상 수익 지표를 활용하여 이를 보조할 수 있는 지표를 생성하는 작업을 추가로 진행하게 되었습니다. 아주 간단하게 접근해본다면, 예상 수익 지표의 경우 오늘 접속한 유저의 향후 1년간 수익이기 때문에, 당해 사업년도 기간 동안 접속할 전체 유저 수를 예측할 수만 있다면, 이러한 예상 수익을 적당히 곱하여 사업년도 매출 추정이 가능하겠죠?

분석 설계

막상 실제 1년 매출을 추정하려고 보니 꽤나 어렵게 느껴졌습니다. 특히 매출에 큰 영향을 주는 여러 가지 업데이트나 이벤트가 계속 이뤄지는 상황에서 이로 인한 매출 변동을 미리 예측하는 것은 사실상 불가능에 가까웠죠. 그렇기에 너무 큰 욕심을 부리는 대신, 연초에 목표 매출을 수립할 때 도움을 줄 수 있는 보조 지표로 활용할 수 있도록 대략적인 추정치를 오차 범위와 함께 제공하는 것을 목표로 하였고, 이후에는 실제 사업 년도 기간이 지남에 따라 발생되는 데이터를 바탕으로 연말 매출 추정치를 점진적으로 보정해 나가는 방식으로 접근하였습니다.

아는 것은 활용하기

앞서 설명하였듯이, 우리의 분석 목표는 사업년도 시작일을 기점으로 사업년도 마지막일 까지의 1년 예상 매출을 추정하는 것이므로 사업년도 시작일부터 오늘(지표 조회 시점)까지의 매출 정보는 실제값을 그대로 이용하면 되겠죠. 즉, 시간이 지남에 따라 발생되는 실제 매출은 누적 반영하면서 남은 기간에 대해서만 예측치를 적용하면 됩니다. 또한 실제 데이터와 비교했을 때 년초에 갖고 있던 가정에서 달라지는 정보들을 활용하여 매일매일 1년 매출 추정치를 수정해 나가는 형태로 설계하였습니다.

만약 오늘이 8월 1일이라면, 이미 알고 있는 정보인 사업년도 시작일부터 7월 31일까지의 실제 누적 매출과 8월 1일부터 사업년도 말까지 남은 5개월간의 예상 매출 값을 더하여 지표를 제공합니다. 내일(8월 2일)이 된다면 예상 매출은 새롭게 갱신되어, 8월 1일까지의 실제 누적 매출과 8월 2일부터의 예상 매출을 더하여 제공하게 되는 것이죠.

[그림1] 지난 일자에 대해서는 실제 매출 값을 활용하며, 지표는 매일 갱신됩니다.

이러한 설계 아래에서 남은 기간(조회시점부터 사업년도 말일)까지의 예상 매출은 어떻게 구할 수 있을지에 대해 고민하였습니다. 기존 예상 수익 지표와 예상 수익 지표 계산시에 활용했던 방법들을 최대한 활용하였으며 아래에 작성한 크게 4가지 작업을 진행하였습니다!

  • 전체 유저 수 추정

    1년 동안 접속하는 전체 유저를 예측하기 위해선, 현재 시점에 활동하는 유저수뿐만 아니라 이후 기간 동안 추가로 접속할 신규 유저 수 추정이 필요합니다. 이를 위해 지금까지 일별 접속한 유저 정보를 이용해 일별 신규 유저 수 유저 비율을 추정하는 작업을 수행했습니다.

  • 예상 수익 지표 보정

    365일 기준 1인당 예상 수익 지표에 대해서 남은 기간에 대한 weight를 구해줍니다. 이때 1인당 예상 수익 지표 자체도 일자별로 조금씩 달라지기 때문에 이러한 변동성을 최대한 완화하기 위해 이동평균 값을 이용합니다. 마지막으로 일별 신규 접속 유저의 경우 드문드문 접속한 유저 집단이 많으므로 이에 대한 보정을 해줍니다.

  • DAU 보정

    이벤트/업데이트/작업장 유저의 유입으로 일별 DAU 값 자체가 편차가 크게 나타나므로 이런 편차를 완화하기 위해 이동평균 값을 이용합니다.

  • 매출 트렌드 보정

    모바일 게임들은 대개 론칭 초반에 AU나 매출이 정점을 찍고 시간이 지날수록 점차 하락하는 추세를 보이므로 이러한 트렌드를 감안하여 론칭 초반의 과대 추정 문제를 완화시켜줍니다.

세부 분석 내용

사업년도 동안 플레이할 전체 유저 수 추정하기

예상 수익 지표의 경우, 조회 시점에 접속한 유저들의 향후 수익을 의미하므로 조회 시점 이후에 접속한 유저에 대한 예상 수익 정보는 빠져 있습니다. 그렇기 때문에 사업년도 1년간 전체 유저에 대한 수익을 구하기 위해서는 해당 기간 동안 접속할 모든 유저 수를 추정하는 작업이 먼저 필요합니다. 이 때 조회 시점까지의 전체 활동 유저 수 및 일별 신규 유저 수 정보를 활용하여 아래와 같이 전체 유저 수를 계산하였습니다.

[그림2] 8월 1일 대비 신규 접속자가 얼마나 들어올지 비율을 예측합니다.

예를 들어 8월 1일을 기준으로 이후에 신규 접속하는 유저 비율은 아래 표와 같이 구할 수 있습니다.

실제 데이터로 신규 접속 유저 비율을 구해보면 그 형태가 유저들의 잔존율 그래프와 비슷한 패턴을 갖습니다. 따라서 저희는 유저들의 잔존율 함수를 추정할 때와 동일하게 분수 함수로 적합 시키는 방식을 신규 유저 비율 추정할 때도 사용하였습니다 (잔존율 함수 추정 방식과 관련된 내용은 지난 포스팅을 참고 바랍니다). 이렇게 추정된 함수를 이용하여 1년 동안 예상되는 일별 신규 접속 유저 수를 모두 더하면 총 접속 유저 수를 추정할 수 있습니다!

예상 수익 지표 보정

일별 신규 접속 유저를 추정한 이후에는, AU당 365일 예상 수익 지표를 곱하여 예상 매출을 계산하였는데요. 현실 상황과 비슷하게 예상 매출을 계산하기 위해서는 추가적으로 몇 가지 보정 작업이 필요했습니다.

  • 기간 보정

    365일 예상 수익의 경우 당일 접속한 유저의 365일간 벌어들일 것으로 예상되는 수익이므로, 8월 1일에 접속한 유저에 곱하여 사용할 경우에는 적절한 weight를 계산하여 곱해주어야 합니다. 즉, 사업년도 말인 12월 31일까지 총 153일간 벌어들일 것으로 예상되는 수익이므로 기존 예상 수익 지표에 \(\frac{153}{365}\) 라는 weight를 곱해줍니다. 마찬가지로 8월 2일에 새로 접속한 유저에는 \(\frac{152}{365}\) 를 곱해줍니다. weight는 비교적 직관적으로 계산한 값을 사용하였습니다.

    [그림3] 남은 기간에 대한 weight를 구해줍니다.

  • 변동성 보정

    매일 갱신되는 예상 매출 값의 경우, 일별 변동 폭이 크다면 사용자 입장에서는 이해하기 어려울 수 있습니다. 1년 매출 추정치를 조회했는데, 어제 조회한 값과 오늘 조회한 값이 매우 편차가 크다면 납득하기 어렵겠죠. 그런데 예상 매출을 추정할 때 사용되는 1인당 LTV 지표의 경우 이벤트나 업데이트 등으로 인해 값의 변동성이 다소 큰 편이었습니다. 따라서 이로 인한 예상 매출 추정치의 변동성을 완화시키기 위해 일별로 추정되는 LTV에 대한 30일 이동평균 값을 사용하였습니다.

  • 신규 접속 유저 보정

    위의 두 보정 작업을 진행하여도 예상 수익 계산 시 결과가 실제 매출보다 과대 추정되는 경향이 있었습니다. 과대 추정 원인에 대해 탐사 분석을 해보니 기준일에 접속한 유저군과 이후 신규로 접속한 유저군의 1인당 예상수익이 크게 다른 것을 알 수 있었습니다. 왜냐하면 특정일에 접속한 유저 집단에는 매일 접속하여 열심히 게임을 플레이하는 유저들의 비중이 높은 반면, 해당 일자에는 접속하지 않았지만 그 이후에 신규로 접속한 유저의 경우는 상대적으로 접속 빈도가 낮은 (즉, 잔존율이 떨어지는) 유저의 비율이 높았던 것이죠.

    따라서 이러한 차이를 고려하기 위해 신규 접속 유저에 대해서는 기존 유저의 1인당 예상 수익보다 낮은 값을 갖도록 1보다 작은 가중치를 곱하여 과추정을 완화시켰습니다. 이 때 적용할 가중치를 구할 때는 과거 데이터를 이용한 예상 매출과 실제 매출의 RMSE를 최소화하는 값을 찾는 방식을 이용하였습니다.

  • DAU 보정

    예상 수익 지표 자체의 변동성 이외에도 이벤트나 업데이트로 인한 유저 유입이나 작업장 유저의 유입으로 인해 특정 일자의 DAU가 크게 치솟는 경우가 있었습니다. 이에 따라, 앞선 방식과 비슷하게 30일 DAU의 이동평균 값을 사용하여 변동성을 완화하였습니다.

  • 매출 트렌드 반영

    앞서도 언급했듯이 대개 모바일 게임의 경우 게임 출시 초반에 DAU나 매출이 가장 높고 그 이후에는 점차 감소하게 됩니다. 그렇기 때문에 과거의 추세가 그대로 유지된다고 생각하고 예상 매출을 추정하면 과다 추정이 되기 쉽습니다. 따라서 이러한 감소 트렌드를 반영해야 하는데, 이를 위해선 기존에 론칭했던 게임들의 과거 추세 정보를 활용하였습니다. 기존 게임의 일 매출 시계열 데이터에서 추세 패턴을 추출해 보면 론칭 이후 일정 시점까진 지속적으로 감소 추세를 보이다가 점차 안정화되는 것을 알 수 있었습니다.

    이러한 선행 지식을 바탕으로 특정 시점까지는 감소하다가 특정 시점 이후로는 상수 값으로 수렴하는 트렌드 함수 L(t)를 추정하여 사용했습니다. 예상 매출 계산 시점으로부터 예측에 사용되는 기간인 60일 전과 감소 추세 시작 시점까지의 일자를 계산하고, 해당 일자를 추정된 트렌드 함수에 활용하여 0~1 사이를 갖는 비율 함수를 만들어주어 곱하였습니다.

[그림4] 추정된 트렌드 함수에 시점을 적용하여 0~1 사이를 값는 비율 함수를 곱합니다.

예상 매출 추정하기

최종적으로 위와 같이 실제 상황에 맞는 다양한 변수들을 고려하면, 예상 매출 추정식은 아래와 같이 계산되게 됩니다!

\[예상 매출 = ∑_{t} (t시점의\ 신규\ 접속\ 유저\ 수)\times (한명\ 당\ 사업년도\ 말까지의\ 예상\ 수익),\ t = 0, ... , x \\ = ∑_{t} { DAU^{*} × f(t) } × { (AU당\ 365일\ 예상\ 수익)^* × weight × \frac{( x - t )}{365} } × L'(t),\ t = 0, ... , x \\ \\ 단,\ \ t: 기준일로부터\ 경과\ 일차, \\ x: 오늘\ 부터\ 사업년도\ 말까지의\ 일자\ 수, \\ f(t): 신규\ 접속\ 유저\ 비율\ 함수, \\ weight: 예상\ 수익\ 보정치로\ t=0일\ 때\ 1,\ 그\ 외에는\ 0\ 에서\ 1\ 사이\ 특정\ 값, \\ DAU^*: DAU\ 보정치,\ 즉,\ DAU의\ 30일\ 이동평균\ 값, \\ (AU당\ 365일\ 예상\ 수익)^*: AU당\ 365일\ 예상\ 수익\ 보정치, \\ L'(t):\ 매출\ 트렌드\ 함수에\ 예상\ 매출\ 계산\ 시점을\ 적용한\ 함수\ 0\ 에서\ 1\ 사이\ 단조\ 감소\ 함수\]

마치며

다른 업무들도 그렇겠지만, 이번 작업은 더욱이 구체적으로 참고할 만한 자료가 없어 시행착오를 많이 겪었던 작업인데요. 실제로 이러한 방식 이외에도, 예상 매출 추정 방법에는 더 좋은 추정 방법이 있을 것으로 예상도 됩니다. 그럼에도 실제 상황과 최대한 비슷하게 여러 보정 작업을 거치며 여러 시도를 했기에, 비슷한 고민을 하고 계신 분들께 약간의 아이디어가 되길 바라며 이 글을 마칩니다.