멤버십 리워드 프로그램의 효과 추정하기
Estimating the effect of a Member Rewards program
작성자: 김가연
DoWhy 를 사용하여 고객에 대한 구독 또는 리워드 프로그램의 효과를 추정하는 방법을 알아보겠습니다.
고객이 웹사이트에 가입하면 추가 혜택을 받는 멤버십 리워드 프로그램이 있다고 가정해봅시다. 해당 프로그램이 효과적인지 어떻게 알 수 있을까요? 여기서 우리는 인과적인 질문을 할 수 있습니다.
멤버십 리워드 프로그램 제공이 총 매출에 미치는 영향은 무엇인가?
그리고 이와 동등한 반사실적(counterfactual) 질문은 다음과 같습니다.
만약 고객들이 멤버십 리워드 프로그램에 가입하지 않았다면, 그들은 웹사이트에 얼마나 더 적은 돈을 썼을 것인가?
다시 말하면, 우리는 처치집단에 대한 평균 처치 효과(the Average Treatment Effect On the Treated, ATT)를 구하고자 합니다.
I. Formulating the causal model
리워드 프로그램이 2019년 1월에 도입되었다고 가정해봅시다. 결과 변수는 연말 총 지출액입니다. 우리는 모든 유저의 모든 월별 거래 내역과 리워드 프로그램 가입을 선택한 유저들의 가입 시간에 대한 데이터를 가지고 있습니다. 데이터는 다음과 같습니다.
# Creating some simulated data for our example example
import pandas as pd
import numpy as np
num_users = 10000
num_months = 12
signup_months = np.random.choice(np.arange(1, num_months), num_users) * np.random.randint(0,2, size=num_users)
df = pd.DataFrame({
'user_id': np.repeat(np.arange(num_users), num_months),
'signup_month': np.repeat(signup_months, num_months), # signup month == 0 means customer did not sign up
'month': np.tile(np.arange(1, num_months+1), num_users), # months are from 1 to 12
'spend': np.random.poisson(500, num_users*num_months) #np.random.beta(a=2, b=5, size=num_users * num_months)*1000 # centered at 500
})
# Assigning a treatment value based on the signup month
df["treatment"] = (1-(df["signup_month"]==0)).astype(bool)
# Simulating effect of month (monotonically increasing--customers buy the most in December)
df["spend"] = df["spend"] - df["month"]*10
# The treatment effect (simulating a simple treatment effect of 100)
after_signup = (df["signup_month"] < df["month"]) & (df["signup_month"] !=0)
df.loc[after_signup,"spend"] = df[after_signup]["spend"] + 100
df0
0
6
1
526
True
1
0
6
2
464
True
2
0
6
3
473
True
3
0
6
4
502
True
4
0
6
5
436
True
...
...
...
...
...
...
119995
9999
7
8
533
True
119996
9999
7
9
518
True
119997
9999
7
10
485
True
119998
9999
7
11
504
True
119999
9999
7
12
459
True
120000 rows × 5 columns
The importance of time
이 문제를 모델링하는 데 있어서 시간이 중요한 역할을 합니다.
리워드 프로그램 가입은 향후 거래에 영향을 미칠 수 있지만, 이전 거래에는 영향을 미치지 않습니다. 사실 리워드 가입 이전의 거래는 리워드 가입 결정을 유발한다고 가정할 수 있습니다.
따라서 각 유저의 변수들을 다음과 같이 나눌 수 있습니다.
처치 전 활동 (처치의 원인)
처치 후 활동 (처치 적용 결과)
물론 가입과 총 지출에 영향을 미치는 많은 중요한 변수가 누락되어 있습니다(e.g., 구입한 제품 유형, 유저 계정 사용 기간, 지역 등). 관측되지 않은 교란 변수(Unobserved Confounders)를 나타내는 노드가 필요합니다.
아래는 i=3 개월에 가입한 유저에 대한 인과 그래프입니다. 모든 i에 대해서 분석은 유사할 것입니다.

더 일반적으로, 고객에 대한 모든 활동 데이터를 위 그래프에 포함시킬 수 있습니다. 모든 사전 및 사후 활동 데이터는 이미 사용된 사전 및 사후 노드들과 동일한 위치 및 엣지를 차지합니다.
II. Identifying the causal effect
만약 관측되지 않은 교란 변수가 큰 역할을 하지 않는다고 가정해봅시다.
DoWhy 는 그래프를 바탕으로, 가입 월과 처지 이전 월(signup_month, pre_spend)에 소요된 금액을 조건화할 필요가 있다고 판단합니다.
III. Estimating the effect
이제 backdoor estimand(추정치)를 기반으로 target_units 를 “att”로 설정하여 효과를 추정합니다.
위와 같이 평균 처치 효과를 알려줍니다. 즉, i=3 개월에 리워드 프로그램에 등록한 고객의 총 지출에 대한 평균 효과입니다. i 값을 변경한 후 분석을 다시 실행하여 다른 달에 가입한 고객에 대한 효과를 비슷한 방법으로 계산할 수 있습니다.
다만 좌측 및 우측 관측 중단으로 인해 효과 추정에 어려움을 겪는 경우가 존재합니다.
좌측 관측 중단 (Left-censoring)
: 고객이 첫 달에 가입하는 경우, 우리는 가입하지 않은 고객과 비교할 만큼 충분한 거래 이력이 없습니다. 따라서 backdoor identified estimand 를 적용해야 합니다.
우측 관측 중단 (Right-censoring)
: 고객이 마지막 달에 가입하는 경우, 가입 후 결과를 추정하기에는 향후(사후) 거래 이력이 부족합니다.
따라서 아무리 가입 효과가 모든 달에 걸쳐 동일했더라도, 데이터가 부족한 상황에서는 추정된 pre-treatment 또는 post-treatment 거래 활동의 변동이 클 수 있기 때문에 가입 월별로 추정 효과가 다를 수 있습니다.
IV. Refuting the estimate
Placebo treatment refuter 를 사용하여 추정치를 반박합니다. 이 refuter 는 treatment 를 독립적인 랜덤 변수로 대체하고 추정치가 0이 되는지 여부를 확인합니다. (0이 되어야 합니다!)
Last updated