gimmesilver's blog

Agbird.egloos.com

포토로그



엔씨소프트 게임 데이터 분석가 추가 채용 데이터분석

  저희 팀에서 데이터 마이닝 기반의 게임 데이터 분석가를 채용합니다. 지난 번(http://agbird.egloos.com/6110138)에 많은 분들이 관심가져주신 덕분에 좋은 분들과 함께 할 수 있었는데 이번에 동일한 직무에 대해서 1명을 더 채용하게 되었습니다. 이번에도 많은 관심 부탁 드립니다.
  참고로 2년 미만 경력 혹은 신입도 지원 가능하냐는 질문이 많이 있는데 원칙상 수시 채용은 2년 이상 경력자만 정직원 채용이 가능합니다. 만약 경력이 2년 미만인 경우엔 부족한 경력 기간 만큼 계약직으로 근무한 후 정규직 전환이 됩니다. 이점 참고하시기 바랍니다.

채용 공고: https://recruit.ncsoft.net/korean/careers/adoptionview.aspx?BNo=5468

회귀 모델을 이용한 지표 해석 방안 데이터분석

1. 우리 지표는 지금 좋은 걸까 나쁜 걸까?

  대부분의 회사에서는 여러 가지 현황을 파악하기 위해 다양한 지표를 집계합니다. 예를 들어 게임 회사의 경우 일별 접속 유저수 (Daily Active User, DAU), 일별 매출, 총 결제 유저수 (Paid User, PU), 유저별 평균 결제 금액 (Average Revenue Per User, ARPU) 등의 지표를 매일 혹은 매시간 단위로 집계하고 있습니다.
  그런데 대부분의 지표들은 그 수치만으로는 정성적인 판단이 어렵습니다. 가령 'DAU 10만' 이라는 수치는 좋은걸까요 아니면 나쁜 걸까요? 그 대답은 그 게임이 어떤 게임이고 어떤 기대치를 갖고 있으며 기존에는 어땠는지 등의 맥락에 따라 달라집니다.
이런 맥락 파악을 위해 사용하는 대표적인 방법이 '비교'입니다. 즉, 유사한 다른 게임의 DAU와 비교하여 이 게임이 대박인지 쪽박인지 판단하거나 혹은 지난 주 DAU와 비교해서 현재 상승세인지 하락세인지를 가늠합니다.
  특히 지표 모니터링 시에는 지표에 대한 시계열 그래프와 함께 '전일 대비 x % 상승' 혹은 '전주 대비 y % 하락' 등과 같이 과거 시점과의 비교 정보를 함께 제공합니다. 그러나 이런 식의 단순 비교는 몇 가지 문제가 있습니다.

  첫째, 지표가 갖는 여러 가지 주기적 변화에 영향을 많이 받습니다. 예를 들어 주말에 주로 사람들이 많이 접속하는 게임의 경우 월요일의 DAU는 항상 일요일보다 낮게 나오고 반대로 주말의 DAU는 항상 좋게 나올 것입니다. 따라서 대부분의 경우 이런 문제를 피하기 위해 주기성을 고려하여 비교합니다. 가령 일주일 주기에 영향을 많이 받는다면 DAU 비교 시 전일 지표와의 비교 뿐만 아니라 전주 대비 변화도 같이 확인하면 됩니다.
  그러나 대개의 경우 지표는 특정 하나의 주기에 영향을 받기 보다는 다양한 주기(시, 일, 주, 달, 분기, 년도)에 영향을 받습니다. 예를 들어 보통 온라인 게임에서는 '월초 효과'라는 것이 있어서 매월 초 매출이 가장 높습니다. 설날이나 입학/졸업 혹은 방학 역시 게임 지표에 영향을 주는 요소입니다.
  따라서 좀 더 세밀한 비교를 위해 이런 것들을 모두 고려하여 전날, 전주, 전달, 전분기 등 다양한 주기의 과거 시점 지표와 비교하기도 합니다. 하지만 이런 경우 지표에 대한 해석은 더 어려워집니다. 예를 들어 어제 게임을 업데이트한 후 지표에 미친 영향을 보고 싶은데 하필 어제가 주말이었고 이번 주는 월초인데 지난 달은 방학이었다면 게임 업데이트가 지표에 어떤 영향을 줬는지 파악하기란 매우 어려울 것입니다. 다시 말해 만약 DAU가 전날보다는 하락했고 전주보다는 상승했는데 전달보다는 하락했으면서 전분기보다는 높아졌다면 이건 좋은 걸까요 아니면 나쁜 걸까요? 결국 비교 대상이 많아지고 각 대상이 일치된 결과를 주지 못한다면 그런 비교는 판단에 도움을 주기는 커녕 혼란만 더할 뿐입니다.

  둘째, 특정 이벤트 효과가 지표 해석에 방해를 주기 쉽습니다. 예를 들어 특정 이벤트가 대박이 나서 이로 인해 매출이 큰 폭으로 늘었다면 해당 이벤트가 종료되고 난 이후 당분간은 지표가 항상 하락으로 표시될 것이고 이런 일관된 부정적인 정보는 담당자의 감각을 무디게 만들어 실제 긍정적인 효과를 줬던 이벤트나 컨텐츠가 무엇이었는지 눈치채지 못하게 만듭니다. 강한 빛이 비추고 난 이후에는 모든 게 깜깜하게 보이는 법입니다.

  셋째, 심지어 여러가지 이벤트가 겹쳐서 발생할 경우 문제는 더 복잡해집니다. 보통 대규모 프로모션을 진행할 경우 이번과 비슷한 과거 프로모션 시점의 지표와 비교합니다. 또는 대규모 컨텐츠 업데이트를 할 경우 업데이트 효과를 분석하기 위해 업데이트 전/후 지표를 비교합니다. 그런데 게임에서는 보통 여러 개의 이벤트가 동시에 진행되기 때문에 특정 업데이트나 프로모션이 지표에 미치는 영향을 측정하기 어렵습니다. 예를 들어, 대규모 컨텐츠 업데이트 후 DAU가 크게 늘었을 때 이게 업데이트에 대해 유저가 만족해서 생긴 현상인지 아니면 동시에 진행 중인 복귀 유저 프로모션 때문인 것인지 알 수 없는 것이죠.

  이 글에서는 이런 문제를 극복하고 지표를 좀 더 객관적으로 해석하기 위해 회귀 모델을 이용하는 방법을 제안합니다. 제안 방법의 목표는 다음과 같습니다.
  1. 현재 지표의 높고 낮음을 판단하기 위한 객관적인 판단 기준 제시하기
  2. 현재 진행되는 다양한 프로모션 및 업데이트가 지표에 미치는 효과를 각각 분리해서 추정하기
  3. 지표의 이상 여부 파악하기

  참고로 여기서 제안하는 방법은 검증된 기법은 아니고 말 그대로 제가 제안하는 방법입니다. 따라서 내용 상에 오류나 보완점에 대해선 댓글로 편하게 의견 주시면 좋겠습니다.

2. 지표에 대한 선형 회귀 모델 만들기

  선형 회귀 분석은 예측 변수(혹은 종속 변수라고도 함)의 값에 영향을 주는 변수들 각각의 영향력을 추정하여 다음과 같은 회귀식을 만드는 기법입니다.

y = beta0 + beta1*x1 + beta2*x2 + beta3*x3 + ...

  이 때 내가 분석하려는 지표를 y로 두고 이 지표에 영향을 주는 여러 가지 요소들(위에서 언급한 일, 주, 달 등의 시간 주기 및 이벤트나 업데이트 진행 여부)을 독립 변수(위 식에서 x1, x2, x3, ...)로 둔 후 회귀 모델을 만들면 각 변수의 회귀 계수는 각 변수가 지표에 미치는 영향력을 의미하게 됩니다.

  예를 들어 아래와 같은 1년치 지표가 있다고 해보죠(이 글에서 사용하는 데이터는 실제 데이터가 아니고 제가 인위적으로 만든 자료입니다).
  언뜻 보기에도 계절에 따른 주기성이 있는 것 같고 이벤트가 있었던 날의 지표가 아닌 날에 비해 전반적으로 높아 보입니다. 따라서 이런 경우 위와 같이 단순히 과거 지표와의 변화만 모니터링해서는 지표의 좋고 나쁨을 판단하기 어렵습니다. 이제 위에서 제안한 회귀 분석을 위해 지표에 영향을 줄만한 요인들을 뽑아 독립변수를 생성합니다. 여기서는 다음과 같은 요소를 정의했습니다.

  • 월: 1~12월
  • 요일: 월~일요일
  • 이벤트1~4: 게임에 적용한 다양한 이벤트들을 비슷한 유형끼리 4개 카테고리로 나눈 후 각 유형의 이벤트가 있었던 날은 그 이벤트에 해당하는 변수에 1을, 아니면 0을 표기

  이렇게 생성한 데이터의 예는 아래 그림과 같습니다.
  이제 위 데이터를 이용해서 아래와 같이 회귀 모델을 생성합니다.

# 월과 요일을 factor 형으로 만드는 이유는
# 이렇게 하면 R에서 선형 회귀 모델링 시 자동으로 더미 변수를 생성해 주기 때문입니다.
data$month <- as.factor(month(data$date))
data$wday <- as.factor(weekdays(as.Date(data$date)))
model <- lm(dau ~ month+wday+event1+event2+event3+event4, data)


  이 회귀 모델의 결과는 아래와 같습니다.

summary(model)

Call:
lm(formula = dau ~ month + wday + event1 + event2 + event3 +
event4, data = data)

Residuals:
Min 1Q Median 3Q Max
-2683.0 -698.6 -36.7 682.2 2629.0

Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 58975.47 231.56 254.684 <2e-16 ***
month2 187.37 273.27 0.686 0.493
month3 -7584.61 266.56 -28.453 <2e-16 ***
month4 -7159.08 268.31 -26.682 <2e-16 ***
month5 -7673.25 266.22 -28.823 <2e-16 ***
month6 -7618.63 274.98 -27.706 <2e-16 ***
month7 -154.90 271.30 -0.571 0.568
month8 -203.52 266.23 -0.764 0.445
month9 -7601.16 268.62 -28.297 <2e-16 ***
month10 -6972.23 266.09 -26.203 <2e-16 ***
month11 -7560.89 268.16 -28.195 <2e-16 ***
month12 -42.94 266.85 -0.161 0.872
wday목요일 -308.42 204.04 -1.512 0.132
wday수요일 31.87 205.72 0.155 0.877
wday월요일 -521.30 203.99 -2.555 0.011 *
wday일요일 5141.59 206.66 24.880 <2e-16 ***
wday토요일 5174.91 203.68 25.407 <2e-16 ***
wday화요일 -271.37 204.39 -1.328 0.185
event1 3258.93 155.97 20.895 <2e-16 ***
event2 12117.28 438.01 27.665 <2e-16 ***
event3 3578.12 179.43 19.942 <2e-16 ***
event4 10121.93 154.26 65.616 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1043 on 344 degrees of freedom
Multiple R-squared: 0.9736, Adjusted R-squared: 0.972

F-statistic: 604.6 on 21 and 344 DF, p-value: < 2.2e-16


이제 이 모델을 이용해 지표를 해석하는 방법은 다음과 같습니다.

3. 지표 판단 기준 만들기 - intercept의 재발견

  위 모델에서 가장 위에 빨간색으로 표시한 intercept는 종속 변수(즉, DAU)에 영향을 주는 요소들의 영향력을 모두 제거했을 때의 기본 수치를 의미합니다. 다시 말해 월이나 요일, 이벤트 등이 DAU에 주는 영향력이 있을 텐데 그런 것들을 모두 제거했을 때의 DAU가 얼마인지를 추정한 값입니다. 따라서 이것은 처음에 언급했던 지표의 높고 낮음을 판단하기 위한 기준값으로 사용할 수 있을 것입니다.
  참고로 모든 회귀 모델에서 intercept가 의미가 있거나 위와 같이 해석할 수 있는 것은 아닙니다. 사실 대부분의 경우 회귀 모델을 데이터 해석에 사용할 때 intercept는 무시합니다. 그러나 위 경우라면 intercept는 해석이 가능합니다. 왜냐하면 제가 사용한 회귀 모델의 독립 변수들은 모두 명백한 의미를 가진 더미 변수들(dummy variables)이고 이들의 영향력을 모두 제거한 상황이 현실적으로 가능한 상황이기 때문이죠. 다시 말해 intercept는 '어떤 이벤트도 하지 않은 상태를 가정했을 때 1월달에 있는 금요일 DAU의 평균치'를 의미합니다. 왜 '1월달에 있는 금요일'이냐면 위 모델을 만들 때 '월'과 '요일' 더미 변수는 각각 '1월'과 '금요일'을 default 값으로 사용했기 때문입니다(모델 결과를 자세히 보시면 1월과 금요일에 해당하는 더미 변수가 없습니다). 따라서 월과 요일의 default 값을 무엇으로 하느냐에 따라 intercept값은 달라지게 됩니다. 그러면 이제 어떤 값을 default 값으로 할 것인지가 고민이 되는데, 이건 아마도 해당 지표의 해석을 담당하는 사람 혹은 의사 결정권자가 정해야 할 문제 같습니다.

  암튼 원래의 지표 그래프에 위 intercept를 표시(파란색 수평선)한 그림은 아래와 같습니다. 이제 지표의 높고 낮음은 이 기준선을 이용해서 객관적으로 비교할 수 있습니다.

파란색 수평선이 기준선(intercept)입니다.

4. 이벤트 영향력 추정하기

  위 회귀 모델 결과에서 밑에 있는 event1~4 변수의 회귀 계수는 각 이벤트들이 DAU에 미치는 영향력을 의미합니다. 예를 들어 event1 이 있었던 날은 DAU 가 평균적으로 약 3,258 정도 상승한 것이죠. 이제 앞서 예로 들었던, 복귀 유저 프로모션과 동시에 진행되는 바람에 알 수 없었던 게임 업데이트가 지표에 미치는 영향도 추정이 가능합니다. 만약 복귀 유저 프로모션이 event4라고 하고 게임 업데이트가 있었던 날이 2016년 12월 28일 수요일이었고 복귀 유저 프로모션 외에 다른 이벤트는 없었다고 하면 우리는 해당 데이터를 이 회귀 모델에 넣어 DAU의 예측치를 얻을 수 있습니다(아래 코드 참고). 이제 우리는 이 값과 실제 DAU의 차이를 이번 업데이트가 DAU에 미친 영향력이라고 추정할 수 있습니다.

> real.dau <- 75345
> temp
date month wday event1 event2 event3 event4
363 2016-12-28 12 수요일 0 0 0 1
> pred <- predict(model, temp, type='response')
> real.dau - pred
6276.694 # 게임 업데이트가 DAU에 미친 영향력 추정치


  참고로 구글이 만든 causal impact라는 라이브러리(https://google.github.io/CausalImpact/CausalImpact.html)가 이와 비슷한 컨셉을 갖고 있습니다. 물론 여기 제가 사용한 방법보다 훨씬 더 세련되고 정교한 기법을 사용했지만요. 예를 들어 아래 그래프는 causal impact 가 보여주는 그래프인데 위에서 부터 각각 실측치(실선)와 예측치(점선)을 비교한 그래프, 이 두 값의 차이를 표시한 그래프, 그리고 이 값의 누적치를 표시한 그래프입니다. 이 누적치가 바로 새로운 이벤트의 영향력을 의미합니다.

5. 지표 이상치 탐지하기

  이제 마지막으로 바로 위에서 사용한 방법을 조금만 변형하면, 우리가 모르는 어떤 이상 현상을 찾는데에도 활용할 수 있습니다. 별다른 이벤트나 업데이트 같은 것이 없었는데도 회귀 모델의 예측치와 실제 DAU가 갑자기 크게 차이가 났다면 이것은 뭔가 이상 현상이 발생한 것이라고 의심할 수 있는 것이죠. 이와 관련해서는 예전에 제가 쓴 '회귀 분석을 이용한 시계열 데이터 이상 탐지(http://agbird.egloos.com/6065006)' 라는 글에 좀 더 자세히 나와 있으니 참고하시면 되겠습니다.

6. One more thing - 회귀 모델의 변화 추적하기

  여기서 끝이 아닙니다. 우리는 지표를 주기적으로 계속 모니터링하듯이 회귀 모델 역시 주기적으로 생성할 수 있습니다. 위 경우를 예로 들면, 한달에 한번씩 과거 1년치 데이터에 대한 회귀 모델을 정기적으로 생성하여 그 값들을 비교해 볼 수 있습니다. 이렇게 하면 우리는 DAU에 영향을 주는 변수들의 영향력 자체가 어떻게 변하는지를 추적할 수 있습니다. 가령 원래는 주말(토/일요일)에 평균적으로 DAU가 5000명 정도씩 늘어나고 있었는데 시간이 지남에 따라 영향력이 4000명으로 줄어든다면 이것은 중요한 정보가 될 수 있습니다. 혹은 event1 이 예전에 비해 영향력이 늘어나고 event2의 영향력은 떨어진다면 우리는 앞으로 event2보다 event1에 더 집중하는 것이 좋겠다는 의사 결정을 할 수도 있습니다.
  더 나아가 기준선이 되는 intercept의 변화를 추적하는 것도 가능합니다. 그리고 이 intercept의 변화는 매우 중요할 수 있습니다. 이건 외부 영향력을 배제한 기본 수치를 의미하기 때문에 일종의 우리 서비스가 갖고 있는 잠재력이라고 생각할 수 있습니다. 따라서 장기적으로 볼 때 이 수치의 변화는 단기적인 DAU의 변화보다 더 중요한 정보일 수 있습니다.

7. 마치며

  '측정할 수 없는 것은 관리할 수 없다.'라는 말이 있습니다(흔히 피터 드러커가 한 말이라고 알려져 있는데 그건 아니라고 합니다). 서비스를 잘 운영하고 개선하기 위해 뭔가를 측정하고 집계해서 지표를 만드는 것은 중요합니다. 그런데 이렇게 다양한 지표들을 만들고 매일 바라보고 있지만 정작 이걸로 어떻게 하면 좋을지는 여전히 난감한 경우가 많습니다.
  저희 회사에서도 수백 개가 넘는 지표를 매일 만들어서 다양한 그래프나 보고서로 제공하고 있지만, 지금 상황이 좋은지, 좋다면 대체 얼마나 좋은지를 해석하기가 쉽지 않습니다. 그 이유는 서두에서도 언급했듯이 단순한 수치만으로는 가치 평가를 하기 어렵기 때문입니다. 따라서 지표들이 좀 더 가치를 발휘하려면 현재의 지표가 좋은 상태인지 나쁜 상태인지를 알 수 있는 신뢰도 높은 비교 정보를 제시하는 것이 필요하다고 생각합니다. 비록 여기서 제안한 방법이 정답은 아니겠지만 적어도 정답을 찾기 위한 과정 중 하나라고 생각하며 혹시 더 좋은 의견이나 정보가 있다면 댓글로 알려 주시기 바랍니다.

지능의 탄생 내가 읽은 책들

인공 지능은 말 그대로 인공적으로 만들어진 지능을 의미한다. 따라서 인공 지능을 잘 구현하려면 먼저 지능에 대해 잘 이해하는 것이 필요할 것이다. 그런 의미에서 최근에 읽은 '지능의 탄생'이라는 책은 지능을 이해하는데 있어 지금까지 읽은 책 중 가장 좋은 책이었다.

지능은 한 마디로 정의하자면 '의사 결정 능력'이다. 의사 결정 능력은 이를 테면 '달면 삼키고 쓰면 뱉는다'와 같은 일련의 규칙으로 정의할 수 있다. 생물에서 이런 류의 가장 기본적인 지능은 '반사(reflex)'이다. 이런 반사는 진화 매커니즘을 통해 DNA에 프로그래밍된다.

그런데 생물이 복잡한 자연 환경 속에서 살아가기에는 반사만으로는 부족하다. 왜냐하면 반사 규칙을 추가하는 것은 최소 한 세대 이상의 시간이 걸리는 반면 지금 당장 눈앞에 나타난 천적에게 어떻게 반응해야 할지는 빠른 판단이 필요하기 때문이다. 따라서 생물은 어떤 상황에서 스스로 행동을 조정해 나가는 학습 과정이 필요하다.
책에서는 '무인 화성 탐사 로봇'을 예로 들어 설명한다. 즉, 사람은 실제 화성에 가보지 못했기 때문에 어떤 상황이 발생할 수 있을지 모든 경우의 수를 프로그래밍할 수 없다. 따라서 '수행한 결과가 탐사에 도움이 되면 그 행동을 반복하고 그렇지 않으면 그 행동을 하지 말아라'와 같은 좀 더 고차원적인 규칙이 프로그래밍되며 이를 통해 로봇은 배터리 충전을 위해 그늘을 피하고, 용이한 탐사를 위해 바위산 대신 평지로 이동하는 등의 행위를 학습하게 된다.
인간이 생존에 유리한(영양분이 가득한 치즈 케이크를 먹는) 행동을 하면 행복감을 느끼고 생존에 불리한(상한 음식의 냄새를 맡는) 행동을 하면 불쾌감을 느끼는 것은 일종의 강화 학습을 위한 보상 매커니즘이다. 그리고 이런 보상은 '만족'과 '실망'을 통해 그 가중치가 조절된다.
더 나아가 인간은 좀 더 고차원적인 보상 매커니즘도 갖고 있는데 그 대표적인 것이 '후회'이다. 얼핏 생각해 보면 후회는 무척 감정 소모적인 행위이지만, 이것을 통해 우리는 순간적으로 유리하다고 생각한 치즈 케이크를 먹는 행위에 대해 좀 더 장기적인 관점에서 유/불리는 따지게 되고 이를 통해 어제 치즈 케이크를 너무 많이 먹은 것에 대해 후회함으로써 일종의 지역 최적화를 피하게 된다.

우리는 간접 경험을 통해 학습할 수도 있다. 직접 경험한 행동에 대한 보상으로만 학습을 할 수 있다면 아마 우리는 절벽에서 뛰어내리거나 양잿물을 삼키는 행위에서 어떤 학습도 수행할 수 없을 것이다. 따라서 집단 생활은 매우 효과적인 학습 환경이 된다. 이런 집단 환경에서 인간은 '모방'을 통해 학습을 하게 되며 '시기', '부러움' 등의 보상 매커니즘을 갖게 된다.

한편, 이런 집단 생활을 하게 되면 서로의 이해관계가 상충될 수 있기 때문에 보상에 의한 최적화가 좀 더 복잡해진다. 이런 다자 간의 이해 관계를 고려한 최적화 전략을 만들 수 있음을 수학적으로 증명한 것이 존 내쉬의 '내쉬 균형'이다. 그런데 모든 상황에서 '내쉬 균형'이 최적의 전략인 것은 아니다. 그 대표적인 것이 '죄수의 딜레마'이다. '죄수의 딜레마' 문제에서는 개인별 최적의 선택이 실제로는 최악의 선택이 된다.
흥미로운 점은 실제 사람들을 대상으로 '죄수의 딜레마'와 유사한 실험을 해보면 많은 경우 사람들은 (내쉬 균형이 아닌) 최적화된 선택을 한다는 점이다. 이렇게 인간의 지능이 죄수의 딜레마에 빠지지 않을 수 있는 장치 중 대표적인 것이 '복수심'이다. 즉, 개인의 이기심으로 인해 사회적으로 최악의 선택을 하게 되는 경우 이를 다른 사람이 복수하는 매커니즘인데 이것이 효과적인 이유는 (매번 비용을 지불해야 하는) 보상과 달리 잘못된 행위가 발생했을 때만 처벌하면 되기 때문이다.

인간은 자기 스스로를 인지하고 통찰하는 '자기 인지' 능력도 갖고 있다. 이것은 다른 이의 사고 과정을 예측하는데 있어 매우 좋은 능력이지만 동시에 '거짓말쟁이의 역설'과 같은 논리적 모순을 발생시키기도 한다.
마지막으로 '좋은 여행지를 추천받기 위해 좋은 여행사를 선택'하는 것과 같은 '메타 선택' 능력도 있다. 이것은 아마도 범용적인 인공지능을 구현하는데 있어 반드시 고려해야할 요소가 아닌가 싶다.

이렇듯 이 책에는 가장 기본적인 지능에서부터 인간만이 가지고 있(는 것으로 알려져 있)는 가장 고차원적인 지능까지 대부분의 영역을 폭넓으면서도 체계적으로 설명하고 있다. 내용 자체도 흥미롭기 때문에 지적인 호기심을 충족하기에도 좋을 뿐더러 기계학습 분야를 공부하거나 새로운 기법을 연구하는데 있어 많은 영감을 줄 수도 있지 않을까 싶다.

데이터 분석을 통한 게임 고객 모델링 #4 데이터분석

이 글은 저희 회사 블로그(http://blog.ncsoft.com/?p=28900)에서도 확인하실 수 있습니다.

***************************************

  이번 편에서는 이전에 소개한 방법들을 이용해 게임 고객을 유형별로 세분화한 자료를 어떤 식으로 활용할 수 있는지 활용 사례와 함께 그 동안 미처 다루지 못했던세부적인 내용 몇 가지를 FAQ 형식으로 소개해 드리겠습니다.

  ‘심슨의 역설 (Simpson’s paradox)’ 이라는 말을 들어보셨나요? 에드워드 심슨이라는 통계학자가 처음 공식적으로 언급한 통계 현상으로, 어떤 집단의 전체 통계량(예를 들어 평균)과 집단을 여러 개 그룹으로 나눠서 구한 통계량이 서로 반대되는 특성을 갖는 현상을 일컫는 말입니다.
  이와 관련해 널리 알려진 사례로 U.C. 버클리 대학교의 1973년 남녀 신입생 합격률 자료가 있습니다. 당시 버클리 대학교의 남녀 입학률은 아래 표와 같습니다.

  위 자료에 의하면 남학생에 비해 여학생의 합격률이 상대적으로 낮게 나오고 있어 버클리 대학교는 남녀 차별을 하고 있다는 의심을 받게 되었죠. 그런데 학과별로 세분화해서 자료를 집계했더니 아래와 같이 나타났습니다(전체자료 중 인원이 가장 많은 상위 6개 학과만 표시한 자료입니다).

  보시다시피 이렇게 학과별로 세분화된 자료를 보면 오히려 여학생의 합격률이 남학생에 비해 전반적으로 높게 나옵니다. 이런 현상이 발생하는 이유는 학과별 입학 정원이 서로 다르기 때문입니다. 즉, 여학생들은 남학생들에 비해 입학 정원이 적은 학과에 지원자가 몰리는 바람에 전체 합격률이 낮아지게 된 것이죠.

  이와 같이 어떤 자료를 집계할 때 전체 대상만을 기준으로 해서 통계를 구할 경우 자칫 실제와 다른 엉뚱한 판단을 할 수 있습니다. 따라서 적절히 자료를 분류하여 집계한 결과를 같이 확인해야 합니다.
  게임 고객 지표 역시 마찬가지입니다. 게임 서비스를 운영할 때는 다양한 지표를 사용하는데, 이 중에서 대표적인 것 몇 가지만 소개하면 아래와 같습니다.

  • 활동 유저(Active User, AU): 특정 기간 동안 게임에 접속한 총 유저수를 의미합니다. 보통 일단위, 주단위, 월단위로 집계를 하는데 게임의 인기도를 파악하는데 중요하게 사용하는 지표입니다.
  • 동시 접속자(Concurrent Connected User, CCU): 특정 시점에 게임에 접속해 있는 유저수를 의미합니다. 이 지표 역시 AU와 비슷하게 게임의 인기도와 밀접하게 관련된 지표입니다. 
  • 유저당 결제금액(Average Revenue Per User, ARPU): 일정 기간 동안 집계된 총 결제 금액을 동일 기간의 AU로 나눈 지표입니다. 말 그대로 한 명의 유저가 얼마의 금액을 사용하는지를 나타내는 수치입니다. 
  • 결제 유저당 결제금액 (Average Revenue Per Paid User, ARPPU): 총 결제 금액을 결제를 한번이라도 한 유저수로 나눈 값입니다. 

  ARPU와 ARPPU를 분리해서 측정하는 이유는 게임의 매출 특성을 좀 더 정확히 파악하기 위함입니다. 가령 ARPU는 낮은데 ARPPU가 매우 높게 나온다면 이 게임은 극소수의 충성도 높은 고객에 의해 대부분의 매출이 발생된다는 뜻입니다. 반대로 ARPU와 ARPPU의 차이가 크지 않다면 전반적으로 많은 수의 유저들이 고르게 매출을 발생시킨다는 의미가 되겠죠. 보통 F2P 기반의모바일 게임이나 캐주얼 게임은 전자의 특성이 강하며 정액제 기반의 PC MMORPG는 후자의 특성이 강합니다.

  만약 이런 지표들을 단지 전체 게임 고객에 대해서만 집계할 경우 앞서 소개한 버클리 대학교 사례처럼 실제 현상을 제대로 반영하지 못할 수 있습니다. 따라서 고객을 유형별로 적절히 분류한 후 각 유형별 지표를 따로 집계하여 전체 지표와 함께 살펴봐야 합니다.
  예를 들어 예전에 모 게임에서 큰 규모의 업데이트를 한 후 게임 고객 동향을 분석한 적이 있습니다. 이 게임은 전체 게임 고객을 약 십 여가지 유형으로 분류하고 있는데, 크게 보면 게임 활동이 왕성하고 충성도가 높은 ‘진성’ 유형, 게임 활동이 그리 활발하지 않은 ‘라이트’ 유형, 자동 사냥 유저로 의심되는 ‘봇’유형 등이 있죠. 혹시 오해하실까 싶어 첨언하자면, 고객지표 관리를 위해 분류하는 ‘봇’ 유형은 개략적인 추정이기 때문에 설령 ‘봇’ 유형으로 분류되었다 하더라도 바로 제재 등의 직접적인 조치를 하지는 못합니다. 이렇게 소위 ‘악성’ 유저로 분류된 이들 중 보다 직접적인 증거가 수집되어 확실히 ‘봇’으로 판정될 경우에만 제재 등의 조치를 취하게 됩니다.

  어쨌든 이 게임의 업데이트 전/후 DAU와 ARPU지표를 확인해 보니 아래와 같이 나왔습니다.

  이 수치를 보면 업데이트로 인해 일별 접속자수(DAU)는 크게 늘어난 반면 상대적으로 유저당 결제금액(ARPU)은 큰 하락세를 보이기 때문에 ARPU를 높이기 위한 상품 프로모션을 기획해야겠다고 생각할 수 있습니다. 그런데 이것을 유형별로 세분화한 지표로 확인해 보면 아래와 같습니다.

  이 자료를 보면 실제 전체 지표 상에서 크게 늘어난 유저는 ‘라이트’나 ‘봇’ 유형이며 ‘진성’ 유형의 유저 수 변화는 상대적으로 그리 크지 않다는 것을 알 수 있습니다. 또한 매출에 가장 큰 비중을 차지하는 ‘진성’ 고객의 ARPU 는 전체 지표와 달리 상승 추세에 있습니다. 전체 지표 상에서 ARPU가 낮게 집계되는 이유는 결재를 거의 하지 않는 기타 유저의 수가 큰 폭으로 증가했기 때문이죠.
  따라서 이렇게 유형별 지표를 보면, ARPU를 높이기 위한 노력보다는 ‘봇’ 유형의 규모를 줄이기 위한 조치를 취하는 한편, ‘라이트’ 유형을 ‘진성’ 유형으로 전환시켜 진성 고객의 수를 늘리기 위한 방안을 모색하는 것이 더 적절해 보입니다.

  더 나아가 고객 세분화는 좀 더 고도화된 예측 작업을 할 때도 바탕이 되는 자료로 활용할 수 있습니다. 예를 들어 이탈 분석의 경우를 생각해 보죠. 이탈 분석은 서비스를 이탈한 고객에 대해서 이탈 원인을 찾거나 혹은 현재 활동하는 고객 중 머지 않아 이탈할 것으로 의심되는 고객을 미리 예측하기 위한 분석을 말합니다. 이런 분석을 통해 이탈 원인에 해당하는 컨텐츠를 개선하거나 혹은 이탈 징후가 보이는 고객을 미리 예측하여 이탈을 방지하기 위한 조치를 취합니다.
  그런데 이런 이탈 분석을 할 때도 고객을 유형별로 나눠서 분석하는 것이 필요합니다. 오랜 기간 게임을 열심히 해왔던 고객과 짧은 기간만 경험하다 이탈하는 고객의 이탈 원인은 매우 다를 것이기 때문입니다.
  심지어 게임에 부정적인 영향을 주는 ‘봇’의 경우 이탈을 방지하는 것이 오히려 게임 서비스에 안 좋기 때문에 이탈 예측 모델 적용 대상에서 제외하는 것이 좋습니다. 따라서 고객 유형을 보고 이탈 방지를 통해 게임 서비스에 긍정적인 효과를 얻을 수 있는 고객을 선별한 후 이들을 대상으로 한 이탈 예측 모델을 만드는 것이 바람직합니다.
  예전에 작업했던 모 게임의 경우 이탈 예측 모델을 적용할 때 우선 전체 이용자를 대상으로 장기간에 걸쳐 게임 활동 유형의 변화를 추적한 후 비슷한 변화를 보이는 고객별로 시퀀스 유형을 분류하였습니다. 아래 그림은 이런 과정을 통해 나온 유형 중 일부입니다.
  이 후 논의를 거쳐 오랜 기간 게임을 열심히 즐기다가 이탈하는 게임 고객들에 대한 분석을 먼저 수행하자고 결정하고 위 유형 중 ‘장기 진성 유형’ 에 해당하는 고객을 선별하여 이탈 예측 분석을 수행했습니다.
  이렇게 특정 유형의 고객을 선별하여 이탈 예측 모델을 만들 경우 해당 유형이 갖고 있는 기대 가치를 좀 더 명확하게 추정할 수 있기 때문에 이탈 방지를 위한 마케팅 비용을 산정하기가 좀 더 수월해지는 장점도 있습니다.

  지금까지 군집화 기법을 이용한 게임 고객 모델링에 대해서 소개해 드렸는데 도움이 되셨는지 모르겠네요. 고객 세분화는 데이터 모델링의 가장 기본적인 응용 사례입니다. 적절한 고객 세분화를 통해 다양한 고객의 특성을 이해하고 보다 정확한 고객 지표를 만들 수 있습니다. 또한 유형별 특성에 맞는 이탈 방지나 맞춤형 프로모션과 같은 마케팅 활동을 할 때도 중요하게 활용됩니다.
  엔씨소프트에서는 게임 고객을 보다 잘 이해하고 도움이 되는 서비스를 만들기 위해 데이터에 기반한 게임 고객 세분화 모델을 만들어 활용하고 있습니다. 비록 아직까지 부족한 점은 많지만 보다 나은 서비스를 위해 다양한 시도를 하고 있으니 많은 관심 부탁 드립니다.

FAQ

  그 동안 지면관계 상 혹은 글의 흐름 상 생략했던 기술적인 내용 중에서 연재 도중에 받았던 몇 가지 질문을 FAQ 형식으로 정리해 보았습니다.

Q1. 여러 가지 군집 유형을 나누는 방법에 대해 소개해 주셨는데 이런 군집 유형이 변하기도 하나요? 만약 변한다면 시간이 지남에 따라 다시 원래 유형으로 돌아가나요 아니면 바뀐 모습을 유지하게 되나요?

A1. 군집을 나눌 때는 특정 시점에 수집된 게임 고객 데이터를 이용하기 때문에 수집 시점의 고객 특징만을 반영할 수 밖에 없습니다. 시간이 지남에 따라 고객의 유형은 달라지기 때문에 유형 분류는 정기적으로 해야 합니다. 그리고 변화 패턴은 고객마다 다르기 때문에 항상 어떻게 변한다고 단정지을 수 없습니다.

Q2. 여기서 소개한 클러스터링 방법 말고 다른 방법으로는 어떤 것들이 있나요? 그리고 그 중에서 가장 성능이 뛰어난 방법은 뭔가요?

A2. 제가 여기서 소개한 방법은 ‘k 평균 군집화’와 ‘계층 군집화’ 인데요, 이것말고도 굉장히 다양한 알고리즘이 있습니다. 제가 소개해 드린 기법은 그 중에서 가장 보편적으로 사용되는 방법일 뿐입니다. 이런 기법들은 모두 저마다의 장단점을 갖고 있기 때문에 어떤 한가지 가장 뛰어난 방법을 찾기 보다는 각 기법의 특성을 잘 파악하여 클러스터링 대상이 되는 데이터에 적합한 방법을 사용하는 것이 중요합니다.
여기까지가 원론적인 답변이고 실전에서는 일단 아는 방법 다 동원해서 분류해 보고 그 중에 가장 괜찮아 보이는 결과를 취합니다.

Q3. 개인 행동 패턴을 통한 군집화 모델과 소셜 네트워크 분석을 통한 군집화 모델 중 어떤 것이 더 유저를 예측하는데 뛰어난가요?

A3. 어떤 것이 더 낫다기 보다 이 둘을 적절히 혼합하여 사용하는 것이 좋습니다. 2편에서 예로 든 다이아몬드와 석탄의 사례를 다시 생각해 보면, 어떤 물체가 다이아몬드가 되려면 입자들의 얽힘 구조뿐만 아니라 그 입자 자체의 특성도 중요합니다. 이 둘 중에 하나라도 다르면 그 물체는 다이아몬드가 아닌 것이죠. 따라서 어떤 고객의 특성을 정확히 파악하려면 고객의 행동 유형과 더불어 고객이 속한 커뮤니티의 네트워크 유형까지 같이 파악하여 이 둘을 통합한 유형을 만드는 것이 좋습니다.
  1편 맨 앞에서 소개했던 MBTI 의 경우를 생각해 보면 MBTI는 각기 독립된 네 가지 기준으로 사람의 성향을 나눈 후 이들을 합쳐 최종 유형을 정합니다. 이와 비슷하게 고객 유형을 나눌 때도 행동 기반의 유형과 커뮤니티 기반의 유형을 각기 분류한 후 이들을 합쳐 최종 유형을 만들면 보다 정확한 고객 특성 파악이 가능하다고 생각합니다.

Q4. 3편에서 예시로 나온 네트워크 시각화 그림들이 흥미로운데 이런 자료는 어떻게 만들 수 있나요?

A4. 블로그에서 소개한 네트워크 그림들은 모두 ‘게피(Gephi, https://gephi.org/)’ 라는 툴을 사용해서 그렸습니다. 이 툴은 누구나 무료로 사용할 수 있는데 다양한 그래프를 그릴 수 있을 뿐만 아니라 기본적인 네트워크 분석기능도 제공해 줍니다. 특히 GUI 기반이기 때문에 기본적인 사용법만 알면 초보자도 쉽게 사용할 수 있는 꽤 괜찮은 툴입니다.

데이터 분석을 이용한 게임 고객 모델링 #3 데이터분석

이 글은 회사 블로그에 기고한 초본입니다. 담당 부서의 마사지를 받은 글은 http://blog.ncsoft.com/?p=26737 에서 확인하실 수 있습니다.

*****************************************

    2편에서 예고했듯이 이번 편에서는 ‘사회 연결망 분석(Social network analysis)’을 통해 고객의 특성을 파악하는 방법에 대해 소개해 드리겠습니다.
    사회 연결망 분석을 위해선 먼저 게임 고객 간의 관계를 ‘연결망(보통 네트워크라는 말을 더 많이 사용)’이라고 부르는 구조로 만들어야 합니다. 연결망(혹은 네트워크)은 말 그대로 여러 개의 개체(보통 ‘노드’라고 함)들을 연결한 것을 말하는데요, 예를 들어 인터넷 네트워크는 여러 기기들이 인터넷을 통해 연결된 구조를 의미합니다. 마찬가지로 사회 연결망(혹은 소셜 네트워크)은 사람들이 사회적 관계를 통해 연결된 구조이죠.
    온라인 게임에서 게임 고객들은 다양한 사회적 관계를 갖게 됩니다. 친구가 되거나 같은 혈맹에 소속되는 것처럼 현실과 유사한 사회적 관계를 맺기도 하고, 같이 파티를 맺고 인던을 돌거나 혹은 서로 아이템을 주고 받는 것과 같은 다양한 상호 작용을 하기도 합니다. 그래서 이런 관계나 게임 활동을 이용하면 게임 고객 네트워크를만들 수 있습니다.
    보통 네트워크 분석을 할 때는 네트워크 구조를 우리가 수학 시간에 배우는 ‘행렬’로 표현합니다. 가령 네 명의 사람이 아래와 같이 연결되어 있다면 이들을 행과 열에 놓고 두 사람 사이가 연결되어 있으면 1, 아니면 0으로 표시하는 것이죠.

네트워크 구조를 행렬로 표현한 예

    얼핏 생각하기엔 그냥 그림으로 그리면 될 것을 왜 이렇게 머리 아프게 행렬로 표시하나 싶지만 여러 가지 복잡한 계산을 하거나 혹은 분석에 필요한 계산을 컴퓨터가 자동으로 처리하도록 프로그래밍할 때는 이렇게 행렬을 이용하는 것이 편하답니다.
    하지만 역시 저같은 일반인들에게는 숫자보다는 그림이 더 보기 좋고 직관적이기 때문에 보통 네트워크는 그림으로 많이 표현됩니다. 예를 들어 아래 그림은 인터넷 네트워크를 시각화한 것입니다.

인터넷 네트워크 (이미지 출처: https://en.wikipedia.org/wiki/Internet_backbone)

    뭔지 모르지만 아무튼 멋지죠? 그런데 이와 비슷하게 온라인 게임에서도 게임 고객간의 네트워크를 시각화할 수 있습니다. 아래 그림은 저희 회사 모 게임에서 고객 간에 서로 아이템을 주고 받는 관계를 네트워크로 시각화한 것입니다. 비록 그리는 방식에 약간의 차이는 있지만 자세히 보면 이 둘은 구조 상 매우 유사하답니다.

게임 고객 네트워크 시각화 예

    한편 보통 네트워크는 여러 개의 작은 집단으로 나눌 수 있습니다. 가령 위 그림에서는 각기 다른 색깔로 구분된 수백 개의 소집단으로 구분될 수 있죠. 이런 소집단들은 같은 집단에 속한 노드 간의 연결선이 외부 노드와의 연결선에 비해 상대적으로 밀도가 높게 구성되는데 이런 여러 개의 소집단들이 모여서 전체 네트워크를 이루게 되죠. 이런 소규모 집단들을 ‘커뮤니티’라고 부릅니다.

이 네트워크의 경우 세 개의 커뮤니티로 나눌수 있죠

    각각의 ‘커뮤니티’들은 저마다 다양한 네트워크 구조를 갖고 있습니다. 예를 들어 우리 회사 게임 고객 네트워크를 보면 아래와 같은 다양한 커뮤니티 구조를 발견할 수 있습니다.

다양한 구조의 게임 고객 커뮤니티

    따라서 유저들을 유사한 행동 패턴끼리 군집화하듯이 커뮤니티 역시 비슷한 네트워크 구조를 갖는 커뮤니티끼리 군집화할 수 있습니다.
    이 때 군집화를 위해 커뮤니티 구조 간의 유사도를 측정하려면 우선 각 커뮤니티 구조를 나타내는 적절한 값을 구해야 합니다. 이를 위해 사용하는 여러 가지 네트워크 지표가 있는데 일일이 다 설명하기에는 지면이 부족하니 대표적인 것 몇 가지만 소개하면 다음과 같습니다.

Degree

    Degree는 네트워크 상의 어떤 노드가 몇 개의 노드와 연결되어 있는지를 나타내는 값입니다. 즉, 노드에 연결된 선의 개수죠. 이 때 개별 노드의 degree를 구하고 난 후 커뮤니티 별로 노드들의 degree 평균이나 표준 편차를 구하면 각 커뮤니티 구조의 차이를 아는데 도움이 됩니다.
    또한 서로 비슷한 degree를 갖는 노드끼리 연결되었느냐 차이가 큰 노드끼리 연결되었느냐를 측정하는 지표로 degree assortativity(동질성)라는 것이 있습니다. 아래 그림에서 왼쪽 커뮤니티는 비슷한 degree를 갖는 개체끼리만 연결되었기 때문에 이 수치가 높은 반면, 오른쪽 커뮤니티는 반대로 매우 낮은 값을 갖습니다. 그래서 이 지표 역시 네트워크 구조를 파악하는데 도움이 되는 정보입니다.

Degree assortativity가 큰 커뮤니티(왼쪽)와 작은 커뮤니티(오른쪽)의 예

Radius

    우리말로 하면 반경인데요, 쉽게 말해 커뮤니티 내에서 가장 멀리 떨어진 개체 사이의 거리를 의미합니다. 이것 역시 네트워크 구조를 파악하는데 많이 사용하는 지표입니다.

Radius가 큰 커뮤니티(왼쪽)와 작은 커뮤니티(오른쪽)의 예

    각 커뮤니티마다 이런 다양한 지표를 구한 후 커뮤니티에 대한 군집화를 수행하면 마치 탄소 분자간의 얽힘 구조를 보고 다이아몬드와 석탄을 구분하듯이 전체 네트워크에서 비슷한 구조를 갖는 커뮤니티끼리 분류할 수 있습니다. 아래 그림은 다양한 네트워크 지표를 기반으로 군집화 알고리즘을 사용해 게임 고객 네트워크를 다섯 가지 유형의 커뮤니티로 분류한 것입니다.

네트워크 구조를 기준으로 커뮤니티들을 다섯 가지 유형으로 군집화한 예

    이렇게 분류를 하면 설령 행동 패턴만 볼 때는 동일한 유형의 게임 고객처럼 보이더라도 어떤 커뮤니티 유형에 속해 있는지에 따라 다르게 관리할 수도 있고 혹은 고객 관리 자체를 커뮤니티 단위로 할 수도 있겠죠.
    더 나아가 네트워크 구조를 잘 파악하면 개체의 특성만 보고는 알 수 없는 독특한 패턴을 발견할 수 있습니다. 가령 범죄자들은 자신의 정체를 숨기기 위해 일반인 코스프레를 하기 때문에 개체의 특성만 분석해서는 정체를 파악하기 쉽지 않은 반면, 네트워크 구조는 여러 노드를 제어해야 하기 때문에 일반인들의 자연스런 관계 구조를 흉내내기가 상대적으로 어렵죠. 따라서 보험 사기나 주식 작전 세력, 악성코드에 감염된 좀비 PC 등을 탐지할 때 이런 네트워크 분석 기법을 많이 활용하고 있습니다.

    저희 회사도 악성 유저를 탐지할 때 이런 기법을 활용하곤 합니다. 예를 들어 아래 커뮤니티의 경우 각 캐릭터들의 게임 활동만 보면 일반 고객과 큰 차이점이 없지만 캐릭터 간의 관계 구조를 시각화하면 이렇게 매우 규칙적이고 인위적인 구조가 나타납니다. 그래서 이런 정보가 큰 도움이 되죠.

이것은 사람이 아니므니다...

    비록 여기서는 고객 커뮤니티를 군집화하기 위해 네트워크 구조를 파악하는 방법만을 살펴 봤지만 실제로는 이 외에도 매우 다양한 네트워크 분석 기법이 있으며 여러 분야에서 폭넓게 활용되고 있답니다.

    지금까지 세 편에 걸쳐 게임 고객을 모델링하기 위해 사용하는 데이터 분석 기법들을 소개해 드렸는데 잘 따라오셨나요? 그럼 마지막으로 다음 편에서는 앞서 설명한 세 가지 기법을 실전에서 어떻게 적용할 수 있는지 소개하면서 그 동안 정신 없이 달려오느라 미처 다루지 못했던 내용들을 FAQ 형식으로 정리하는 시간을 갖겠습니다.

1 2 3 4 5 6 7 8 9 10 다음