지난 달에 비해 이달의 이용 유저수가 크게 감소했다. 광고나 이벤트 등은 크게 차이나지 않았다. 그래서 감소의 원인을 조사하여 대책을 마련해보고자 한다.
지난달과 비교해서 유저수가 감소하였음
지난달과 같은 수준으로 유저수 회복
문제 발견 단계에서는 항상 크고 넓은 시점으로 모든 가능성을 염두에 두는 것이 중요하다. 아래와 같은 가설을 세운다고 해보자.
가설을 세운 후에는 가급적 단시간에 검증하는 것이 좋다. 관련 부서를 통해 다음과 같은 사실을 알아낼 수 있었다고 하자.
그렇다면 ‘성별 혹은 연령 등 특정 유저층에서 탈퇴한 유저가 많았다’ 라는 가설만이 조사할 가치가 있어보인다. 이것을 조금 더 자세히 알아볼 필요가 있다는 의미이다. 먼저 성별, 연령 등을 기준으로 분류하여 줄어든 유저가 있는지 없는지 확인할 수 있다. 그러면 각 유저층의 유저수를 지난달과 비교해서 줄어든 유저층이 있는지 데이터로 확인하고, 만일 실제로 있다면 유저수를 어떻게 회복할지 생각해봐야 한다.
분석해야 할 테마가 정해졌다면 분석에 필요한 데이터를 검토한다. 이번에 실시할 세그먼트 분석에는 구체적으로 어떠한 데이터가 필요한지 다음 가설을 통해 다시 한 번 리마인딩 해보자.
숫자가 줄어든 유저층에 적합한 대책을 세워서 지난달과 같은 수준으로 유저수를 회복한다.
이 가설을 가지고 분석 스토리를 정리해보자.
위에서 불러온 파일들을 확인해보자
여기서 log_date 를 날짜형으로 바꾸고 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
성별, 연령대, 기종과 같은 컬럼은 팩터형으로 변경해주고 나머지는 위와 동일하게 처리해주도록 하자.
여기서 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
이번 사례와 같이 문제의 요인을 탐색하는 분석에서는 특정 상태의 데이터와 유저 정보를 연관시켜서 인과관계를 파악하는 식으로 분석하는 경우가 많다. 그러면 앞서 준비한 데이터를 연관시켜보도록 하자.
# DAU에 user_info 결합
dau_user_info <- merge(dau, user_info, by = c("user_id", "app_name"))
head(dau_user_info)위에서 볼 수 있는 ’user_id’와 ’app_name’을 기준으로 데이터가 결합된 것을 확인할 수 있다. 유저들의 게임이용 여부를 각 속성정보들을 이용해 파악할 수 있다.
이제 각 조건별로 데이터를 크로스집계하여 분석해보자.
substr은 문자를 추출하는 함수다. 첫번째부터 일곱번째 문자를 추출하여 월별 데이터를 만들고, table()함수로 크로스 집계하여 각각의 항목에 어느 정도의 숫자가 있는지 세어보는 분석으로서, 데이터 분석의 최초 단계에 실시하는 분석 기법 중 하나이다.
남녀 데이터를 비교해보면 전체적인 수치는 떨어졌지만 남녀 간의 구성비율은 거의 변화가 없으므로 성별과 게임이용률 하락에는 연관관계가 크지 않음을 알 수 있다.
# 월 항목 추가
dau_user_info$log_month <- substr(dau_user_info$log_date, 1, 7)
# 성별로 집계
table(dau_user_info[, c("log_month", "gender")])## gender
## log_month F M
## 2013-08 47343 46842
## 2013-09 38027 38148
연령대별로 비교해보면, 모든 연령대에서 대체로 비슷한 비율로 이용자수가 하락하였고, 특별히 전체 이용률에 영향을 끼친 연령대는 존재하지 않는다고 해석할 수 있다.
## generation
## log_month 10 20 30 40 50
## 2013-08 18785 33671 28072 8828 4829
## 2013-09 15391 27229 22226 7494 3835
n중 크로스집계를 위해 reshape2라는 라이브러리를 사용하였다. reshape2는 데이터 전처리를 위한 여러 가지 툴을 모아둔 라이브러리로서 많은 분석자가 요긴하게 사용하고 있는 패키지이다. 그 중에서 ‘dcast()’ 함수를 사용해보았다. 함수 사용법은 다음과 같다.
위와 같이 입력하면 데이터에서 세로축에서 x를 놓고 가로축에는 y와 z의 모든 가능한 조합을 놓아 크로스집계를 실시한다. ’크로스집계 안의 값은 C의 숫자를 세어서 넣으라’는 것이 value.var=C, length 에 해당한다.
결과를 보면 F_20, F_30 등 성별과 연령대를 크로스한 분석축이 새로 생긴 것을 알 수 있다. gender + generation 을 합쳤기 때문에 성별과 연령대가 ’_’로 연결되어 분석축으로 작성되었다.
그런데 집계 데이터를 보면, 이번에도 모든 세그먼트에서 비슷한 비율로 수치가 떨어졌음을 알 수 있고, 아쉽게도 전체 이용률 하락에 주로 영향을 끼친 부분은 찾아볼 수 없었다.
library(reshape2)
dcast(dau_user_info, log_month ~ gender + generation, value.var = "user_id", length)단말기 별로 집계해서 보니, Android 기기에서 유저수가 크게 감소했음을 확인할 수 있었다.
## device_type
## log_month Android iOS
## 2013-08 46974 47211
## 2013-09 29647 46528
이전에는 IOS 와 Android에서 비슷한 유저수를 유지했지만, 9월 두 번째 주부터는 Android 유저수가 급격히 줄어들었음을 알 수 있다.
# 날짜별로 단말기별 유저수 산출하기
library(plyr)
dau_user_info_device_summary <- ddply(dau_user_info, .(log_date, device_type), summarize, dau = length(user_id))
# 시계열의 트렌드 그래프 그리기
library(ggplot2)
library(scales)
limits <- c( 0, max(dau_user_info_device_summary$dau))
a <- ggplot(dau_user_info_device_summary, aes( x = log_date, y = dau, col = device_type, lty = device_type, shape = device_type)) +
geom_line(lwd = 1) +
geom_point(size = 4) +
scale_y_continuous(label = comma, limits = limits)
library(plotly)
ggplotly(a)2개 이상의 변수의 인과관계를 교차해서 집계하는 분석 기법인 ’크로스 집계’를 사용해보았다. 두 가지 이상의 속성을 이용해서 복합적인 항목과 결과의 인과관계를 도출하는 것을 다중(n중) 크로스 집계라고 부르기도 한다. 이와 같은 크로스집계는 각종 직무에서 수집된 데이터를 해석할 때는 수집한 데이터를 먼저 쭉 살펴볼 목적으로 단순집계를 하거나 히스토그램을 작성하기도 한다고 한다. 경향이나 위와 같은 여러 항목을 조합한 인과관계를 파악하기 위해서는 데이터 항목별로 크로스집계를 실시하는 것만으로도 충분히 유용한 결과를 얻을 수 있기 때문이다.
또 탐색형 데이터 분석을 해보았는데, 여기에서 사전에 세웠던 가설을 보고 데이터 분석의 출발점을 항상 확인하는 것이 작업 효율상 중요하다고 판단된다. 데이터 분석을 깊게 검토하기 시작하면 끝이 없는 경우가 많아서, 필요 이상으로 분석에 시간을 낭비하는 경우가 종종 있다. 그런 사태를 방지하기 위해서라도 데이터 분석을 하기 전에 가설을 세워서 그것을 수시로 참조하는 것이 중요하다고 생각된다.
위에서 세웠던 가설에 데이터 분석 결과를 반영해서 정리해자면 아래와 같다.