본문 바로가기

부트캠프/멀티캠퍼스_퍼포먼스 마케팅과 데이터 분석

[멀티캠퍼스 부트캠프 7주차(1)] 데이터 분석 심화_검정의 이해

데이터 분석 심화_검정의 이해



1. 검정을 위한 확률

1) 사건과 확률

 -사건(event): 관측치나 데이터가 특정 조건을 만족시키는 상황

 -확률(probability): 관심있는 사건이 발생할 가능성을 0~1 사이의 숫자로 표현한 값

  • 이론적 확률(Theoretical Probability): 수학적 원리를 기반으로 하는 확률(미래 예측의 의미)
  • 경험적 확률(Empirical Probability): 관찰된 데이터와 실제 결과를 기반으로 하는 확률(과거 빈도의 의미)

2) 조건부 확률과 독립

 -조건부 확률(Conditional Probability): 특정한 조건, 영역에서 계산된 확률

   P(B|A) = P(A∩B) / P(A) 

 -독립(Independece): 서로에게 영향을 미치지 X

   P(B|A) = P(B)

   → 독립인 경우 조건부확률 = 독립인 두 사건이 동시에 발생할 확률 = 두 확률의 곱

        P(A∩B) = P(A)P(B)

 

 

2. 검정의 주요 개념

1) 기술 통계와 추론 통계

 -기술 통계(Descriptive Statistics): 측정한 데이터를 정리, 요약, 시각화하여 특징 파악(현황 파악 등 과거 자체나 현실에 초점)

 -추론 통계(Inferential Statistics): 일부를 선택해서 측정한 결과로 전체 분포 추측(가설 세운 후 통계적 판단 可)

 

2) 정규분포(Normal Distribution)

 -키, 몸무게 등 자연적인 현상들의 분포

 -표준정규분포(Standard Normal Distribution): 평균이 0, 분산이 1인 정규분포 → 서로 다른 분포의 데이터 간 비교 可

 -평균 μ, 분산 σ^2

 

3) 왜도와 첨도

 -왜도(Skewness): 봉우리가 하나인 어떤 분포가 좌우 방향으로 쏠린 정도

  • 왜도 > 0: 최빈값<중앙값<평균
  • 왜도 < 0: 평균<중앙값<최빈값

 -첨도(Kurtosis): 봉우리가 하나인 어떤 분포가 상하 방향으로 뾰족한 정도

 

4) 가설 검정

 -귀무가설(Null Hypothesis, H_0): '차이가 없다/효과가 없다' 처럼 현상 유지를 주장하는 가설(기각의 대상)

 -대립가설(Alternative Hypothesis, H_1): 차이/효과가 있다는 주장

 -가설 검정(Hypothesis Test): 표본 집단에 대한 자료를 가지고 해당 가설이 맞는지 판단하는 과정

 -p-value: 내가 가진 데이터가 귀무가설을 지지하는 정도를 확률로 나타낸 것(데이터와 귀무가설의 차이가 우연일 확률)

 -유의수준(α): 귀무가설이 참인데오 실수로 기각할 허용 최대 확률

  • p-value > α → 귀무가설(H_0) 채택
  • p-value < α → 대립가설(H_1) 채택

5) 양측 검정과 단측 검정

 -단측 검정(One-tailed test): 대립 가설이 효과의 방향을 지정하는 경우

   ex) H_1: 첫 번째 그룹의 평균이 더 크다

 -양측 검정(Two-tailed test): 대립 가설이 효과의 방향을 지정하지 않을 경우

   ex) H_1: 두 그룹의 평균이 다르다

 

6) 검정통계량

 -검정통계량(Test Statistics): 차이, 관계의 정도를 숫자로 표현한 것

 -데이터와 귀무가설 간의 차이를 나타냄

 -p-value를 계산하기 위한 매개변수의 역할

 

 

3. 두 그룹 차이 검정(t 검정)

1) 정규성 검정(Shapiro-Wilk test)

 -데이터가 정규분포를 따르는지 확인

 -H_0: 데이터가 정규분포를 따른다

 → 정규분포가 아니라면 평균 비교가 무의미하므로 윌콕슨 순위합 검정 수행

윌콕슨 순위합 검정(Wilcoxon rank-sum test)

    -데이터가 정규분포를 따르지 않을 때 사용하는 비모수 검정

    -H_0: 두 그룹의 분포가 같다(중앙값에 차이가 없다)

    -두 독립된 그룹의 값들을 순위로 바꾸어, 어느 쪽 그룹의 순위 합이 더 높은지 비교

    -정규성 가정이 깨지거나, 이상치 데이터가 많거나, 표본 수가 적을 때 사용

 

2) 등분산 검정(Bartlett's test)

 -두 그룹의 분산이 같은지 확인

 -H_0: 그룹 간 분산이 같다

 → 분산이 다르다면 Welch's t-test 수행

Welch's t-test

    -정규성은 있지만, 두 그룹의 분산이 다를 때 사용하는 모수 검정

    -H_0: 두 그룹의 평균은 같다

    -각 그룹의 분산을 따로 계산하여 더 엄격하게 비교

 

3) 독립 표본 t-test

 -독립성, 정규성, 등분산성이 만족된 조건 하에 두 그룹 의 평균을 비교하는 모수 검정

 -H_0: 두 그룹의 평균은 같다(μ_x = μ_y)

 -H_1: 두 그룹의 평균은 다르다(μ_x ≠ μ_y)

두 그룹 차이 검정 프로세스와 t 분포

 

 

4. 세 그룹 이상 차이 검정(분산분석)

-분산을 이용하여 여러 그룹별 평균의 차이에 대한 검정(analysis od variance, ANOVA)

1) 정규성 검정(Shapiro-Wilk test)

  → 정규분포가 아니라면 Kruskal-Wallis 검정 수행

 ※Kruskal-Wallis 검정

    -데이터가 정규분포를 따르지 않을 때 사용하는 비모수 검정

    -H_0: 모든 집단의 중앙값(분포)은 같다

 

2) 등분산 검정(Bartlett's test)

  → 분산이 다르다면 Welch's ANOVA 수행

 ※Welch's ANOVA

    -데이터가 정규분포는 따르지만, 그룹 단 분산이 다를 때 사용하는 모수 검정

    -H_0: 모든 집단의 평균은 같다

    -각 집단의 분산 크기에 따라 가중치를 다르게 주어 계산

 

3) 분산분석

 -3개 이상 집단의 평균이 모두 같은지 한 번에 검정하는 모수 검정

 -H_0: 모든 집단의 평균이 같다(μ_1 = μ_2 = ... = μ_k)

 -H_1: 적어도 하나의 평균은 다르다

  → 어느 집단과 어느 집단이 다른지 바로 나오지 X

 -집단 간 변동과 집단 내 변동을 F통계량으로 만들어 비교

 -F = (집단 간 평균제곱) / (집단 내 평균제곱) ~ F(k-1, n-k)

  • 집단 간 변동: 집단 평균들끼리 얼마나 떨어져 있나
  • 집단 내 변동: 같은 집단 안에서 데이터가 얼마나 퍼져 있나

세 그룹 이상 차이 검정 프로세스

 

 

5. 독립성 검정(카이제곱 검정)

1) 범주형 변수의 교차표와 독립성 검정

 -독립성 검정: 두 범주형 변수가 서로 독립인지 판단하는 과정

 -H_0: 두 범주형 변수가 독립

 

2) 독립성 검정과 카이제곱값 계산

 -카이제곱(Chi-Square) 값: 교차표의 각 칸이 귀무가설 기준 예상값보다 전반적으로 얼마나 큰 지 계산

  • X_ij: 첫 번째 변수의 i범주, 두 번째 변수의 j범주 조합에 대한 실제 빈도
  • nhat_ij: 두 변수의 독립을 가정하고 관측치 수 n을 고려한 각 조합의 기대 빈도

 


 

상황별 통계 분석법과 오류

 


 

0. 라이브러리 설치 및 불러오기

-scipy.stats: t-검정, 상관분석, 확률분포 확인에 사용(기초 통계 및 확률 분포)

-statmodels.formula.api.ols: 데이터 간의 관계를 수식으로 정의하고 모델링(회귀 분석)

-statmodels.stats.anova.anoval_lm: 분산분석 및 회귀 모델이 통계적으로 유의미한지 평가

import pandas as pd
import numpy as np

# 그래프 라이브러리
import matplotlib.pyplot as plt
import seaborn as sns

# 통계 관련 라이브러리
from scipy import stats
from statsmodels.formula.api import ols
from statsmodels.stats.anova import anova_lm

# 워닝 무시
import warnings
warnings.filterwarnings('ignore')

 

1. 단일표본 t-검정(One-smaple t-test)

-하나의 집단에 대해 이 집단의 평균이 특정 숫자와 같은지 확인

1) 평균키 단측 검정

 -A대학교 평균키가 174인지, 더 큰지 확인

 -귀무가설: A대학교 평균키는 174와 유의한 차이가 없다

 -대립가설: A대학교 평균키는 174보다 더 크다(단측 검정)

 -stats.ttest_1samp(데이터, 기준값, 옵션)

  • alternative = 'two-sided': 양측 검정(기준값과 다른가?)
  •                      'less': 좌측 단측 검정(기준값보다 작은가?)
  •                      'greater': 우측 단측 검정(기준값보다 큰가?)
df_h = pd.read_csv('../../data/heights.csv')

print(df_h.shape)
df_h.head(3)

# 표본 평균키
print(df_h['son'].mean())
# >>> 174.45753692820037

# 표본 표준편차
print(df_h['son'].std())
# >>> 7.1493420461869
stats.ttest_1samp(df_h['son'], 174, alternative='greater')
# >>> TtestResult(statistic=np.float64(2.1012099902448504), pvalue=np.float64(0.017927222148374937), df=np.int64(1077))

# 깔끔한 ver.
# result = stats.ttest_1samp(df_h['son'], 174, alternative='greater')
# print(result.statistic)  # >>> 2.1012099902448504(t-통계량)
# print(result.pvalue)  # >>> 0.017927222148374937(p-value)
# print(result.df)  # >>> 1077(자유도)

 ※t-통계량

    : 차이(데이터 평균과 기준값의 차이) / 표준오차(데이터가 원래 흔들리는 정도)

     -t-통계량 大 = 그 지점 밖의 꼬리 면적 좁아짐 = p-value 작아짐 = 통계적으로 유의미

     -보통 2를 넘어가면 통계적으로 유의미한 차이일 가능성 高

 ※함수 vs. 속성

     -함수/메서드(.function()): 무언가 동작을 시킬 때 사용

     -속성(.attribute): 이미 계산되어 해당 객체 안에 저장된 값 꺼내올 때 사용

 -통계적 해석: p-value < 0.05 이므로 대립가설 채택 → A대학교 평균키는 174보다 더 크다

 

2) 평균키 양측 검정

 -귀무가설: A대학교 평균키는 174와 유의한 차이가 없다

 -대립가설: A대학교 평균키는 174와 유의한 차이가 있다

stats.ttest_1samp(df_h['son'], 174, alternative='two-sided')
# >>> TtestResult(statistic=np.float64(2.1012099902448504), pvalue=np.float64(0.035854444296749874), df=np.int64(1077))

 -해석: p-value < 0.05 이므로 대립가설 채택 → A대학교 평균키는 174와 유의한 차이가 있다

 

 

2. 독립표본 t-검정(두 그룹 차이 검정)

-두 집단에 대해 서로 상관이 없을 때, 두 집단의 평균이 서로 같은지 확인

1) 가설 정립 및 데이터 분리

 -남자 수학점수와 여자 수학점수의 차이 검정

 -귀무가설: 두 그룹의 점수는 차이가 없다

 -대립가설: 두 그룹의 점수는 차이가 있다(양측 검정)

df_sp = pd.read_csv('../../data/StudentsPerformance.csv')

print(df_sp.shape)
df_sp.head(3)

# 남녀 수학점수 평균
df_sp.groupby('sex')['math score'].mean()
# >>> sex
#     female    63.561886
#     male      68.393305
#     Name: math score, dtype: float64
# 남녀 수학점수 데이터 분리
male_math = df_sp[df_sp['sex'] == 'male']['math score']  # 남자인 조건 중 math score만 가져옴
female_math = df_sp[df_sp['sex'] == 'female']['math score']

male_math  # 시리즈 형태의 데이터

 

2) Shapiro-Wilk 정규성 검정

 -stats.shapiro(데이터): shapiro 정규성 검정(귀무가설: 데이터의 분포가 정규분포와 같다)

stats.shapiro(male_math), stats.shapiro(female_math)
# >>> (ShapiroResult(statistic=np.float64(0.9948297721426106), pvalue=np.float64(0.10925772997767996)),
#      ShapiroResult(statistic=np.float64(0.9923991147460336), pvalue=np.float64(0.010804272932667338)))

 -해석: 남자 수학점수는 p-value > 0.05 이므로 귀무가설 채택 → 정규성 만족

           여자 수학점수는 p-value < 0.05 이므로 귀무가설 기각 → 정규성 불만족

sns.histplot(x=female_math, binwidth=2);

정규분포를 따르지 않는 여자의 수학 점수

 

3) 윌콕슨 순위합 검정(비모수 검정)

 -stats.ranksums(데이터1, 데이터2, 옵션): 윌콕슨 순위합 검정(귀무가설: 두 그룹의 분포가 같다(중앙값에 차이가 없다))

stats.ranksums(male_math, female_math, alternative='two-sided')
# >>> RanksumsResult(statistic=np.float64(4.842485861382294), pvalue=np.float64(1.2822476216088928e-06))

 -해석: p-value < 0.05 이므로 귀무가설 기각 → 두 그룹은 유의한 중앙값 차이가 있다

 

4) 이상치 제거 후 등분산 검정(bartlett test)

# 이상치가 제거된 여성 수학점수
female_math2 = female_math[female_math >= 24]
female_math2

stats.shapiro(female_math2)
# >>> ShapiroResult(statistic=np.float64(0.9958904574988353), pvalue=np.float64(0.21301966474028172))
# 이상치가 제거된 여성 수학 점수는 정규성 만족

 -stat.bertlett(데이터1, 데이터2, ...): 등분산 검정(귀무가설: 두 그룹의 분산이 같다)

stats.bartlett(male_math, female_math2)
# >>> BartlettResult(statistic=np.float64(1.6107537523161348), pvalue=np.float64(0.2043858801252942))

 -해석: p-value > 0.05 이므로 귀무가설 채택 → 등분산 만족 → t-test로 넘어감

 

5) 독립표본 t-test

 -stats.ttest_ind(데이터1, 데이터2, 옵션): 서로 다른 두 집단의 평균 비교(귀무가설: 두 그룹의 평균에는 유의한 차이가 없다)

 -equal_var: 두 집단의 분산이 같은지 여부 설정

  • True(기본값): 두 집단의 분산이 같다고 가정
  • False: 두 집단의 분산이 다르다고 가정(Welch's t-test)

 -non_policy: 데이터 결측치 처리 방법

  • 'propagate'(기본값): 결과로 NaN 반환
  • 'omit': 결측치 무시하고 계산
stats.ttest_ind(male_math, female_math2, alternative='two-sided', equal_var=True)
# >>> TtestResult(statistic=np.float64(4.75146572963073), pvalue=np.float64(2.3212333827714955e-06), df=np.float64(980.0))

 -해석: p-value > 0.05 이므로 귀무가설 채택 → 남자와 여자의 수학 점수에는 유의한 차이가 있다

# 분산이 다를 경우 Welch's t-test 수행
stats.ttest_ind(male_math, female_math2, alternative='two-sided', equal_var=False)
# >>> TtestResult(statistic=np.float64(4.7570061243342465), pvalue=np.float64(2.2598756850962233e-06), df=np.float64(979.9202720718512))

※현실에서는 윌콕슨 검정 후 Welch's t-test를 통해 교차 검증하는 경우 多(CLT와 해석의 용이성 때문)

    서로 결과가 다르다면 윌콕슨 검정 결과를 따라가는 것이원칙

 

 

3. 분산분석(ANOVA, 세 그룹 이상 차이 검정)

1) stats.f_oneway 활용

 ① 가설 설정

df_ins = pd.read_csv('../../data/insurance.csv')

print(df_ins.shape)
df_ins.head(3)

df_ins['ins_type'].unique()
# >>> array(['A', 'B', 'C'], dtype=object)
# 보험타입(ins_type) 별 보험기간(period) 평균
df_ins.groupby('ins_type')['period'].mean()
# >>> ins_type
#     A    5.205543
#     B    4.986253
#     C    5.083592
#     Name: period, dtype: float64
# 상자그림
sns.boxplot(df_ins, y='period', x='ins_type');

  -귀무가설: 그룹 간 차이가 없다

  -대립가설: 적어도 두 그룹은 period 차이가 있다

 

 ② 정규성 검정

# 데이터를 그룹별로 분할
g1 = df_ins[df_ins['ins_type'] == 'A']['period']
g2 = df_ins[df_ins['ins_type'] == 'B']['period']
g3 = df_ins[df_ins['ins_type'] == 'C']['period']
# 정규성 검정(귀무가설 : 데이터가 정규분포를 따른다) 
stats.shapiro(g1), stats.shapiro(g2), stats.shapiro(g3)
# >>> (ShapiroResult(statistic=np.float64(0.9609627280677312), pvalue=np.float64(1.4330273745547826e-09)),
#      ShapiroResult(statistic=np.float64(0.979152137466476), pvalue=np.float64(4.53409450856129e-06)),
#      ShapiroResult(statistic=np.float64(0.993884463720728), pvalue=np.float64(0.06630241192528225)))

   → 정규성 불만족하므로 Kruscal 검정

 

 ③ Kruskal-Wallis 검정(비모수 검정)

  -stats.kruskal(데이터1, 데이터2, ...): 크루스칼-왈리스 검정 수행(귀무가설: 모든 집단은 분포가 같다(중앙값 동일))

stats.kruskal(g1, g2, g3)
# >>> KruskalResult(statistic=np.float64(2.1702378162710483), pvalue=np.float64(0.3378616090120884))

  -해석: p-value > 0.05 이므로 귀무가설 채택 → 그룹 간 중앙값 차이가 없음

 

 ④ 등분산 검정(모수 검정)

   ※앞선 데이터는 정규성을 만족하지 않았지만, 정규성 만족한다고 가정 시

stats.bartlett(g1, g2, g3)
# >>> BartlettResult(statistic=np.float64(2.3844658034005226), pvalue=np.float64(0.3035427257255459))

 

 ⑤ 분산분석

  -독립성, 정규성, 등분산성 만족해야 함

  -stats.f_oneway(데이터1, 데이터2, ...): 일원 분산 분석 수행

stats.f_oneway(g1, g2, g3) 
# >>> F_onewayResult(statistic=np.float64(1.3640782415863413), pvalue=np.float64(0.25596826874927986))

  -해석: p-value > 0.05 이므로 귀무가설 채택 → 그룹 간 평균 차이가 없음

 

2) anova_lm 활용

 -독립성, 정규성, 등분산성 만족해야 함

 -반드시 선형 모델을 먼저 만든 뒤 해당 모델을 바탕으로 결과 뽑아냄

 -데이터 분리 필요 없는 간편한 방법

 -ols("종속변수 ~ C(독립변수)", 데이터프레임).fit(): 선형 회귀 모델 만듦

   ※C()를 써줘야 숫자로 된 범주(ex. 1번 집단, 2번 집단) 제대로 파악 가능

   ※종속변수에 띄어쓰기가 있는 경우 Q(종속변수) 사용해야 제대로 인식

 -anova_lm(모델): 집단 간 평균 차이가 통계적으로 유의한지 보여주는 ANOVA 테이블 생성 함수

  scipy.stats.f_oneway() statmodels.stats.anova.anova_lm
입력 형태 리스트나 배열을 낱개로 전달 데이터프레임+회귀 모델 결과물 전달
결과값 F-통계량, p-value ANOVA Table(자유도, 제곱합, F값, p값)
확장성 일원 분석(One-way)만 가능 이원(Two-way) 이상, 상호작용 분석 가능
data = ols("period ~ C(ins_type)", df_ins).fit()
anova_lm(data)

 -해석: p-value(0.255968) > 0.05 이므로 귀무가설 채택 → 그룹 간 평균 차이가 없음

 

 

4. 독립성 검정(카이제곱 검정)

-성별(남, 여)과 흡연 여부(Yes, No)는 서로 독립인가?

-귀무가설: 성별과 흡연 여부는 독립이다

-대립가설: 성별과 흡연 여부는 독립이 아니다

-stats.chi2_contingency(교차표): 두 범주형 변수 사이에 관계가 있는지 확인

# 교차표 생성
ct = pd.crosstab(df_ins['sex'], df_ins['smoker'])
ct

# 독립성 검정
stats.chi2_contingency(ct)
# >>> Chi2ContingencyResult(statistic=np.float64(9.61426576423706), pvalue=np.float64(0.0019307163989584425),
#     dof=1, expected_freq=array([[525.2195122, 140.7804878], [541.7804878, 145.2195122]]))

-해석: p-value < 0.05 이므로 귀무가설 기각 → 성별과 흡연 여부는 독립이 아니다

※expected_freq: 독립을 가정한 교차표

 


 

#부트캠프후기 #멀티캠퍼스부트캠프 # 데이터마케팅부트캠프