[
ml
idea
draft
]
이탈 예측을 어떻게 할 것인가?
예전에 게임 유저 이탈 예측을 시도해 보았는데, 성과가 썩 좋지는 않았다. 유저 이탈은 외부 요인 등으로 인해 성능에 한계가 있지만, 아래의 사항을 고려하여 다시 시도해보려 한다.
개선할 것
피처 합성 및 HPO 활용
저번에는 수작업된 피처들과, 적당한 휴리스틱으로 선택한 초모수로 훈련하였다. 최근에 Featuretools 등의 자동 피처 합성기와 Dask / Ray 클러스터를 이용한 초모수 최적화(Hyper-parameter Optimization) 테크닉을 활용해보려 한다. 얼마 안되는 피처에서 대충 설정한 초모수 보다는 좋은 결과가 나올 것으로 기대한다.
지금부터 필자가 고안한 변수와 초모수를 이용하여 이탈 예측 방법을 설명하겠다. 초모수는 서비스별 특성에 맞게 변경이 가능할 것이다.
용어와 개념
\[k = \lceil \frac {p} {d} \times U \rceil\]
- 단위 기간 한계 접속 일수 (unit_margin_plays, k^mar) : 단위 기간 접속 일수 (k) 의 한계값 (초모수).
- 유저의 단위 기간 접속일수가 이 값 미만이면 학습 및 예측에서 제외한다.
- 예측의 기대 이익에 맞도록 적절하게 선택
\[k^{mar} \in \mathbb Z, 1 \le k^{mar}\]
- 접속 주기 (play_freq, f) : 유저가 몇 일마다 접속하는지의 값. 유저가 대상 기간내 접속한 첫 날과 마지막 날로 유저별 기간을 정한뒤, 그 기간 의 일수 (d) 와 접속 일수 (p) 로 계산
- 예로, 대상 기간 14 일 동안 어떤 유저의 접속 및 결석일이 다음과 같은 경우 (접속일을 0, 결석일을 1로 표시)
[0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0]
- 해당 유저의 접속 주기 계산을 위한 기간은 두 번째 날부터 여덟 번째 날까지의 7일간이다.
- 즉, 기간 일수 d = 7 동안 접속 일수 p = 4 인 경우로, 접속 주기 f = 1.75 가 된다.
\[f = \frac {d} {p} = \frac {U} {k}\]
- 최대 접속 주기 (max_play_freq, f^max) : 접속 주기의 최대값. 단위 기간 (U) 및 한계 접속 일수 (k^mar) 로 계산.
- 예로, 단위 기간 U = 7 이고 단위 기간 한계 접속 일수 k^mar = 3 이면, f^max = 2.33 이 된다.
\[f^{max} = \frac {U} {k^{mar}}\]
- 유효 접속 일수 (effect_plays, e_p) : 학습이나 예측에서 몇 접속일의 데이터 포인트를 사용할지를 나타냄 (초모수).
- 예로 e_p = 4 인 경우, 대상일 이전 4 접속일의 데이터를 사용하겠다는 뜻이다.
- 이 값이 클 수록 모델 성능이 향상될 수 있으나, 많은 데이터가 필요하고 개념 표류 (Concept Drifting) 가 발생할 수 있다.
- 정확히 이 일수에 맞는 데이터를 수집하기 위한 것이 아니라, 다른 변수의 계산에 사용된다.
\[e_p \in \mathbb Z, 0 \lt e_p\]
\[E_d^{max} = \lceil f^{max} \times e_p \rceil\]
- 결석 일수 (absent_days, a) : 유효 데이터에서 마지막 접속일 이후 결석일의 수
피처
예측 모델의 성패는 피처에 달려있다고 해도 과언이 아닐 것이다. 피처는 다양한 방식으로 발굴될 수 있는데, 이 글에서 다 다루기는 어렵다. 별도의 글 온라인 게임을 위한 피처 유니버스 만들기 를 참고하도록 하자.
데이터 준비
앞서 말한 개념과 피처를 이용해 학습 및 예측을 위한 데이터를 준비하게 된다. 중요한 것은 모든 유저가 대상은 아니라는 점 이다. 게임 가입 후 적응하지 못하여 초기에 이탈했거나, 비정기적으로 플레이하는 유저, 그리고 어뷰징 툴을 사용하는 등의 유저는 기대 이익을 최대화하는 이탈 검출 을 위해 대상으로 하지 않는 것이 바람직할 것이다.
학습 데이터
학습 데이터 (learn_data, L) 는 유저별 피처 (features, X) 와 라벨 (label, y) 로 구성된다.
기본 용어와 개념
- 학습 데이터 (learn_data, L) : 모델 학습용 데이터.
- 이후 설명할 학습 데이터 시작일 (L_b) 에서 시작해, 학습 데이터 일수 (L_d) 이후인 학습 데이터 종료일 (L_e) 까지
- 학습 데이터 일수 (learn_data_days, L_d) : 학습 데이터의 날자 수 (초모수)
- 학습 데이터 일수가 많을 수록 데이터가 많아지나, 개념 표류를 피하도록 적절한 L_d 설정
- 적어도 이후 설명할 한계 학습 데이터 일수 (L_d^mar) 이상이어야 한다.
\[L_d \in \mathbb Z, L_d^{mar} \le L_d\]
실재 학습 데이터는 이후 설명할 수집 윈도우를 진행하며 여러번에 걸쳐 수집되며, 윈도우는 유효 데이터와 이탈 확인 데이터의 두 부분으로 나누어 진다. 먼저 관련 용어를 살펴보자.
- 이탈 확인 데이터 (churn_test_data, C) : 이탈 여부 판단에 사용
- 앞에서 설명한 유효 데이터 종료일 (E_e) 이후, 아래에서 설명할 이탈 확인 일수 (c_d) 만큼의 데이터
- 이탈 확인률 (churn_test_rate, c_r) : 각 유저에 대해, 이탈 확인에 필요한 일수를 계산하기 위한 값 (초모수).
- 접속 주기 (f) 에 대한 비율로, 오탐이나 미탐이 적도록 설정
- 너무 작으면 제대로된 검증을 할 수 없고, 너무 크면 검증에 시간이 오래 걸리며 지나치게 엄격한 검증이 될 수 있다.
\[c_r \in \mathbb R, 0 \lt c_r\]
- 이탈 확인 일수 (churn_test_days, c_d) : 각 유저에 대해, 이탈 확인에 필요한 날자 수.
- 유효 데이터에서 구한 접속 주기 (f) 에 이탈 확인률 (c_r)을 곱해 구한다.
- 예로 접속 주기 f = 1.75 인 유저에 대해 이탈 확인률 c_r = 6 으로 하면 이탈 확인 일수 c_d = 11 로, 유효 데이터 종료일 이후 11 일의 데이터가 있어야 이탈 판단이 가능하다.
\[c_d = \lceil f \times c_r \rceil\]
- 최대 이탈 확인 일수 (max_churn_test_days, c_d^max) : 모든 유저의 이탈 확인 일수 중 가장 큰 값. 최대 접속 주기 (f^max) 에 이탈 확인률 (c_r) 을 곱해 구한다.
- 이탈 확인을 위해 이 일수 만큼의 데이터를 확보해야 한다.
\[c_d^{max} = \lceil f^{max} \times c_r \rceil\]
- 한계 학습 데이터 일수 (learn_data_margin_days, L_d^mar) : 학습용 데이터는 학습 및 판정용 데이터가 필요한데, 이를 위해 필요한 최소한의 데이터 날자 수.
- 최대 유효 데이터 일수 (E_d^max) 와 최대 이탈 확인 일수 (c_d^max) 의 합이다.
- 예로, 최대 유효 데이터 일수 E_d^max = 10 이고 최대 그리고 최대 이탈 확인 일수 c_d^max = 7 이면 한계 학습 데이터 일수 L_d^mar 은 17 이 된다.
\[L_d^{mar} = E_d^{max} + c_d^{max}\]
한계 학습 데이터 일수는 어디까지나 최소한의 값이다. 이에 따라 데이터를 확보해도 그 기간동안 유저 행동에 변동이 있으면 데이터가 부족해질 수 있기에, 실제 학습 데이터 일수는 한계 학습 데이터 일수 보다 여유있게 잡자.
- 학습 데이터 종료일 (learn_data_end, L_e) : 학습 데이터의 마지막 날자. 이어 설명할 예측 데이터 시작일 (P_b) 보다 작아야 함
\[L_e < P_b\]
- 학습 데이터 시작일 (learn_data_begin, L_b) : 학습 데이터의 시작 날자.
- 학습 데이터의 시작일은 학습 데이터 종료일 (L_e) 과 학습 데이터 일수 (L_d) 에서 결정
\[L_b = L_e - L_d\]
수집 윈도우 관련
- 수집 윈도우 (window, w) : 유저의 학습 데이터를 순회하며 데이터를 수집하는 윈도우.
- 데이터 양을 늘리고 유저의 플레이 시기별 데이터를 활용하기 위해 이용
- 수집 윈도우 시작일 (window_begin, w_b) : 유저에 대한 윈도우 시작일.
- 처음에는 유저의 기간 내 첫 접속일과 같다.
- 이어 설명할 윈도우 스텝만큼 증가한다.
- 수집 윈도우 크기 (window_width, w_w) : 수집 윈도우의 범위.
- 유저의 수집 윈도우 시작일부터 유효 접속 일수를 만족하는 유효 데이터 일수 (E_d) 및 접속 주기 (f) 를 구한다.
- 여기서 이탈 확인 일수 (c_d) 를 구한다.
- 유효 데이터 일수 (E_d) 와 이탈 확인 일수 (c_d) 의 합이 윈도우의 크기가 된다.
- 유효 데이터 일수의 데이터는 학습에 사용되고, 이탈 확인 일수의 데이터는 이탈 판정에 사용된다.
\[w_w = E_d + c_d\]
- 수집 윈도우 종료일 (window_end, w_e) : 수집 윈도우 시작일부터 수집 윈도우 크기로 계산
\[w_e = w_b + w_w\]
여기까지의 설명을 그림으로 나타내면 아래와 같다:
- 수집 윈도우 비율 (window_rate, w_r) : 수집 윈도우의 진행 크기를 결정하는 비율 (초모수).
- 유효 데이터 일수 (E_d) 에 대한 비율
- 이 값이 0 에 가까울수록 중복이 많아지고, 1 에 가까울수록 데이터 재활용성이 낮아진다.
- 중복을 허용하되, 적정 수준을 유지하도록 설정
\[w_r \in \mathbb R, 0 \lt w_r \leq 1\]
- 수집 윈도우 스텝 (window_step, w_s) : 수집 윈도우의 진행 크기
- 유저의 유효 데이터 일수 (E_d) 에 수집 윈도우 비율 (window_rate, w_r) 을 곱해 결정
\[w_s = \lceil E_d \times w_r \rceil\]
- 수집 윈도우는 스텝 단위로 진행하다가, 유저가 이탈하거나 남은 데이터가 이탈 확인을 하기에 부족해지면 끝난다.
슈도 코드
학습 데이터를 모으는 과정의 슈도 코드는 아래와 같다:
학습 데이터 시작일 (L_b) 과 종료일 (L_e) 에서 학습 데이터 (L) 초기화
최대 유효 데이터 일수 (E_d^max) 를 구함
학습 데이터 내 모든 유저에 대해
첫 접속일을 수집 윈도우 시작일 (w_b) 로
수집 윈도우에 대해
데이터가 최대 유효 데이터 일수 (E_d^max) 미만이면
다음 유저로
윈도우 시작일 (w_b) 부터 최대 유효 데이터 일수 (E_d^max) 이후의 날을 대상일 (t) 로 함
대상일부터 거꾸로 거슬러 유효 접속 일수 (e_p) 를 만족하는 날을 찾아 유효 데이터 일수 (E_d) 결정
유효 데이터가 부족하면
다음 유저로
유효 데이터에서 단위 기간 접속 일수 (k) 및 접속 주기 (f) 를 구함
단위 기간 접속 일수 (k) 가 단위 기간 한계 접속 일수 (k^mar) 미만이면
다음 유저로
마지막 접속일 (l) 에서 결석 비율 (a_r) 을 구함 (피처로 사용)
접속 주기 (f) 에서 이탈 확인 일수 (c_d) 를 구함
이탈 확인 데이터가 부족하면
다음 유저로
이탈 확인 데이터 (C) 에서 구한 단위 기간 접속 일수 (k) 가 단위 기간 한계 접속 일수 (k^mar) 미만이면
이탈로 라벨링
유효 데이터에서 피처 정보 수집
피처와 유저의 이탈 여부 (라벨) 를 학습 데이터로 추가
이탈했으면
다음 유저로
활성이면
수집 윈도우 비율 (w_r) 로 윈도우 스텝 (w_s) 산정
수집 윈도우의 스텝만큼 윈도우 진행
위의 과정을 구체적인 예를 통해 살펴보자.
학습 데이터 수집 예
지금까지 설명한 개념과 과정의 이해를 돕기 위해, 추가적인 예를 들어 설명하겠다. 아래는 단위 기간 접속 일수가 k = 5 에서 k = 4 으로 변하고 이탈한 유저의 예이다.
- 공통 변수
- 단위 기간 U = 7
- 이탈 확인률 c_r = 3
- 윈도우 비율 w_r = 0.5
- 유효 접속 일수 e_p = 5
- 첫 번째 스텝 (단위 기간 접속 일수 k = 5 인 경우)
- 유효 데이터 일수 E_d = 8
- 접속 주기 f = 1.6
- 이탈 확인 일수 c_d = 5
- 윈도우 크기 w_w = E_d + c_d = 13
- 윈도우 스텝 w_s = 4
- 활성 판정
- 두 번째 스텝 (단위 기간 접속 일수 k = 4 인 경우)
- 유효 데이터 일수 E_d = 11
- 접속 주기 f = 1.75
- 이탈 확인 일수 c_d = 6
- 윈도우 크기 w_w = E_d + c_d = 20
- 이탈 판정
초모수의 선택
여기서는 초모수를 정하는 예를 살펴보겠다. 온라인 및 모바일 게임 서비스이고 단위 기간을 일주일로 할 때, 다음과 같이 초모수를 선택한다:
- 유효 접속 일수 (e_p)
- 4 ~ 10 범위에서 예측 점수가 높은 것을 HPO로 선택
- 단위 기간 한계 접속 일수 (k^mar) = 3
- 일주일에 세 번 오는 유저까지를 대상. 너무 가끔씩 접속하는 유저는 예측의 효용성이 작을 수 있다.
- 이탈 확인 일수 (c_d)
- 학습 데이터 일수 (L_d)
- 윈도우 비율 w_rs)
어떤 서비스에서 어떤 척도를 사용하는지에 따라 다양한 초모수가 이용될 수 있겠다.
척도의 선택
“실제 예측 모델이 목표로 해야할 것은 오차를 최소화하는 것이 아니라 모델 적용을 통해 기대되는 이익을 최대화 하는 것”
흔히 사용되는 Accuracy, Recall, F1-Score 등의 척도에서 이익을 최대화 하기 위한 방향으로 하는 것이 맞을 것이다.
예를 들어 제한된 프로모션 비용에서 이익을 최대화 하기 위해서 VIP 대상 이탈 예측을 선택하는 경우, 이들은 매출을 올려주는 진성 유저이기에 오탐을 두려워하지 말고 미탐이 적은 방향으로 학습 척도를 선택할 수 있다.
예측과 검증
예측
학습이 완료된 모델로 실제 예측을 실시한다. 이때 예측을 위한 데이터가 필요하다.
예측 데이터 (pred_data, P) : 학습된 모델로 유저의 이탈 예측을 하기 위한 데이터
용어와 개념
- 예측 데이터 일수 (pred_data_days, P_d) : 유저별 이탈 예측에 필요한 데이터의 일수. 최대 유효 데이터 일수 (E_d^max) 와 같게 한다.
\[P_d = E_d^{max}\]
-
예측 데이터 종료일 (pred_data_end, P_e) : 예측 데이터의 마지막 날자. 보통 대상일 (t) 전날이다.
\[P_e = t - 1\]
-
예측 데이터 시작일 (ed_data_begin, P_b) : 예측 데이터의 시작 날자. 예측 데이터 종료일에서 예측 데이터 일수를 뺀 것
\[P_b = P_e - P_d\]
- 예측 데이터 내 단위 기간 접속 일수 (k) 가 단위 기간 한계 접속 일수 (k^mar) 미만인 유저는 기이탈로 판단해 예측 대상에서 제외한다.
슈도 코드
예측 데이터를 모으고 예측하는 과정의 슈도 코드는 아래와 같다:
예측 데이터 시작일과 종료일에서 예측 데이터 (P) 초기화
예측 데이터 내 모든 유저에 대해
대상일에서 거꾸로 유효 접속일 (e_p) 에 맞는 유효 데이터 일수 (E_d) 를 찾음
유효 데이터에서 구한 단위 기간 접속 일수 (k) 가 단위 기간 한계 접속 일수 (k^mar) 미만이면
다음 유저로
유효 데이터에서 피처 정보 추출
학습된 모델에 넣어 예측
예측 후에는 결과를 저정해 사후 검증에 활용하도록 하자.
검증
실제 모델의 성능 평가를 위해 예측 후 검증이 꼭 필요하다. 검증은 예측 이후 데이터에 대해, 앞에서 설명한 학습 데이터 수집시와 같은 방식으로 이탈을 판정한다. 다만, 윈도우를 진행하지 않고 한 번만 판정한다.
예측한 모든 유저에 대해 검증하려면 충분한 시간이 흐른뒤 검증을 실시해야 한다. 검증의 결과로 예측 모델의 성능이 떨어졌으면, 예측 실패 사례를 포함한 최신 데이터로 다시 학습을 진행해야 한다.
슈도 코드
검증 과정의 슈도 코드는 아래와 같다:
대상 예측일에 대한 예측 결과 불러오기
예측 결과 내 모든 유저에 대해
예측 시점의 접속 주기 (f) 를 얻고, 이를 이용해 이탈 확인 일수 (c_d) 를 계산
이탈 확인 데이터내 단위 기간 접속 일수 (k) 가 단위 기간 한계 접속 일수 (k^mar) 미만이면
이탈 판정
예측과 실제 결과를 비교
검증 결과에서 모델의 성능 계산
검증 결과의 활용
검증의 결과 모델의 예측 성능이 일정 수준 이하로 떨어졌다면, 학습 데이터에 검증 데이터 기간이 포함되도록 하여 다시 모델을 업데이트하도록 하자.
기타
미숙 유저의 분류
미숙 (unripe) 유저는 가입 후 본격적으로 서비스를 이용하지 않은 유저로, 이탈 외 이런 유저의 식별도 도움이 될 수 있다.
- 서비스 초기에 적응하지 못하는 유저를 분석하기 위해
- 광고 어뷰징을 위해 접속하는 가짜 (false) 유저를 구분하기 위해
용어와 개념
끝으로
여기에 제시된 방법이 절대적인 것은 아닐지라도 이탈 예측을 하기 위한 참고가 되기를 바란다.