주제
1. 가상 A/B 테스트 데이터로 실습
2. Two-sample t-test 실습
3. Impression / Click / Purchase / Amount 비교
4. A/B 테스트 분석 구현 방법
1. 가상 A/B 테스트 데이터로 실습
1.1 테이블 소개
- 가상 데이터로 A/B 테스트 실습 진행
- 프로덕션 DB에 저장되는 정보들을 데이터 웨어하우스에 적재했다고 가정
- raw_data.user_event
- 사용자/날짜/아이템 별로 impression이 있는 경우 그 정보를 기록하고 impression으로부터 클릭, 구매, 구매 시 금액을 기록
- 실제 환경에서는 이런 그룹화된 정보를 로그 파일 등의 소스로부터 만들어내는 프로세스가 필요
CREATE TABLE raw_data.user_event (
user_id int,
datestamp timestamp,
item_id int,
clicked int,
purchased int,
paidamount int
);

- raw_data.user_variant
- 사용자가 소속된 AB test variant를 기록한 파일
- 보통 experiment와 variant 테이블이 별도로 존재함
- variant_id에 언제 소속되었는지에 대한 타임스탬프 필드가 존재하는 것이 일반적임
- 보통 프로덕션 DB에서 가져옴
CREATE TABLE raw_data.user_variant (
user_id int,
variant_id varchar(32) -- control vs. test
);

- raw_data.user_metadata
- 사용자에 관한 메타 정보가 기록된 파일(성별, 나이 등)
- 메타정보를 이용해 다양한 각도에서 테스트 결과를 분석해볼 수 있음
CREATE TABLE raw_data.user_metadata (
user_id int,
age varchar(16),
gender varchar(16)
);

- 요약 테이블은 CTAS로 만들 수 있다
CREATE TABLE analytics.variant_daily_sessions AS
SELECT
variant_id,
user_id,
datestamp,
count(distinct item_id) num_of_items, -- 총 impression
sum(clicked) num_of_clicks, -- 총 click
sum(purchased) num_of_purchases, -- 총 purchase
sum(paidamount) revenue -- 총 revenue
FROM raw_data.user_event ue
JOIN raw_data.user_variant uv ON ue.user_id = uv.user_id
GROUP by 1, 2, 3

1.2 데이터 살펴보기
- t-score를 계산하는 방법
- scipy.stats.ttest_ind 활용
- ttest_ind()함수를 사용하여 두 그룹의 값들을 비교
- t-score와 p-value를 계산하여 반환함
- 직접 계산
- Tableau 같은 대시보드 툴에서는 직접 계산을 해야함
- scipy.stats.ttest_ind 활용
2. Two-sample t-test 실습
- 서로 독립적인 두 그룹 사이의 샘플 평균을 비교하는 검정 방법
- x1, x2는 각 집단의 평균
- n1, n2는 각 집단의 크기
- s1, s2는 각 집단의 표준편차

- 파이썬 scipy의 ttest_ind() 함수를 이용한 t-score 구하기
# control 그룹에 속한 매출액 정보와 test 그룹에 속한 매출액 정보를 numpy 배열로 변환 후 계산
def compute_z_score(df, field_name):
a = df[df["variant_id"]=="control"][field_name].to_numpy()
b = df[df["variant_id"]=="test"][field_name].to_numpy()
t, p = stats.ttest_ind(b, a)
return t, p
# 계산된 t-score(z-score) 확인
print(compute_z_score(variant_daily_sessions, "revenue"))

- s1은 각 값의 제곱의 합을 알면 쉽게 계산이 가능하다
- 값의 제곱의 합이 왜 필요하지? → Tableau에서 z-score를 계산할 때는 파이썬을 이용한 계산이 불가능하기 때문에 직접 구해야만 함
- 필요한 변수들을 미리 구하고 t-score 계산 진행
import numpy as np
import math
n_a2 = len(a)
n_b2 = len(b)
mean_a2 = np.mean(a)
mean_b2 = np.mean(b)
var_a2 = np.var(a)
var_b2 = np.var(b)
t_score2 = (mean_b2 - mean_a2)/math.sqrt(var_a2/n_a2+var_b2/n_b2)
print(t_score2)

3. Impression / Click / Purchase / Amount 비교
- Two-sample t-test 계산을 impression, click, purchase, amount 지표에 반복하여 진행
- A와 B 별로 위의 평균값을 보여주고 B의 값의 경우 t-score를 바탕으로 컬러 코딩하여 보기 쉽게 정리
- 빨간색은 테스트 그룹이 더 낮음을 뜻함
- 초록색은 테스트 그룹이 더 높음을 뜻함
- 예시) :
| A | B | |
| Impressions | 109 | 105 |
| Clicks | 15 | 14 |
| Purchase | 1.6 | 2.0 |
| Paidamount | 110 | 120 |
- 위의 compute_z_score() 함수를 사용하여 각 지표의 t-score 계산
- 모든 z-score가 -1.96 - 1.96 사이이므로 p-valuesms 0.05보다 크다고 할 수 있다.
# impression
print(compute_z_score(vds, 'num_of_items'))
# click
print(compute_z_score(vds, 'num_of_clicks'))
# purchase
print(compute_z_score(vds, 'num_of_purchases'))



4. A/B 테스트 분석 구현 방법
4.1 A/B 테스트 분석 시각화 대시보드 요구 조건
- 다음 분석이 가능해야한다:
- A/B 테스트 전체 기간에 걸쳐 키 지표가 비교 가능해야 한다
- 일별로 키 지표의 비교가 가능해야 한다(trend)
- 키 지표의 경우 통계적으로 유의미한지 무의미한지 표시가 되어야 한다(color coding)
- 트래픽(사용자) 메타 데이터가 있다면 이를 바탕으로 필터링이 가능해야 한다
- 성별
- 나이
- 지역
- 신규 사용자 vs. 기존 사용자
- Acquistion channel
- 위 정보를 통해 새 기능의 부분적인 론치가 가능할 수 있다
- 어려운 점은?
- 선택된 필터에 따라 z-score 계산이 이루어져야 한다는 점
- 지표, 날짜, 데모그래픽 조건
- 먼저 선택된 필터에 맞춰 raw data 수집이 이루어져야 함
- 아니면 모든 가능한 조합에 대해 미리 수집을 해놓고 필터 선택에 따라 지표들을 aggregate
- 어떤 대시보드를 사용하느냐에 따라 다름
- 대시보드에서는 A와 B 양쪽에서 아래 3개 정보를 각각 가지고 와서 z-score를 계산
- 샘플 수
- 매출의 합
- 매출 제곱의 합
- 읽어오는 방법은 크게 2가지가 있음 :
- 모든 필터 조합에 대해 미리 계산 (Tableau)
- 동적으로 SQL을 실행해서 계산 (Looker)
- 선택된 필터에 따라 z-score 계산이 이루어져야 한다는 점
4.2 OLAP Cube
- 미리 모든 조합에 대해 계산된 데이터를 OLAP Cube라고 함
- Tableau 사용 시 미리 모든 조합에 대해 데이터를 수집해야 함
- A와 B별로 각 지표에 대해 가능한 모든 date, age, gender 조합에 대해 아래를 미리 계산 :
- 샘플 수
- 매출의 합
- 매출 제곱의 합
- 이를 바탕으로 t-score를 계산
- 장점 : 속도가 빠름 (데이터를 매번 읽어올 필요가 없음)
- 단점 : 필터가 변경될 때마다 데이터 수집 방법도 바뀌어야 함
- OLAP Cube 생성 SQL 예시 :
SELECT
variant_id,
'impression' category,
datestamp,
age,
gender,
count(1) n, -- number of sessions
sum(num_of_items) sum,
sum(num_of_items*num_of_items) sum2 -- square
FROM jyunghye.analytics_variant_user_daily
GROUP BY 1, 2, 3, 4, 5'Data Science > TIL (Today I Learned)' 카테고리의 다른 글
| 프로그래머스 데이터분석 데브코스 1기 - 70일차 (0) | 2024.03.01 |
|---|---|
| 프로그래머스 데이터분석 데브코스 1기 - 69일차 (0) | 2024.02.29 |
| 프로그래머스 데이터분석 데브코스 1기 - 67일차 (1) | 2024.02.27 |
| 프로그래머스 데이터분석 데브코스 1기 - 66일차 (0) | 2024.02.26 |
| 프로그래머스 데이터분석 데브코스 1기 - 65일차 (0) | 2024.02.23 |