A/B 테스트로 알아보는 카이제곱 분포

A/B 테스트로 알아보는 카이제곱 분포

2025. 5. 25. 17:26Data 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