2025. 5. 25. 17:26ㆍData Analysis/분석 방법론
수리통계학에서 배우고 있는 다양한 dist들이
수식과 증명 위주 수업이라 와닿지 않아 학습의 연장선으로
실제 데이터 분석에서의 적용 하는 방법에 대해 고민해보려고 한다.
그래서 그 첫 시작은 Chi-square dist
문제 상황
한 쇼핑몰 앱에서 "구매 버튼 색상"을 바꿨을 때 CTR(클릭률)이 달라지는지를 A/B 테스트를 통해 확인하려고 한다.
Group A: 빨간색 버튼
Group B: 파란색 버튼
버튼을 클릭한 유저 수와 미클릭한 유저 수를 다음과 같은 표로 나타냈다고 해보자.
Group | 클릭 | 미클릭 | 전체 |
A (빨강) | 45 | 55 | 100 |
B (파랑) | 30 | 70 | 100 |
우리는 이 표를 통해 다음 질문에 답을 하는 것이 목표이다.
"버튼 색상과 클릭 여부는 과연 무관한가?
아니면 어떤 색상이 더 클릭을 유도하는가?"
A/B 테스트 개념 복습
카이제곱 분포에 앞서 시나리오에서 가정한 A/B 테스트에 대한 이해를 잠깐 할 필요가 있을 것 같다.
이전 포스팅에서 A/B 테스트 개념을 다룬 적이 있다. 👉 https://semlog.tistory.com/34
그래도 간략하게 요약해보면,
A/B 테스팅이란 유저를 임의로 두 집단으로 나누고,
한 집단에게는 기존 요소(A), 다른 집단에게는 새로운 요소(B)를 도입해,
두 집단의 성과를 측정 비교하여 새로운 요소가 기존 요소에 비해 좋은지를 정량적으로 평가하는 방식을 말한다.
여기서 성과란 새 사이트가 목표로 삼았던 기준에 따라 회원 가입율, 재방문율, 구매전환율 등의 지표를 의미한다.
카이제곱 독립성 검정 이론
카이제곱 독립성 검정은 두 범주형 변수(클릭, 미클릭)가 독립적으로 분포하는지 테스트하는 검정이다.
말이 약간 딱딱하니 바꿔보자.
"버튼 색상과 클릭 여부가 정말 관계 없다면, 어떤 분포가 나타나야 할까?"
이때 등장하는 게 바로 기대빈도(Expected Freq.) 개념이다.
"두 변수가 독립이라면, 빨간 버튼 유저 중 몇명이 클릭했을 것으로 기대되는가?"
"파란 버튼 유저 중 몇 명이 클릭했을 것으로 기대되는가?"
예를 들어, 클릭한 사람의 총합은 45+30 = 75명
빨간 버튼을 본 유저는 총 100명
그럼 빨간 버튼 중 기대되는 클릭 수는:
즉, 실제로는 45명이 클릭했는데, 독립이라고 가정하면 37.5명만 클릭했을 것이라는 이야기
버튼 색상 | 실제 클릭 | 기대 클릭 | 차이 |
빨강 | 45 | 37.5 | +7.5 |
파랑 | 30 | 37.5 | -7.5 |
만약, 기대 빈도와 실제 관측빈도 차이가 크다면
독립이라고 가정한 게 이상하다는 신호가 될 수 있음
그래서 통계적으로 어떻게 판단할까?
이 차이들을 단순히 눈으로 보는 게 아니라, 하나의 숫자로 정량화하는 것이 카이제곱 검정!
즉, 기대와 간측의 차이를 제곱해서 기대로 나눈 값들의 합
→ 차이가 클수록 값이 커짐
정규분포 근사 조건
여기서 중요한 건 이 통계량이 카이제곱 분포를 따른다는 것인데,
아무 때나 그런 건 아니고, 각 셀의 기대빈도가 보통 5 이상으로 충분히 클 때,
표본이 충분히 크다는 전제에서, 정규분포 근사가 가능하고
그에 따라 카이제곱 분포를 이용해 p-value를 계산할 수 있다.
p-value로 결론 내리기
검정 결과, 카이제곱 통계량이 충분히 크다면,
"기대값(=독립 가정)과 관측값 사이에 차이가 크다." → "두 변수는 독립이 아닐 수 있다."
즉, 버튼 색상과 클릭 여부는 관련이 있다는 결론을 낼 수 있다.
Python의 chi2_contingency 라이브러리를 활용한 A/B 테스트 실습
그럼 이제 다시 본론으로 돌아와서 문제 상황을 보자.
한 쇼핑몰 앱에서 "구매 버튼 색상"을 바꿨을 때 CTR(클릭률)이 달라지는지를 A/B 테스트를 통해 확인하려고 한다.
Group A: 빨간색 버튼
Group B: 파란색 버튼
Group | 클릭 | 미클릭 | 전체 |
A (빨강) | 45 | 55 | 100 |
B (파랑) | 30 | 70 | 100 |
표를 기반으로 chi2_contingency 라이브러리를 활용해 검정해보면,
다음과 같은 결과를 얻을 수 있다.
결과 해석
항목 | 결과 |
χ² | 4.1813 |
p-value | 0.0409 |
자유도(df) | 1 |
기대빈도 | [[37.5, 62.5], [37.5, 62.5]] |
결론 | p < 0.05 → 통계적으로 유의미한 차이 존재 |
결과를 하나하나 뜯어보면,
이번 실험 목적은 "버튼 색상 변화가 유저 클릭 행동 여부에 영향을 주는가 검정하는 것" 이다.
각 셀의 기대빈도 ≥ 5 이므로 정규 근사가 가능하고, 카이제곱 통계량을 적용할 수 있고,
p-value 0.0409 < 0.05로 귀무가설을 기각하고, 색상과 클릭 간 관계가 통계적으로 유의미 하다고 판단할 수 있다.
즉, 실제 클릭률은
- 빨강 45%
- 파랑 30%
으로, 빨간 버튼이 클릭률이 더 높기 때문에 빨간 버튼이 더 효과적으로 보는 것이 타당하다.
만약, 실험 설계가 충분히 타당했다면, 유저 전환율 향상을 위해 빨간색을 기본 색상으로 채택할 수 있다.
그렇지만, 클릭 이후의 전환율, 이탈률 등을 함께 분석하여
빨간색 버튼이 시선을 끌지만, 구매까지 이어지지 않을 수 있는 가능성까지 함께 고려해야 한다.
또한, 장기적으로는 미리 설계해둔 로그를 이용해,
연령과 성별, 기기 등에 따른 반응 차이를 확인하는 실험을 함께 진행해볼 수 있을 것이다.
코드
# 필요한 라이브러리 불러오기
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import chi2_contingency
# 데이터 생성: A/B 그룹 클릭 수
data = {
'Group': ['Red Button', 'Blue Button'],
'Clicked': [45, 30],
'Not Clicked': [55, 70]
}
# 데이터프레임 생성
df = pd.DataFrame(data)
df.set_index('Group', inplace=True)
# 분할표 만들기
contingency = df.values
print("Contingency Table:\n", contingency)
# 카이제곱 독립성 검정
chi2, p, dof, expected = chi2_contingency(contingency)
print(f"Chi-squared: {chi2:.4f}")
print(f"p-value: {p:.4f}")
print(f"Degrees of freedom: {dof}")
print(f"Expected frequencies: {expected}")
# 결과 해석
alpha = 0.05
if p < alpha:
print("통계적으로 유의미한 차이 존재 (p < 0.05)")
else:
print("통계적으로 유의미한 차이가 존재 (p >= 0.05)")
# 시각화
click_rate = df['Clicked'] / (df['Clicked'] + df['Not Clicked'])
click_rate.plot(kind='bar',
color=['blue', 'orange'],
title='Click Rates by Group')
plt.ylabel('Click Rate')
plt.xlabel('Group')
plt.ylim(0, 1)
plt.xticks(rotation=0)
# 레이블 표시
for i, v in enumerate(click_rate):
plt.text(i, v + 0.02, f"{v:.2f}", ha='center', va='bottom')
plt.legend(['Click Rate'], loc='upper right')
plt.grid(axis='y', linestyle='--', alpha=0.7)
plt.show()
'Data Analysis > 분석 방법론' 카테고리의 다른 글
KPI란 무엇인가 (0) | 2025.04.05 |
---|---|
A/B 테스트란 (0) | 2024.07.03 |
Data preprocessing (0) | 2024.05.05 |
Data Analysis Overview (0) | 2024.05.05 |