과거의 행동으로부터 현재의 행동을 예측할 수 있는가?

Ryu

2020-04-22

Overview

게임 ‘낚시랜드’에서는 유저가 피처폰에서 스마트폰으로 전환할 때 유저 ID 정보를 제대로 이전하지 못한 경우가 많지 않은가?’ 하는 의혹이 발생했다는 가정하에 과거 데이터를 이용해 분석해보고자 한다.

Dataloading

유저별로 ID 이전을 한 유저인지 아닌지 나타내는 데이터 정리

먼저 유저별로 피처폰에서 스마트폰으로 ID 이전을 한 유저인지 아닌지 나타내는 데이터를 작성해보자

unique(AA[, c(“XX”, “YY”. “ZZ”)])

위와 같이 입력함으로써 AA라는 데이터에서 항목 XX와 YY, ZZ가 중복되지 않도록 정리할 수 있다. XX만 다른 값이고 YY와 ZZ가 같은 값이라면 양쪽 데이터가 남지만 XX, YY, ZZ 모두 같은 값이라면 중복 처리되어 하나만 남게 된다. 여기서는 dau라는 날짜별 이용 상황 데이터를 가지고 월별 이용 상황을 나타내는 데이터를 작성하고 있기 때문에 하나만 남기기 위해 region_day의 중복을 제거해야 하는데, 이를 위해 unique 함수를 사용해서 region_month, device, user_id가 유일하도록 데이터를 작성하고 있는 것이다.

여기서는 피처폰 이용자와 스마트폰 이용자로 나누어서 월별 이용 데이터를 만들고 있다. 아울로 지난달과 이달의 데이터를 분류하여 각각 fa.mau1, fp.mau2, sp.mau1, sp.mau2에 데이터를 저장하고 있다.

다음으로 “mau$is_access” <- 1 을 입력하여 mau 데이터의 is_access라는 항목 모두에 1을 저장한다. 이를 가지고 데이터를 결합해 다음달에도 이용하는지 아닌지 판단한다. mau에는 1월과 2월에 게임을 이용한 유저의 데이터가 저장되어있다. 한편 fp.mau1에는 피처폰에서 이용한 유저의 데이터가 들어 있다. mau에서 2월의 데이터를 추출하여 이 데이터와 결합함으로써 1월에 피처폰으로 이용했던 사람이 2월에도 계속해서 이용하는지 판단할 수 있다. fp.mau1의 is_access[is. na(fp.mau1_is_access)] <- 0 에서는 결합 후 결손치가 된 곳을 0으로 치환하고 있다.

여기에 덧붙여 앞에 작성한 fp.mau2의 2월 이용 상황 데이터로부터 2월에도 계속해서 피처폰으로 이용하는지 구별한다.

다음으로 1월에는 피처폰으로 이용하다가 2월에는 스마트폰으로 이용한 유저를 구별해보자.

sp.mau2에는 2월에 스마트폰으로 이용한 유저의 데이터가 들어 있다. 여기에 is_sp라는 항목을 추가하여 모두 1을 저장하고 있다. 다음으로 이 데이터와 fp.mau1을 결합해서 fp.mau1에는 2월 이용자 중 스마트폰으로 이용한 유저의 데이터가 추가된다. 데이터를 살펴보면 다음과 같다.

다음으로 로지스틱 회귀분석에 필요한 데이터만 이 데이터로부터 추출한다. 이미 작성한 fp.mau1이라는 데이터로부터 is.access == 0 (다음 달(2월)에 이용하지 않은 유저), 혹은 is.sp == 1 (다음달 (2월)에 스마트폰으로 이용한 유저)만 추출하고 한다.

날짜별 게임 이용 상황 데이터 정리하기

dau 데이터에서 피처폰 이용자임과 동시에 2013년 1월에 이용한 유저를 뽑아내고 있다. 그 다음에 dcast함수로 순서를 정렬하여 fp.dau.cast라는 데이터로 저장한다.

names(fp.dau.cast)[-1] <- paste0(“X”, 1:31, “day”)

위 부분은 항목명을 알기 쉽도록 첫 번째 열을 제외한 나머지 열에 이름을 붙이기 위한 것이다. paset0 함수로는 파라미터로 넘겨준 값들을 공백 없이 연결한 값을 얻을 수 있다. 여기서는 “X”와 “day” 사이에 1에서 31까지의 숫자를 넣으라는 뜻이다.

앞서 작성한 이용 상황 데이터와 정답 데이터인 fp.mau1을 결합한다.

talbe 함수로 해당 부분을 집계해서 확인해보면, 유저군 ’0’이 190명, 유저군 ’1’이 62명으로 합계 252명의 데이터가 집계된 것을 알 수 있다.

## 
##   0   1 
## 190  62

로지스틱 회귀분석을 통한 모델 작성

로지스틱 회귀분석을 하고자 할 때는 glm 함수를 사용한다. 여기서 family 옵션에 binomail을 입력하고 있는데, 이 부분이 로지스틱 회귀분석을 실시하라고 지시하는 곳이다. 또한 여기서는 step이라는 함수를 사용하고 있는데 step 함수는 AIC라는 지표를 사용하여 모델에 사용할 설명변수를 늘릴지 혹은 줄일지 자동으로 계산해서 찾아주는 함수이다.

작성된 모델을 이용해서 예측하기

로지스틱 회귀분석에 의해 작성된 모델을 가지고 ID 이전을 해서 이용할 확률을 계산해보자. R에서는 fitted 함수로 예측값을 얻을 수 있다. fp.dau1.cast 데이터의 prob 항목에 예측값을 넣고 이후에 이어질 모델의 신뢰성 분석을 위해 ifelse 함수를 사용하는데, 이는 예측확률이 0.5보다 큰 것은 ID를 이전할 것이라고 예측했다는 뜻으로 1로 변경하고, 0.5보다 작은 것은 탈퇴할 것이라고 예측했다는 뜻으로 0으로 변경하기 위함이다.

이로써 분석 대상인 유저 ID별로 지난달 날짜별 이용 여부(X##day)와 is_sp에 이어, prob에 ID 이전을 할 확률과 pred에 그 확률을 근거로 한 ID 이전 여부의 예측값이 추가되었다. 여기서 마지막 항목 pred를 사용해서 모델의 신뢰도를 확인해보자. 예측과 실제의 차이를 확인하는 방법에는 여러 가지가 있지만, 여기서는 간단히 table 함수를 사용해서 집계하도록 하자.

##      pred
## is_sp   0   1
##     0 180  10
##     1  20  42

이번에 로지스틱 회귀분석을 통해 작성한 모델로 ‘1’ (ID 이전할 것)이라고 예측된 유저는 ’pred’가 1인 열이다. 한편 실제로 ID를 이전한 유저는 is_sp가 1인 행이다.

즉, 180명은 탈퇴할 것이라고 예측되었으며, 실제로 그렇게 했고, 42명은 ID를 이전할 것이라고 예측되었으며 실제로 그렇게 했다는 의미이다. 정답률을 계산하면 88%로 신뢰할 만한 모델을 구축했다고 생각해도 무방하다.

예측결과로부터 유저군 추측하기

이 모델에서 ‘1’(ID 이전할 것)이라고 예측되어 실제로 탈퇴한 유저가 10명인데, 이들의 지난달 이용 상황을 고려하면 분명 ID 이전을 하는 게 자연스럽다. 그러나 실제로는 탈퇴해버렸다. 여기서 이 유저들의 실제 이용 상황을 살펴보자.

fp.dau1.cast1에는 is_sp = 1(실제 스마트폰으로 이용한 유저)이며 예측에서도 ‘1’ 이라고 분류된 유저들만 뽑아냈다. 다음으로 order 함수를 사용해서 order(fp.dau1.cast1$prob, decreasing =T)와 같이 fp.dau1.cast1 데이터의 prob 항목이 큰 순서대로 정렬해서 표시하고 있다. 이 데이터를 통해 예측과 실제 모두 ’1’인 유저는 역시 게임을 자주 이용했던 것을 알 수 있다.

다음으로 예측은 ’1’인데 실제로는 ’0’인 유저에 대해 이용 상황을 체크해보자.

여기서도 fp.dau.cast2에서 해당 조건의 유저 데이터만 추출해서 order 함수로 prob가 큰 순서대로 정렬해서 표시했다.많은 유저에서 ’1’이라는 데이터를 볼 수 있으며, 1월의 어느 시점까지는 열심히 게임을 이용했던 것을 알 수 있다. 아무래도 이 10명의 유저가 게임에 흥미를 잃은 것은 아닌 듯하다.

다음으로 예측과 실제 모두 ’0’이었던, 즉 게임을 그만둔 유저들의 이용 상황도 살펴보도록 하자.

거의 게임을 이요하지 않고 있는데, 게임에 흥미를 잃으면서 서서히 발길이 줄어드는 모습을 짐작할 수 있다. 이를 통해 생각해봐도 이번에 작성한 모델은 역시 신뢰할만하다고 할 수 있다. 즉, 처음에 세웠던 가설대로 ’ID 이전 실패로 인해 탈퇴’의 영향은 크지 않았으며, 실제로 세어 봐도 10명 남짓일 뿐임을 알 수 있다.