1. 실험 설계
1-1. 샘플 수 및 비율 확인
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.read_csv('final_cookie_cats_for_superset_02.csv')
# 버전별 샘플 수 시각화
sns.countplot(x='version', data=df)
plt.title('Version별 샘플 수')
plt.show()
# 비율 출력
print(df['version'].value_counts(normalize=True))
1-2. 가설 설정 및 t-test 수행 (예: retention_1 기준)
# retention_1: True → 1, False → 0
group_30 = df[df['version'] == 'gate_30']['retention_1'].astype(int)
group_40 = df[df['version'] == 'gate_40']['retention_1'].astype(int)
# 독립표본 t-test
t_stat, p_val = ttest_ind(group_30, group_40)
print(f"t-statistic: {t_stat:.3f}")
print(f"p-value: {p_val:.5f}")
2. 실험 지표 및 메트릭 하이라키
2-1. 핵심 메트릭 및 보조 지표 확인
print(df[metrics].describe())
2-2. 메트릭 하이라키 예시
├── 유지율
│ ├── retention_1
│ └── retention_7
├── 구매 전환
│ ├── purchase_flag
│ └── purchase_amount
└── 사용자 참여도
├── sum_gamerounds
└── engagement_score
3. 사후 분석
3-1. 일자별 유지율 비교
# 일자별 평균 retention_1
daily_ret = df.groupby(['experiment_date', 'version'])['retention_1'].mean().reset_index()
# 시각화
plt.figure(figsize=(12, 5))
sns.lineplot(data=daily_ret, x='experiment_date', y='retention_1', hue='version')
plt.title('일자별 retention_1 비교')
plt.ylabel('Retention Rate')
plt.show()
아래 코드는 실험 날짜(experiment_date)별로 A/B 테스트 그룹(version)에 대해 7일차 유지율(retention_7), 구매 전환율(purchase_flag), 그리고 평균 구매 금액(purchase_amount) 를 각각 계산하여 한 화면에 시각화하는 예시입니다.
참고:
- purchase_flag는 0과 1로 이루어진 이진 변수이므로 평균을 계산하면 구매 전환율(구매한 사용자 비율)이 됩니다.
- 각 지표의 일자별 평균 값을 그룹화하여 비교함으로써, 시간에 따른 성과 변화를 한눈에 파악할 수 있습니다.
import matplotlib.pyplot as plt
import seaborn as sns
# 날짜 컬럼을 datetime 타입으로 변환
df['experiment_date'] = pd.to_datetime(df['experiment_date'])
# 일자별로 A/B 테스트 그룹 별로 7일차 유지율, 구매 전환율, 평균 구매 금액 계산
daily_metrics = df.groupby(['experiment_date', 'version']).agg({
'retention_7': 'mean',
'purchase_flag': 'mean', # 구매 전환율 (구매한 사용자 비율)
'purchase_amount': 'mean'
}).reset_index()
# 시각화를 위한 서브플롯 생성 (세 행, 한 열)
fig, axes = plt.subplots(3, 1, figsize=(12, 15), sharex=True)
# 7일차 유지율 시각화
sns.lineplot(data=daily_metrics, x='experiment_date', y='retention_7', hue='version', ax=axes[0])
axes[0].set_title('일자별 7일차 유지율(retention_7) 비교')
axes[0].set_ylabel('Retention 7 Rate')
# 구매 전환율 시각화
sns.lineplot(data=daily_metrics, x='experiment_date', y='purchase_flag', hue='version', ax=axes[1])
axes[1].set_title('일자별 구매 전환율(purchase_flag) 비교')
axes[1].set_ylabel('Purchase Conversion Rate')
# 평균 구매 금액 시각화
sns.lineplot(data=daily_metrics, x='experiment_date', y='purchase_amount', hue='version', ax=axes[2])
axes[2].set_title('일자별 평균 구매 금액(purchase_amount) 비교')
axes[2].set_ylabel('Average Purchase Amount')
# 레이아웃 조정 및 시각화 출력
plt.tight_layout()
plt.show()
코드 해석
- 데이터 전처리
- df['experiment_date'] = pd.to_datetime(df['experiment_date'])를 통해 날짜 데이터를 datetime 타입으로 변환합니다.
- 그룹화 및 집계
- groupby를 사용해 experiment_date와 version별로 데이터를 그룹화하고, 각 그룹에 대해 retention_7, purchase_flag, purchase_amount의 평균을 계산합니다.
- 시각화
- matplotlib의 서브플롯을 사용해 세 개의 그래프(7일차 유지율, 구매 전환율, 평균 구매 금액)를 한 화면에 배치합니다.
- sns.lineplot을 사용하여 각 지표의 일자별 추세를 A/B 그룹별로 비교합니다.
이와 같이 여러 지표를 종합적으로 시각화하면, 실험 결과에 대한 포괄적인 해석과 A/B 그룹 간 차이를 한눈에 파악할 수 있습니다.
3-2. 세그먼트별 비교 (예: region)
region_group = df.groupby(['region', 'version'])['retention_1'].mean().unstack()
region_group.plot(kind='bar', figsize=(8, 5), title='지역별 retention_1')
plt.ylabel('Retention Rate')
plt.show()

위 그래프는 지역(region)별로 A/B 테스트 그룹(version)의 1일차 유지율(retention_1) 평균을 비교한 결과입니다.
- 가로축은 지역(East, North, South, West)이며,
- 각 지역마다 두 개의 막대(gate_30, gate_40)가 1일차 유지율을 나타냅니다.
그래프 해석
- 모든 지역에서 gate_30(파란 막대)이 gate_40(주황 막대)보다 1일차 유지율이 더 높게 나타납니다.
- 지역별 차이는 있지만, 전반적으로 gate_30이 동일 지역 대비 더 높은 유지율을 기록합니다.
- 예를 들어, East 지역에서 gate_30의 유지율이 약 0.80 수준으로 나타나며, gate_40 은 약0.30 정도로 보입니다(정확한 값은 그래프 축 눈금 참조).
종합적으로, 모든 지역에서 gate_30 버전이 1일차 유지율을 더 높게 이끌어내고 있음을 시사합니다. 이후 다른 지표(7일차 유지율, 구매 전환율 등)와 함께 분석하면 지역별로 더 세밀한 인사이트를 얻을 수 있을 것
3-3. 디바이스별 구매율 비교
device_purchase.plot(kind='bar', figsize=(8, 5), title='디바이스별 구매 전환율')
plt.ylabel('Purchase Rate')
plt.show()
4. 전략 수립 및 Next Step
4-1. 성과 해석 예시 (코드는 없고 참고용)
- gate_40 그룹의 retention_1과 purchase_flag가 유의미하게 높다면:
- 전체 사용자에 대해 gate_40 UI 적용 고려
- 신규 사용자 유입 시 gate_40 버전 우선 적용
- 특정 세그먼트(예: mobile + East region)에서 성과가 좋다면:
- 세그먼트 기반 타겟 마케팅 실행
- 슈퍼셋 필터를 통해 해당 세그먼트를 따로 시각화
데이터 정합성 분석
info(), describe(), isnull().sum(), duplicated().sum() 등을 통해
데이터의 구조, 통계, 결측치 및 중복 여부를 확인
불필요한 컬럼 삭제
A/B 테스트에 필요한 핵심 지표만 남기기 위해 required_columns 리스트에 포함된 컬럼만 선택
분석 목적에 맞지 않는 userid, sum_gamerounds, version_bin, is_gate_40 등은 제거
데이터 타입 변환
experiment_date를 datetime 타입으로 변환하여 시간 관련 분석
(예: 일자별 추세 분석)에 활용
추가 컬럼 생성
is_purchase: purchase_amount가 0보다 크면 구매한 것으로 간주해 1,
아니면 0으로 설정
retention_ratio:
7일차 유지율과 1일차 유지율의 비율을 계산해, 장기 유지 효율을 추가 지표로 생성
engagement_index:
사용자 참여와 실제 구매 전환 여부를 결합해, 구매한 사용자 중 참여도가 높은 경우를 강조하는 지표
최종 데이터 확인
최종적으로 필요한 컬럼만 남기고 추가 컬럼까지 생성한 후 데이터 샘플을 출력하여 전처리 결과를 확인이 목적
데이터 정합성 분석결과
행과 컬럼의 구조
총 90,189개의 행과 19개의 컬럼이 존재
각 컬럼의 데이터 타입이 명확하게 지정되어 있어
(정수, 부동소수점, 불리언, 문자열 등) 데이터가 올바른 형식으로 저장되어 있음 확인
결측치 및 중복 데이터
모든 컬럼에서 결측치가 0으로 나타나, 누락된 데이터가 전혀 없음
중복 행도 0개로 확인되어, 데이터에 중복이 없고 정합성이 높다고 할 수 있다
전처리 및 추가 지표 생성
A/B 테스트 분석에 불필요한 컬럼들을 제거하고,
분석에 핵심적인 컬럼들만 선택하여 데이터의 목적에 맞게 정제함
experiment_date 컬럼을 datetime 형식으로 변환하여 시간 추세 분석에 적합하게
purchase_amount를 기준으로 구매 여부를 나타내는 is_purchase 컬럼을 추가하고,
1일차와 7일차 유지율의 비율(retention_ratio), 그리고 구매와 참여를 결합한 지표
(engagement_index)를 생성하여 후속 분석에 유용한 추가 정보를 제공
현재 분석 목적에 큰 영향을 주지는 않으므로, 이후 작업 시 인덱서를 명시적으로 사용하여 경고를 방지할 수 있습니다.
전체적으로, 데이터의 구조와 내용이 잘 정제되어 있으며 결측치나 중복 데이터 없이 깔끔한 상태임을 확인할 수 있습니다. 이를 바탕으로 A/B 테스트 및 추가 분석 작업을 진행하기에 적합한 데이터임
- cookie_cats_new2.csv(text/csv) - 3272278 bytes, last modified: 2025. 4. 3. - 100% done
Saving cookie_cats_new2.csv to cookie_cats_new2.csv
정합성 분석
컬럼명과 설명 필요없는 컬럼은 삭제예
NO. | 컬럼명 | 설명 |
1 | userid O | 각 사용자를 구분하는 고유 식별자 |
2 | version O | 실험 그룹 (예: "gate_30", "gate_40") |
3 | sum_gamerounds O | 사용자가 플레이한 총 게임 라운드 수 |
4 | retention_1 O | 초기 사용 후 1일 내 재접속 여부 (True/False) |
5 | retention_7 O | 초기 사용 후 7일 내 재접속 여부 (True/False) |
6 | 1일~7일 사이의 재접속 지표 (일부 데이터 누락 가능) | |
7 | days_active 검토 | 사용자가 활동한 총 일수 |
8 | max_level O | 사용자가 도달한 최고 레벨 |
9 | paid_user ▲ 검토 | 유료 구매 여부 (True/False) |
10 | total_revenue ▲ 검토 | 해당 사용자가 발생시킨 총 매출액 |
11 | 튜토리얼을 건너뛰었는지 여부 (True/False) | |
12 | 사용자가 마지막으로 플레이한 날 (일자 또는 기준 일수) | |
13 | 사용자가 도달한 게이트(레벨) 정보 | |
14 | A/B 실험 그룹 (red_yes_button 또는 default_button) | |
15 | 버튼 테스트 후의 활동 일수 | |
16 | activity_time ▲ | 사용자의 활동 시간대 (예: 플레이 시간 등) |
17 | 사용자의 지역 정보 | |
18 | device_type O | 사용자가 이용한 기기 유형 (예: 모바일, 태블릿 등) |
19 | past_behavior_score ▲ | 과거 행동 패턴을 기반으로 산출된 점수 |
20 | log_sum_gamerounds ▲ | 총 게임 라운드 수의 자연로그 값 (정규화 목적) |
21 | engagement_score ▲ | 여러 요소를 종합해 산출한 사용자 참여도 점수 |
22 | 실험 진행 날짜 (YYYY-MM-DD 형식) | |
23 | 구매 여부 (1: 구매, 0: 미구매) | |
24 | 실제 구매 금액 | |
25 | user_survey_score ▲ | 사용자가 설문에 남긴 점수 |
26 | 이상치 제거 후의 총 게임 라운드 수 | |
27 | version_bin ▲ | gate_30인경우 0️⃣version을 이진 값(0 또는 1)으로 변환한 값 |
28 | is_gate_40 ▲ | "gate_40" 그룹 여부 (1: 해당, 0: 미해당) |
29 | retention_total 검토 | 1일 및 7일 재접속 여부를 합산한 총 재접속 횟수 |
세부 파생 컬럼 및 설명
컬럼명 | 설명 | 컬럼 생성 공식/방법 |
is_gate_40 | 사용자가 "gate_40" 그룹에 속하는지 여부 (1: 해당, 0: 미해당) | (df["version"] == "gate_40").astype(int) |
retention_total | 1일과 7일 재접속 여부를 합산 (True=1, False=0) | df["retention_1"].astype(int) + df["retention_7"].astype(int) |
user_survey_score | 사용자 설문 점수 (1~5 사이의 임의 점수) | np.random.randint(1, 6, size=len(df)) |
purchase_flag | 구매 여부 (10% 확률로 1, 90% 확률로 0) | np.random.choice([0, 1], size=len(df), p=[0.9, 0.1]) |
purchase_amount | 구매 금액 (구매 시 5~100 사이의 임의 값, 미구매 시 0) | np.where(df['purchase_flag'] == 1, np.random.uniform(5, 100, size=len(df)), 0) |
experiment_date X 아케이드게임에는 필요없는 컬럼 |
실험 날짜 (2023-01-01 ~ 2023-12-31 사이의 임의 날짜) | pd.to_datetime(np.random.randint(0, num_days, size=len(df)), unit='D', origin=start_date) |
activity_time | 활동 시간 (임의로 선택: morning, afternoon, evening, night) | np.random.choice(['morning', 'afternoon', 'evening', 'night'], size=len(df)) |
region | 사용자 지역 (임의로 선택: North, South, East, West) | np.random.choice(['North', 'South', 'East', 'West'], size=len(df)) |
device_type | 기기 유형 (임의로 선택: mobile, desktop, tablet) | np.random.choice(['mobile', 'desktop', 'tablet'], size=len(df)) |
past_behavior_score | 과거 행동 점수 (1~10 사이의 임의 점수) | np.random.randint(1, 11, size=len(df)) |
log_sum_gamerounds | 로그 변환된 총 게임 라운드 수 (log(sum_gamerounds + 1)) | np.log(df['sum_gamerounds'] + 1) |
engagement_score | 참여 점수 (log_sum_gamerounds와 past_behavior_score의 곱) | df['log_sum_gamerounds'] * df['past_behavior_score'] |
A/B테스트를 하는 방향성 설정 단계
1차 방향성 설정
1. 목표 설정
- 실험 목적: 동일한 게임 버전 내에서 서로 다른 device_type (ex. mobile, tablet, desktop) 유저들의 행동 차이 분석
- 핵심 지표(KPI):
- retention_1 (1일차 재방문율)
- retention_7 (7일차 재방문율)
- sum_gamerounds (게임 라운드 수)
- total_revenue (수익)
- max_level (최고 도달 레벨)
2. 분석 설계
A. 그룹 구분
- 실험 그룹: device_type 값으로 구분 (mobile vs tablet vs desktop)
- 두 가지 방식으로 접근 가능:
- 전체 유저를 device_type 기준으로 분류하여 분석
- 또는 버전별(gate_30, gate_40)로 나눠서 그 안에서 device_type 간의 차이 비교
B. 통계 기법
- 범주형 지표 (retention_1, retention_7):
- 카이제곱 검정 (Chi-Square Test)
- 연속형 지표 (sum_gamerounds, total_revenue, max_level):
- 정규성 만족 시: ANOVA
- 정규성 미만족 시: Kruskal-Wallis 또는 Mann-Whitney U Test (pairwise)
3. 대시보드 구성 방향 (Superset 등 시각화 툴 연동 시)
- 필터: device_type, version
- KPI별 그래프:
- retention_1 & retention_7: 막대그래프 (기기별 재방문율)
- sum_gamerounds, max_level, total_revenue: 박스플롯 or 히스토그램
- conversion funnel: 레벨 도달률 비교 by device_type
4. 분석 인사이트 기대
- 특정 기기에서 더 높은 잔존율 or 수익 창출? → 마케팅 전략 차별화
- 기기별 UI/UX 개선 포인트 도출
다음 단계 추천
- device_type 기준으로 각 KPI의 평균/분포 시각화
- 버전별로 분리하여 기기별 행동 차이 비교
- 통계 검정 수행 후 유의미한 차이 확인
2차 방향성 설정
A/B 테스트 분석 보고서 작성 – 최적의 방향성 설계
1단계: 사후 분석 (Post-hoc Analysis)
1. 분석 목적
- A/B 실험 결과를 일자별, 세그먼트별(device_type 등)로 분석하여 유의미한 행동 차이 및 패턴을 도출하는 것
2. 분석 항목 구성
- 일자별 분석
- 목적: 실험 기간 동안 주요 지표의 변화 추세 확인
- 분석 대상: retention_1, retention_7, sum_gamerounds, total_revenue의 일자별 평균 혹은 분포
- 참고: 데이터에 날짜 컬럼이 없다면 activity_time을 기준으로 대체 가능
- 세그먼트별 분석
- 기준: device_type, version, paid_user, past_behavior_score 등
- 분석 방법:
- 세그먼트별로 주요 지표(잔존율, 수익, 레벨 등) 비교
- 통계 검정 (카이제곱, t-test, ANOVA 등)으로 유의성 판단
- 버전 × 기기 교차 분석
- 목적: 예) gate_30 유저 중 mobile과 desktop 사용자의 반응 차이 비교
- 분석 구조: version과 device_type의 교차 세그먼트를 기준으로 주요 지표 비교
3. 해석 포인트 예시
- 특정 기기에서 retention_1이 유의하게 높다면 해당 기기의 UX/UI가 효과적일 가능성
- tablet 유저는 플레이 시간이 길지만 수익은 낮을 경우 → 광고 기반 수익 모델 제안 가능
- desktop 유저의 max_level이 낮다면 초반 경험(튜토리얼 등) 개선 필요성 제시
2단계: 전략 수립 및 Next Step
1. 전략 수립 기준 – 실험 결과 기반
- 기기별 UX 개선 전략
- mobile: 직관적 UI, 빠른 세션 중심, 푸시 알림 강화
- tablet: 몰입형 콘텐츠 제공, 프리미엄 기능 강화
- desktop: 진입 장벽 낮추기, 튜토리얼 및 안내 강화
- 세그먼트 타겟 마케팅 전략
- retention_7이 높은 세그먼트: 장기 이용 유도 캠페인
- paid_user 전환율이 높은 세그먼트: 혜택 중심 프로모션 강화
- past_behavior_score가 낮은 그룹: 온보딩 및 초기 가이드 강화
- 실험 리디자인 기획
- version과 device_type의 교차 실험 재설계
- 유저 여정 기반 전환 퍼널(funnel) 분석으로 이탈 지점 확인
- 실험 그룹 세분화 후 각 그룹 맞춤 실험 설계
2. Next Step 우선순위
단계 | 실행 항목 | 목적 |
1 | 주요 지표에 대한 통계 검정 및 시각화 | 유의미한 인사이트 도출 |
2 | 세그먼트 별 user persona 설정 | 맞춤 전략 설계 |
3 | funnel 분석 (예: 첫 플레이 → 과금 전환률) | 이탈 지점 및 성장 포인트 파악 |
4 | 후속 실험 설계 (기기별 UI, 콘텐츠 실험 등) | 제품 개선 및 수익화 전략 마련 |
가장 최적의 방향성은
세그먼트별 행동 분석을 기반으로, 기기 특성에 맞는 리텐션 및 과금 전략을 수립하고, 이를 바탕으로 실질적인 비즈니스 성장을 도모할 수 있는 후속 실험을 설계하는 것
5. 클라우드 슈퍼셋 업로드용 저장
df.to_csv('abtest_ready_for_superset.csv', index=False)
'데이터 분석가:Applied Data Analytics > 데이터 시각화' 카테고리의 다른 글
Sankey 차트를 LTV 시각화에 사용하는 이유 (0) | 2025.04.09 |
---|---|
Superset 클라우드 시각화 2nd (0) | 2025.04.04 |
Superset 클라우드 시각화 1st (0) | 2025.04.04 |
클라우드 Superset (0) | 2025.04.03 |
Superset 설치 (0) | 2025.04.02 |