Box and Whisker

Optimize the World

푸시 메시지 타이밍 찾기

유저의 접속 세션 데이터를 기반으로, 개별 유저에게 적절한 푸시 메시지 타이밍을 결정한다.

문제 제기

모바일 앱이 많아지면서 유저의 재방문을 높이기 위해 푸시 메시지를 사용하는 서비스가 많다. 문제는 유저를 고려하지 않는 푸시 메시지인데, 스팸으로 취급될 뿐더러 서비스 이탈을 가속화시키기도 한다. 특히, 푸시 메시지 자체의 비용이 매우 저렴하기 때문에 남용하는 경우가 많다. 그러나 푸시 메시지의 진짜 비용은 메시지 송신에 들어가는 물리 비용이 아니라, 고객이 느끼는 매체 피로감이다. 고객이 마케팅 채널에 과도하게 노출되면, 서비스 자체에 대한 매력도가 떨어진다. 만약 유저의 접속 패턴을 고려해서 적당한 푸시 타이밍에 메시지를 보낼 수 있다면, 마케팅 효과를 극대화하면서 과도한 푸시 메시지의 부작용을 피할 수 있다.

기본 아이디어

푸시 메시지로 달성하려는 목적은 다양한데, 이 글에서는 잘 접속하던 유저의 접속 주기가 증가하는 경향을 보일 때, 이를 관리하기 위한 목적으로 보내는 푸시 메시지를 가정한다. 이미 확실하게 이탈한 유저를 다시 모집하기 위해 보내거나, 별 다른 목적 없이 보내는 푸시 메시지는 논의에서 제외한다.

개별 사용자를 고려한 이탈 측정하기를 참고하면, 어떤 유저가 이런 종류의 푸시 메시지 대상으로 적합한지 알 수 있다. 서비스 사용 빈도가 줄어드는 유저를 다시 활성화시키려는 목적의 푸시 메시지를 보내기 위해서, 유저의 기존 접속 패턴을 사용한다.

유저의 접속 패턴을 관찰하면, 특정 시간대에 접속이 집중되는 것을 알 수 있다. 일반적으로 점심 시간과 저녁 퇴근 시간대, 저녁 식사 시간 이후부터 잠자기 전까지의 시간대에서 피크를 보인다. 이는 대부분의 유저들에게서 공통적으로 관찰할 수 있는 접속 패턴이다.

그러나 이러한 현상은 모든 유저들을 하나의 그룹으로 합쳐서 보았을 때 나타나며, 유저 개개인의 사정은 모두 다르다. 즉, 평균적인 유저의 접속 패턴은 전체 집단의 그것과 유사하지만, 유저를 더 자세하게 관찰하면 주로 접속하는 시간은 유저마다 다르다. 개별 유저의 접속 세션을 이용하여 유저 각각의 접속 시간 분포를 만들 수 있다.

개별 유저의 접속 시간 분포

접속 세션은 로그인 시각에서 시작하여 로그아웃 시각으로 끝나는, 일종의 가로로 긴 형태의 막대기라고 할 수 있다. 만약 세션이 로그인 시각과 로그아웃 시각에 따라 가로 길이가 결정되고, 그 세로 길이는 일정한 찰흙 막대기라면, 이 막대기를 바닥에 차곡차곡 쌓을 수 있다. 바닥에는 ‘시각(time)’ 눈금이 있어서 찰흙 막대기를 이 눈금에 맞춰 정확한 자리에 쌓는다.

session_bar

유저의 세션 막대는 시간이 흐르면서 여러 개가 생긴다. 한 명의 유저가 서비스를 사용하면서 세션 정보를 생성하고, 이러한 정보들은 모두 새로운 막대기가 된다. 개별 유저의 세션 막대들을 아래 그림처럼 동일한 시간 축에 차곡차곡 쌓는다. 이는 유저 전체에 대한 세션 막대기가 아니라, 특정 유저 한 명만의 정보다. 만약 100명의 유저가 있다면 100개의 서로 다른 시간 축에 개별 유저의 세션 막대기만 따로 쌓아서 100개의 서로 다른 찰흙 더미를 만든다.

session_bar2

아래에 이미 쌓인 찰흙 막대기가 있다면, 그 위에 추가로 세션 찰흙을 쌓는다. 바닥과 새로 쌓을 세션 찰흙의 길이가 맞지 않다면, 경계선에서 찰흙을 잘라 빈 공간이 없도록 계속해서 쌓는다. 모든 막대기를 쌓고 나면 아래와 같은 찰흙 더미가 생긴다.

session_bar3

유저의 수 많은 세션을 이렇게 쌓으면 이는 유저 개인의 접속 시간 분포가 된다. 총 넓이가 1이 되도록 표준화시키면 이를 통해 유저 개인이 어느 시간대에 접속해 있을지 확률을 계산할 수 있다.

session_bar4

접속 분포 함수를 \(f\)라고 한다면 $t_1$ 시점부터 $t_2$ 시점까지 유저가 접속해 있을 확률은 아래와 같이 계산할 수 있다.

\[P(t_1 \le X \le t_2) = \int_{t_1}^{t_2}f(x)dx\]

위에서 만든 접속 시간 분포를 사용하면, 유저가 오전 11시 30분에서 오후 1시 사이에 접속해 있을 확률을 아래와 같이 계산한다.

\[\begin{align} P(11\text{:}30 \le X \le 13\text{:}00) & = \int_{11\text{:}30}^{13\text{:}00}f(x)dx \\ & = \frac{13}{34} \approx 0.3823 \\ & = 38.23\% \end{align}\]

session_bar5

유저의 접속 패턴은 보통 요일에 따라 다른데, 특히 평일과 휴일 사이에 차이가 많다. 위의 예시에서는 편의를 위해 요일 패턴을 감안하지 않았으며, 접속 시각을 시간 단위로만 기록하였다.

접속 시간 분포를 활용한 푸시 타이밍

모든 유저의 접속 시간 분포를 알고 있기 때문에 가장 접속할 가능성이 높은 시간대를 유저별로 찾을 수 있다. 접속 가능성이 높은 시간대는 유저가 서비스를 주로 사용하는 시간이므로, 메시지를 수용할 가능성이 높다. 예를 들어, 재접속을 유도하는 푸시 메시지를 보낸다면 유저가 서비스를 주로 사용하던 시간대에 보내는 것이 합리적이다. 기존에 게임을 하던 시간에 게임 관련 메시지를 받는다면, 유저가 다시 게임을 할 가능성이 높기 때문이다.

대부분의 서비스는 유저의 세션 정보를 기록하여 보관한다. 따라서 유저 세션 정보를 활용한 위의 방법은 어느 서비스에서나 실행 가능하다. 주어진 정보를 최대한 활용해서 합리적인 의사 결정을 하도록 돕는 것이 데이터 분석의 목적이다. 이미 알고 있는 유저의 접속 정보를 활용해서 메시지를 보낼 시간을 정하는 것은 현명한 의사결정 방법이다.

다만, 유저의 세션 정보에서 아직 활용하지 않은 데이터가 있는데, 바로 현 시점의 유저 접속 여부다.

현 시점까지의 접속 정보를 활용한 푸시 타이밍

이미 오늘 잘 접속해서 서비스를 이용한 유저에게 푸시 메시지를 보낼 필요는 없다. 문제는 오늘 이 시간까지 접속하지 않은 유저들인데, 어차피 접속할 유저들에게 푸시 메시지를 보내는 것도 자원 낭비다. 그러나 시간이 흐르면 지금까지 접속하지 않은 유저가 이후 시간대에 접속할 가능성은 점점 줄어든다.

따라서 현 시점까지 접속하지 않은 유저가 앞으로 접속할 가능성을 가늠하고, 이에 대응하여 전략을 수립한다. 이런 확률을 계산하기 위해서 조건부 확률을 이용하는 것이 정확한 방법인데, 이를 위해서는 세션 데이터를 더 가공해야 한다. 조건부 확률을 이용해 푸시 타이밍을 결정하는 방법에 대해서는 유저가 접속할 확률 계산하기에서 소개하고, 지금은 위에서 구한 접속 시간 분포를 이용한다.

조건부 확률을 사용하지 않기 때문에 개념에 유의할 필요가 있다. 아래에서 구하는 확률은 특정 사건(특정 시점 전까지 유저가 접속하지 않은 사건)이 발생했다는 가정하에서 구하는 확률이 아니다. 위에서 구한 접속 시간 분포는 유저가 접속을 했을 경우에 어느 시간대에 접속할 가능성이 높은지를 나타낸다. 이에 대한 더 자세한 구분과 설명은 유저가 접속할 확률 계산하기에서 다룬다.

아래는 푸시 메시지를 보낼까 말까 망설이는 실무자의 상황을 가상으로 만들어 본 것이다.

현 시점을 $t_0$라고 하면, 아래와 같은 그림을 상상할 수 있다. $t_0$이전에는 유저가 접속하지 않았으므로, 오늘 남은 기회는 $t_0$ 오른쪽에 남은 시간 뿐이다. 만약 유저가 오늘 접속한다면, 해당 시간에 유저가 접속해 있을 확률은 $33\,/\,34 \approx 97.06\%$다. 아직 유저가 접속할 기회는 많다. 조급하게 푸시 메시지를 보낼 필요는 없다.

session_bar_t0

시간이 흘러서 $t_1$이 되었다. 아직 유저는 접속하지 않았고, 시간이 흐른 만큼 유저가 접속할 가능성은 줄어들었다. 그래도 $t_1$ 시점 이후에 유저가 접속해 있을 가능성은 $28\,/\,34 \approx 82.35 \%$다. 아직 기다릴 수 있다. 유저에게 연락하지 않는다.

session_bar_t1

시간이 더 흘러서 $t_2$가 되었다. 점심 시간 직전인데, 아직 유저는 접속하지 않았으며, 유저가 접속할 수 있는 시간대가 줄어들었다. $t_2$ 시점 이후에 유저가 접속해 있을 가능성은 $21\,/\,34 \approx 61.76 \%$다. 그러나 아직 메시지를 보내지 않고 기다린다.

session_bar_t2

점심 시간이 지났고, 시간은 $t_3$가 되었다. 가장 자주 접속을 하던 점심 시간대가 지나서도 유저가 접속하지 않았다. 유저가 $t_3$ 시점 이후에 접속해 있을 가능성은 $12\,/\,34 \approx 35.29\%$다. 가능성이 $50\%$이하로 떨어졌으니, 유저에게 푸시 메시지를 보낸다. “지금 들어오시면, 선물을 드립니다.” 약간 늦은 감도 드는데, 조금 더 빨리 메시지를 보내는 것이 좋았을지 모른다. 12시 30분에 보내면 더 좋지 않았을까?

session_bar_t3

$t_{3-1}$로 돌아가서 12시 30분의 상황을 살펴보면, 유저가 이 시점 이후에 접속해 있을 가능성은 $16\,/\,34 \approx 47.06\%$다. 이미 가능성이 절반 이하다. 시간을 되돌릴 수 있다면, 12시 30분에 유저에게 메시지를 보내고 싶다. “지금 들어오시면, 선물을 많이 드립니다.”

session_bar_t3_1

실행 상의 어려움

자동화

유저들의 접속 여부를 준실시간으로 확인해서 확률을 계산해야 한다. 이에 대한 기술적인 방안이 없다면, 실행이 어렵다. 위와 같은 과정을 개별 유저에 대해서 판단하고 실행을 해야하므로 자동화는 필수적이다. 모든 유저의 상황이 다르기 때문에 사람이 하나씩 대응하는 것은 불가능하다. 미리 정해 놓은 확률 기준을 넘어가면 자동으로 이벤트를 발생시키는 트리거 시스템이 필요하다. 기준만 사람이 똑똑하게 결정하고, 실행은 기계에게 맡겨야 가능한 전략이다.

로그 아웃 기록 부재

웹이나 앱의 접속 기록에서 로그아웃 기록이 없는 경우가 많다. 이러한 경우, 특정 기준을 사용하여 적절한 로그아웃 시간을 만들어주어야 한다. Google Analytics는 기본적으로 30분 동안 유저의 활동이 기록되지 않을 경우, 세션 아웃을 기록한다. 우리도 이를 따른다. 서비스에 따라서 기준이 달라질 수도 있는데, 세션 길이에 대한 확신이 있을 경우 이를 변경하는 것도 좋다.

아주 짧은 세션

세션 길이가 아주 짧은 서비스도 많다. 서비스에 따라서는 평균 세션 길이가 십여분에 불과한 경우도 있다. 이런 경우, 현실적으로 세션 찰흙을 쌓는 것이 불가능할 수 있다. 시간 축을 촘촘하게 만드는 것이 하나의 대안이다. 그러나 불가피하게 접속 분포가 세밀해진다. 시간 간격을 충분히 촘촘하게 만들어도 중간에 이가 빠진 형태의 분포가 형성될 수 있다. 이럴 때는 활용 가능한 분포 모양으로 다듬는다.

데이터 관리

서비스 이용 유저가 많은 경우, 모든 유저의 분포를 따로 저장하기 어렵다. 위의 과정은 경험적 분포를 만들기 때문에, 실제로 시스템에 저장하려면 아주 많은 데이터를 포함할 수 있다. 게다가 요일 특성이나, 기타 유저에 따른 속성을 고려한다면 유저 한 명에게 필요한 데이터가 아주 많아진다. 이런 경우, 실제로 유저에게 취할 액션과 전략을 먼저 결정하고, 필요한 정보만 기록한다. 가능하다면 분포를 특정 함수형으로 근사화하여 사용하는 것이 좋다.

활용안

유저 가치

모든 유저가 다 같은 가치를 갖지 않는다. 유저의 기본적인 잠재가치(LTV)를 고려하는 것도 중요하지만, 개별 유저마다 구매 타이밍이 다르기 때문에 이에 대한 고려가 필요하다. 조만간 구매 타이밍이 돌아올 유저라면 이러한 가치를 함께 고려해서 푸시 메시지 타이밍을 결정하는 것이 효과적이다. 확률은 단순히 특정 사건에 대한 믿음의 정도를 나타내는 숫자다. 확률에 가치(돈)를 부여해서 기대 가치를 계산하고, 이를 기준으로 실행 자원을 사용하는 것이 중요하다.

컨텐츠를 고려한 메시지 내용

타이밍과 함께 중요한 것이 메시지의 내용이다. 여러가지 방안이 있지만, 유저가 최근에 경험한 컨텐츠와 관련이 있는 메시지가 효과적이다. 만약, 유저 경험의 허들 구간이 존재한다면 허들 부근의 유저에게는 허들 관련 메시지를 보내는 것을 고려한다. 아무리 메시지 타이밍을 잘 선택하더라도, 메시지의 내용이 부실하다면 원하는 행동을 이끌어내기 어렵다.

A/B 테스트

푸시 메시지 규모를 나누어 A/B 테스트를 하면 효과를 확실하게 알 수 있다. 정말 유저 접속 분포를 사용해서 메시지를 보내면 반응률이 더 높은지 실험을 통해 검증한다. 위에서 정리한 내용은 상황에 따라서 그 결과가 다를 수 있다. 일반적인 내용이므로 실제 서비스에 적용한다면 테스트가 필요하다. 극단적으로는 ‘그냥 점심 시간에 일괄적으로 보내는 것과 차이가 없다’는 결론에 도달할 수도 있다. 아주 작은 규모라도 테스트를 반드시 수행한다. 관련 내용은 다음을 참고한다.

타임 윈도우 확장

위에서는 온라인 서비스를 가정하여 고객의 접속 시간을 매우 짧은 시간대로 표현하였다. 그러나 관찰 기간을 늘려서 생각하면, 반드시 시간 단위의 접속 기록만을 다룰 수 있는 방법은 아니다. 예를 들어, 일 단위 접속 기록으로 변형하면 얼마든지 기간을 확장한 응용 방법을 생각할 수 있다. 물론 이런 경우에 고객에게 취할 수 있는 액션이나 전략은 달라져야 한다. 고객의 방문 주기가 아주 긴 오프라인 매장이나 다른 종류의 서비스 분야에 충분히 대응할 수 있다.

관련 글

유저가 접속할 확률 계산하기