어떤 속성의 고객들이 떠나고 있는가?

Ryu

2020-04-09



Overview

지난 달에 비해 이달의 이용 유저수가 크게 감소했다. 광고나 이벤트 등은 크게 차이나지 않았다. 그래서 감소의 원인을 조사하여 대책을 마련해보고자 한다.

  • 현실의 모습

지난달과 비교해서 유저수가 감소하였음

  • 이상적인 모습

지난달과 같은 수준으로 유저수 회복

issue-finding

문제 발견 단계에서는 항상 크고 넓은 시점으로 모든 가능성을 염두에 두는 것이 중요하다. 아래와 같은 가설을 세운다고 해보자.

  1. 광거에 문제가 있어서 신규 유저수보다 탈퇴 유저수가 더 많았다.
  2. 매월 테마를 바꿔서 개최하던 게임 이벤트가 식상해져서 그만둔 유저가 많았다.
  3. 성별 혹은 연령 등 특정 유저층에서 탈퇴한 유저가 많았다.

가설을 세운 후에는 가급적 단시간에 검증하는 것이 좋다. 관련 부서를 통해 다음과 같은 사실을 알아낼 수 있었다고 하자.

  1. 광고는 지난달과 비교해서 거의 같은 수준이었으며 신규 유저수도 거의 같은 수준이었다.
  2. 이벤트 내용도 지난달과 거의 바뀌지 않았다.

그렇다면 ‘성별 혹은 연령 등 특정 유저층에서 탈퇴한 유저가 많았다’ 라는 가설만이 조사할 가치가 있어보인다. 이것을 조금 더 자세히 알아볼 필요가 있다는 의미이다. 먼저 성별, 연령 등을 기준으로 분류하여 줄어든 유저가 있는지 없는지 확인할 수 있다. 그러면 각 유저층의 유저수를 지난달과 비교해서 줄어든 유저층이 있는지 데이터로 확인하고, 만일 실제로 있다면 유저수를 어떻게 회복할지 생각해봐야 한다.

Data loading

분석해야 할 테마가 정해졌다면 분석에 필요한 데이터를 검토한다. 이번에 실시할 세그먼트 분석에는 구체적으로 어떠한 데이터가 필요한지 다음 가설을 통해 다시 한 번 리마인딩 해보자.

  • 문제
  1. 지난달과 비교해서 유저수가 줄어들었다. (사실)
  2. 어떤 특정한 유저층에 문제가 생겼을 것이다. (가설)
  • 해결책

숫자가 줄어든 유저층에 적합한 대책을 세워서 지난달과 같은 수준으로 유저수를 회복한다.

이 가설을 가지고 분석 스토리를 정리해보자.

  1. 유저수가 지난달보다 줄어들었다. (사실)
  2. 어딘가 숫자가 줄어든 세그먼트가 있을 것이다 (가설)
  3. 그 세그먼트에 적합한 대책을 세워서 유저수를 지난달과 같은 수준으로 회복한다. (해결책)

EDA(Exploratory data analysis)

위에서 불러온 파일들을 확인해보자

여기서 log_date 를 날짜형으로 바꾸고 user_id 를 문자형으로 바꿔주도록 하자.

  1. dau
  • 자료구조 : 데이터 프레임
  • log_date : 문자형 -> 날짜형
  • app_name : 문자형
  • user_id : 정수형 -> 문자형

여기서 log_date는 로그인한 날짜를, app_name은 게임의 이름을, user_id 는 유저 식별 값을 의미한다.

## 'data.frame':    170360 obs. of  3 variables:
##  $ log_date: chr  "2013-08-01" "2013-08-01" "2013-08-01" "2013-08-01" ...
##  $ app_name: chr  "game-01" "game-01" "game-01" "game-01" ...
##  $ user_id : int  33754 28598 30306 117 6605 346 28601 123 33446 31685 ...
##    log_date           app_name            user_id     
##  Length:170360      Length:170360      Min.   :    1  
##  Class :character   Class :character   1st Qu.:14349  
##  Mode  :character   Mode  :character   Median :28976  
##                                        Mean   :26162  
##                                        3rd Qu.:37611  
##                                        Max.   :49525
  1. user_info

성별, 연령대, 기종과 같은 컬럼은 팩터형으로 변경해주고 나머지는 위와 동일하게 처리해주도록 하자.

  • 데이터 구조 : 데이터프레임
  • install_date : 문자형 -> 날짜형
  • app_name : 문자형
  • user_id : 정수형 -> 문자형
  • gender : 문자형 -> 팩터형
  • generation : 정수형-> 팩터형
  • device_type : 문자형 -> 팩터형

여기서 install_date는 다운로드한 날짜를, app_name은 게임이름을, user_id 는 유저 식별 값을, gender는 성별을, generation은 연령대를, device_type 은 사용기기의 종류를 의미한다.

## 'data.frame':    49526 obs. of  6 variables:
##  $ install_date: chr  "2013-04-15" "2013-04-15" "2013-04-15" "2013-04-15" ...
##  $ app_name    : chr  "game-01" "game-01" "game-01" "game-01" ...
##  $ user_id     : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ gender      : chr  "M" "M" "F" "M" ...
##  $ generation  : int  40 10 40 10 40 40 30 20 50 20 ...
##  $ device_type : chr  "iOS" "Android" "iOS" "Android" ...
##  install_date         app_name            user_id         gender         
##  Length:49526       Length:49526       Min.   :    1   Length:49526      
##  Class :character   Class :character   1st Qu.:12382   Class :character  
##  Mode  :character   Mode  :character   Median :24764   Mode  :character  
##                                        Mean   :24764                     
##                                        3rd Qu.:37145                     
##                                        Max.   :49526                     
##    generation    device_type       
##  Min.   :10.00   Length:49526      
##  1st Qu.:20.00   Class :character  
##  Median :20.00   Mode  :character  
##  Mean   :24.54                     
##  3rd Qu.:30.00                     
##  Max.   :50.00

Data Cleaning

이번 사례와 같이 문제의 요인을 탐색하는 분석에서는 특정 상태의 데이터와 유저 정보를 연관시켜서 인과관계를 파악하는 식으로 분석하는 경우가 많다. 그러면 앞서 준비한 데이터를 연관시켜보도록 하자.

위에서 볼 수 있는 ’user_id’와 ’app_name’을 기준으로 데이터가 결합된 것을 확인할 수 있다. 유저들의 게임이용 여부를 각 속성정보들을 이용해 파악할 수 있다.

Segesegment

이제 각 조건별로 데이터를 크로스집계하여 분석해보자.

1) By Sex

substr은 문자를 추출하는 함수다. 첫번째부터 일곱번째 문자를 추출하여 월별 데이터를 만들고, table()함수로 크로스 집계하여 각각의 항목에 어느 정도의 숫자가 있는지 세어보는 분석으로서, 데이터 분석의 최초 단계에 실시하는 분석 기법 중 하나이다.

남녀 데이터를 비교해보면 전체적인 수치는 떨어졌지만 남녀 간의 구성비율은 거의 변화가 없으므로 성별과 게임이용률 하락에는 연관관계가 크지 않음을 알 수 있다.

##          gender
## log_month     F     M
##   2013-08 47343 46842
##   2013-09 38027 38148

2) By Age

연령대별로 비교해보면, 모든 연령대에서 대체로 비슷한 비율로 이용자수가 하락하였고, 특별히 전체 이용률에 영향을 끼친 연령대는 존재하지 않는다고 해석할 수 있다.

##          generation
## log_month    10    20    30    40    50
##   2013-08 18785 33671 28072  8828  4829
##   2013-09 15391 27229 22226  7494  3835

3) By Sex & Age

n중 크로스집계를 위해 reshape2라는 라이브러리를 사용하였다. reshape2는 데이터 전처리를 위한 여러 가지 툴을 모아둔 라이브러리로서 많은 분석자가 요긴하게 사용하고 있는 패키지이다. 그 중에서 ‘dcast()’ 함수를 사용해보았다. 함수 사용법은 다음과 같다.

  • dcast(data, x ~ y + z, value.var = “C”. length)

위와 같이 입력하면 데이터에서 세로축에서 x를 놓고 가로축에는 y와 z의 모든 가능한 조합을 놓아 크로스집계를 실시한다. ’크로스집계 안의 값은 C의 숫자를 세어서 넣으라’는 것이 value.var=C, length 에 해당한다.

결과를 보면 F_20, F_30 등 성별과 연령대를 크로스한 분석축이 새로 생긴 것을 알 수 있다. gender + generation 을 합쳤기 때문에 성별과 연령대가 ’_’로 연결되어 분석축으로 작성되었다.

그런데 집계 데이터를 보면, 이번에도 모든 세그먼트에서 비슷한 비율로 수치가 떨어졌음을 알 수 있고, 아쉽게도 전체 이용률 하락에 주로 영향을 끼친 부분은 찾아볼 수 없었다.

3) By Device type

단말기 별로 집계해서 보니, Android 기기에서 유저수가 크게 감소했음을 확인할 수 있었다.

##          device_type
## log_month Android   iOS
##   2013-08   46974 47211
##   2013-09   29647 46528

Visualizaion

이전에는 IOS 와 Android에서 비슷한 유저수를 유지했지만, 9월 두 번째 주부터는 Android 유저수가 급격히 줄어들었음을 알 수 있다.

Result

2개 이상의 변수의 인과관계를 교차해서 집계하는 분석 기법인 ’크로스 집계’를 사용해보았다. 두 가지 이상의 속성을 이용해서 복합적인 항목과 결과의 인과관계를 도출하는 것을 다중(n중) 크로스 집계라고 부르기도 한다. 이와 같은 크로스집계는 각종 직무에서 수집된 데이터를 해석할 때는 수집한 데이터를 먼저 쭉 살펴볼 목적으로 단순집계를 하거나 히스토그램을 작성하기도 한다고 한다. 경향이나 위와 같은 여러 항목을 조합한 인과관계를 파악하기 위해서는 데이터 항목별로 크로스집계를 실시하는 것만으로도 충분히 유용한 결과를 얻을 수 있기 때문이다.
또 탐색형 데이터 분석을 해보았는데, 여기에서 사전에 세웠던 가설을 보고 데이터 분석의 출발점을 항상 확인하는 것이 작업 효율상 중요하다고 판단된다. 데이터 분석을 깊게 검토하기 시작하면 끝이 없는 경우가 많아서, 필요 이상으로 분석에 시간을 낭비하는 경우가 종종 있다. 그런 사태를 방지하기 위해서라도 데이터 분석을 하기 전에 가설을 세워서 그것을 수시로 참조하는 것이 중요하다고 생각된다.

위에서 세웠던 가설에 데이터 분석 결과를 반영해서 정리해자면 아래와 같다.

  • 유저의 수가 지난 달보다 줄어들었다. (사실)
  • Android 단말기를 이용하는 유저수가 현저히 줄어들었다. (사실)
  • Android 단말기에서 게임에 문제가 있는지 찾아내고 해결하여 유저수를 지난달과 같은 수준으로 되돌린다. (적절해 보이는 해결책)