데이터 분석 TIL - 가설검정(t-검정, z검정, 카이제곱)과 연속형/범주형 변수의 상관관계

테리·5일 전

1. 학습 키워드

  • 가설 검정의 종류
  • 상황에 따라 다르게 사용하는 검정 방법
  • 연속형 변수와 범주형 변수의 상관관계 구하는 함수

2. 학습 내용

가설을 검정하는 방법은 여러가지가 있다. 연속형 데이터를 비교할 때, 범주형 데이터를 비교할 때 사용하는 검정의 방법이 다르며 비교하고자 하는 집단의 수에 따라서도 다른 검정 방법을 사용한다.

  • t-검정
  • 두비율 검정
  • 카이제곱 독립성 검정

위 세가지의 검정 방법은 실제 업무 상황에서 자주 마주칠 수 있는 검정 방법으로 각각의 사용 상황을 명확히 아는 것이 필요하다.

신뢰구간 vs 가설검정

신뢰구간

모집단의 특성(평균, 비율 등)이 포함될 것으로 ‘신뢰’하는 값의 범위

  • 표본을 통해 추정한 값을 중심으로, 오차 범위를 더해 추정값 ± 신뢰한계로 표현
  • 일반적으로 95% 신뢰수준 사용 → 반복 측정 시 95%는 참값을 포함한다. (빈도주의 관점)

가설검정

차이가 의미가 있는지 판단하기 위한 절차

  • 가설 설정 후 p-value를 기준으로 유의 수준과 비교해 검증하고자 하는 가설이 우연인지 아닌지 판단

t-검정(두 집단의 평균이 다르냐?)

두 집단의 평균이 통계적으로 유의하게 서로 다르냐?를 확인할 때 사용함. 그렇기에 주로 연속형 변수를 다룰 때 사용된다.

  • 모집단이 정규분포를 따른다는 가정을 바탕으로 진행하는 검정
  • 단일표본 t검정(한 집단의 평균이 기준값과 다른지 확인)과 독립표본 t검정이 있지만 t-검정에서 독립표본 t검정(서로 독립된 두 집단의 평균 차이 비교)은 자주 사용된다.

⭐️독립표본 t검정
ex) A/B 테스트 이후 t검정 사용
ex) 남학생과 여학생의 평균 키가 다른가?

  • 귀무가설 : 두 집단의 평균은 같다.
  • 대립가설 : 두 집단의 평균은 다르다.

더 구체적인 A/B 테스트 예시를 살펴보자

  • A/B 각각 500명 대상으로 실험
  • A 평균 구매금액 = 20,000원
  • B 평균 구매금액 = 21,000원
    → 차이 1000원이 우연인가? 진짜 유의미한 효과인가?
  1. 가설 설정
가설의미
H₀(귀무가설): μA = μBA/B의 실제 평균에는 차이가 없다
H₁(대립가설): μA ≠ μB두 집단의 평균은 다르다 (효과가 있다)
  1. 관측된 차이: 신호(signal)
    • XˉBXˉA\bar{X}_B - \bar{X}_A = 평균 차이
  2. 데이터의 흔들림: 잡음(noise) = 표준오차(SE)
    • 데이터가 변동이 크면(SE↑) → 차이가 우연처럼 보임
    • 표본 수가 많고 변동이 적으면(SE↓) → 차이가 뚜렷해 보임
    • SE = “H₀가 참일 때 평균차가 어느 정도 흔들릴지”를 나타내는 값
  3. t값 = 신호/잡음 비율 계산
  4. t값에서의 p-value 계산 및 유의성 확인
    • 설정한 유의성(0.05)보다 작으면 대립가설 채택, 크면 귀무가설 채택
  5. 최종결론
    "B안이 A안보다 평균 구매금액이 약 1,000원 높으며, 이는 통계적으로 유의미한 차이입니다(p < 0.05). 우연에 의한 결과일 확률은 매우 낮습니다.”

여기에서 t-검정은 모수 검정에 속한다.
모수 검정이란 모집단이 정규 분포를 따른다는 가정을 바탕으로 진행하는 통계 검정이다. 그렇기 때문에 표본의 모양을 보고 정규분포 모양인지를 확인하며 정규성을 따르는지 확인해야한다. 정규분포 모양이면 t-검정을 그렇지 않으면 비모수 검정을 진행해야한다.

정규성과 등분산성 확인

데이터수가 30개 이하일 경우에는 데이터가 정규성을 따르는지 등분산성을 따르는지 확인해봐야함.

  • Q-Q플랏: 정규성을 검정하는 방법중 하나.
  • 히스토그램 확인: 종모양인가?

비모수 검정

  • 모집단을 분포를 모를때, 정규분포를 가정할 수 없을 때, 정규분포를 가정하지 않아도 사용할 수 있음.
  • 극단값이 많은 경우, 좌우 비대칭 분포인 경우, 표본 수가 너무 작은 경우
    -> 분포 전체를 가정할 수 없다면, 데이터의 '위치'에 집중해서 검정함. (평균 대신 순위, 중앙값 등 분포의 위치에 주목함)

데이터의 크기(순위)를 보고 비교함. '평균이 다르다' 처럼 두 집단이 다른지 여부를 검정하는 것임.

지금까지는 두개의 집단의 차이를 비교하고 검정하는 방법이었다. 그렇다면 3개 이상의 집단을 비교 검정할때는 어떤 방법을 사용할까? 이럴때 ANOVA를 사용한다.

분산분석 (ANOVA: Analysis of Variance)

  • 3개 이상 집단의 평균 차이를 비교하는 검정 방법 (t검정의 확장 형태)⭐️
  • 한 번의 검정으로 모든 집단 간 평균 차이 유무를 판단
  • 집단 간 변동이 크고 집단 내 변동이 작다면 집단 간 평균에 차이가 있다고 판단
  • 전제조건: 정규성, 등분산성 + 독립성(각 집단의 데이터는 서로 독립적이어야 함)
  • 가설
    • 귀무가설(H₀) : 모든 집단의 평균이 같다
    • 대립가설(H₁) : 적어도 하나의 집단 평균은 다르다

연속형 변수 속에서 집단간 평균의 차이를 기준으로 통계적으로 유의하다고 판단하는 대표적인 검정 방법은 t-검정이다. 하지만 데이터는 항상 연속형 데이터만 있는 것이 아니라 범주형 데이터도 있다. 이러한 경우에는 범주형 변수를 검정하는 방법을 사용해야 한다.

범주형 변수(수치가 아니라 label로 구분되는 변수)

범주형 데이터를 분석하는 방법은 두가지가 있다.

  1. 숫자로 변환해 비율, 빈도를 비교하는 방식(ex 구매율, 클릭율, 불량률, 에러 횟수 등)
  2. 범주 자체의 분포나 관계를 비교하는 방식

1. 범주형 변수의 비율에 대한 가설 검정 -> Z검정 for proportions (두 비율 검정) ⭐️

두 개 집단의 비율 차이가 통계적으로 유의한지 비교할 때 사용
(t 검정은 연속형 변수에서 정규분포를 따른다고 가정할때 사용하지만 두 비율 검정은 범주형에서 집단간의 비율 차이를 활용함)

  • 사용 조건
    • 두 집단의 성공 비율 비교 (전환율, 클릭률, 구매율 등)
    • 표본 수가 충분히 클 때 (일반적으로 n ≥ 30)

실무 A/B테스트에서 거의 항상 쓰는 기본 검정

범주형 변수 간 관계에 대한 가설 검정 -> 카이제곱 검정

카이제곱 독립성 검정 (Test of Independence) ⭐️⭐️

두 범주형 변수 간에 관련이 있는지(독립인지)를 검정할 때 사용

행과 열로 이루어진 교차표로 표현 가능한 두 범주형 변수의 관계를 파악할 때 사용함.

  • 성별에 따른 구매여부의 관계를 파악할 때
  • p ≈ 0.03 < 0.05 → 귀무가설 기각
  • 성별에 따라 구매 여부가 달라진다고 볼 만한 증거가 있다고 해석할 수 있다!

검정방법 정리

질문 유형예시검정 방법귀무가설(H₀)
한 집단의 비율이 기준과 다른가?“구매율이 50%보다 높은가?”이항검정 (Binomial test)비율 = 기준값
두 집단의 비율이 다른가?“A/B 집단 클릭률이 다른가?”Z검정 for proportions두 집단의 비율이 같다
여러 범주의 관측 비율이 기대 비율과 다른가?“A/B/C 메뉴 선호 비율이 같을까?카이제곱 적합도 검정관측 비율 = 기대 비율
두 범주형 변수가 서로 관련 있는가?“성별과 구매 여부가 관련 있나?”카이제곱 독립성 검정두 변수는 독립이다

검정을 위한 파이썬 코드 사용

정규성 확인(히스토그램, Q-Q 플랏)

from scipy import stats
import matplotlib.pyplot as plt
import seaborn as sns

# histplot 그려보기
sns.histplot(data, kde=True) # sns.histplot(df['purchase_amount'], kde=True)

# Q-Q plot 그려보기
stats.probplot(data, plot=plt) # stats.probplot(df['price'], plot=plt)
plt.show()

t-검정(ttest_ind): 두 집단의 평균 비교

from scipy import stats

# 독립표본 t-test (등분산 가정)
t, p = stats.ttest_ind(a, b, equal_var = True)

# Welch t-test (등분산성 위반시)
t, p = stats.ttest_ind(a, b, equal_var = False)

Z 검정(두 비율 검정) - 두 집단 비율 비교

from statsmodels.stats.proportion import proportions_ztest
import numpy as np

count = np.array([A의성공수, B의성공수])
nobs = np.array([A의전체수, B의전체수])

stats, p = proportions_ztest(count, nobs)

카이제곱 독립성 검정 - 두 집단관 관련 여부

import pandas as pd
from scipy.stats import chi2_contingency

contingency = pd.crosstab(category1, category2) # pd.crosstab(df['gender'], df['purchase'])
chi2, p, dof, expected = stats.chi2_contingency(contingency)

이동평균, 누적합 파이썬 함수 실습 정리

이동평균 -> rolling()

이동평균: n번째 데이터를 포함한 이전날짜 m개의 데이터의 산술평균

rolling() 메서드에서 center 파라미터 설정

center=True 이면 해당 행을 중심으로 이전 이후의 행을 모두 고려해 윈도우 크기의 개수만큼 확보되면 해당 행부터 결과값을 보여줌. 이때 오른쪽 값을 포함할지 왼쪽 값을 포함할지는 closed 파라미터로 결정할 수 있음.

closed='left' 라고 했으므로 왼쪽을 포함하고 오른쪽을 포함하지 않는다. 즉 3번째 행은 자기 자신을 포함시키지 못해 출력을 못하며, 4번째 행에서 자기 자신의 값인 1018을 포함하지 못하고 그 이전의 개수가 3개일때부터 출력이 사작됨.

sum()을 사용하면 누적 합계가 된다.

expanding

처음부터 누적 합, 누적 평균 계산

연속형 변수와 이산형 변수의 상관관계: stats.pointbiserialr()

각 범주형 변수 확인

# Point-Biserial Correlation
# 연속형 변수와 이분형 범주형 변수에 대한 상관관계 구하기 
r, p_value = stats.pointbiserialr(mdf['sales_channel_id'], mdf['price'])
r, p_value

# r = 0.17 로 상관관계가 높지 않음
# p-value 가 0.05 보다 작으므로, 이는 통계적으로 신뢰를 가지고 판단할 수 있음 

범주형 집단간 평균의 차이를 비교: ANOVA

각 카테고리별 price의 Series값이 groups에 들어가있음. 따라서 총 3개의 집단(카테고리)간 평균의 차이를 비교하게 됨.

범주형 변수가 3개 이상인 경우: Cramer' V

  • 라벨 인코딩을 해서 범주형 변수를 숫자로 변환한다.
  • Cramer' V 함수를 만든다.
  • 혼동행렬(상관관계)를 구한다.
  • 그러면 범주형 변수가 3개 이상인 컬럼과의 컬럼간 상관계수를 확인할 수 있음.
# step 02-03.함수 정의 및 혼동행렬 생성(define a function and make a confusion matrix)

def cramers_V(var1,var2) :
    crosstab =np.array(pd.crosstab(var1,var2, rownames=None, colnames=None)) # Cross table building
    stat = chi2_contingency(crosstab)[0] # Keeping of the test statistic of the Chi2 test
    obs = np.sum(crosstab) # Number of observations
    phi2 = stat / obs
    r, k = crosstab.shape
    phi2corr = max(0, phi2 - (((k-1)*(r-1))/(obs - 1)))
    rcorr = r - ((r-1)**2)/(obs-1)
    kcorr = k - ((k-1)**2)/(obs-1)
    return np.sqrt(phi2corr / min((kcorr-1), (rcorr-1)))

rows= []

for var1 in data_encoded:
    col = []
    for var2 in data_encoded :
        cramers =cramers_V(data_encoded[var1], data_encoded[var2]) # Cramer's V test
        col.append(round(cramers,2)) # Keeping of the rounded value of the Cramer's V  
    rows.append(col)
cramers_results = np.array(rows)
data_encoded_df = pd.DataFrame(cramers_results, columns = data_encoded.columns, index =data_encoded.columns)

data_encoded_df

3. 배운점

  1. t-검정, z검정(두 비율 검정), 카이제곱 독립성 검정에 대해 알 수 있었다. 다소 모호하고 어떠한 상황에서 사용해야 하는지 잘 몰랐는데 블로그에 정리해보면서 조금 더 명확하게 알 수 있었다. 나중에 사용하게 될 일이 있을 때 이 글을 다시 참고해 보면 좋을 것 같다.

  2. 숫자로된 연속형 변수간의 상관관계 밖에 구하는 방법을 몰랐는데 범주형 변수와의 상관관계를 구하는 방법을 정리할 수 있었다. 이 내용 또한 필요할 때 찾아서 사용하면 좋을 것 같다.

0개의 댓글