본문 바로가기
Data Analysis/Scipy

1. [Python] T-test

by 베짱이28호 2022. 8. 29.

1. [Python] T-test

 


1. T test

  • 모분산을 알 수 없을 때 사용한다.
    • 전수 조사는 비용, 시간 등 현실적인 문제로 사용하기 어렵다.
    • 모집단에서 표본을 뽑아서 표본 분산을 사용한다.
    • 모분산을 아는 경우에는 z 검정을 사용한다.
  • 가정
    • 독립성 : 표본들이 서로 독립적으로 추출되어야 함 (무작위 표본추출)
    • 정규성 : 데이터와 표본 평균이 정규성을 따라야 함.
    • 등분산성 : 비교하는 집단들의 분산이 동일해야 함
# Shapiro-Wilk 정규성 검정
_, p_value = stats.shapiro(data)
print(f"정규성 검정 p값: {p_value:.4f}")
# P val이 0.05보다 크거나 같아야함... 귀무가설 : 정규분포를 따른다.

 

2. 단일 표본 T test

한 집단의 평균을 검정할 때 사용하는 방법

  • 가설 설정
    • H₀ (귀무가설): μ = μ₀ (표본 평균과 모집단 평균이 같다)
    • H₁ (대립가설): μ ≠ μ₀ (표본 평균과 모집단 평균이 다르다)
import numpy as np
from scipy import stats

# 데이터 및 모집단 평균 정의
scores = np.array([71, 72, 72, 68, 71, 71, 73, 72, 74, 69])
population_mean = 70

# 세 가지 검정 수행
t_stat_two, p_two = stats.ttest_1samp(scores, population_mean, alternative='two-sided')
t_stat_greater, p_greater = stats.ttest_1samp(scores, population_mean, alternative='greater')
t_stat_less, p_less = stats.ttest_1samp(scores, population_mean, alternative='less')

print(f"양측검정 -> t통계량: {t_stat_two:.4f}, p값: {p_two:.4f}")
print(f"단측검정(더 큼) -> t통계량: {t_stat_greater:.4f}, p값: {p_greater:.4f}")
print(f"단측검정(더 작음) -> t통계량: {t_stat_less:.4f}, p값: {p_less:.4f}")


# 출력 
# 양측검정 -> t통계량: 2.3265, p값: 0.0450
# 단측검정(70 up) -> t통계량: 2.3265, p값: 0.0225
# 단측검정(70 down) -> t통계량: 2.3265, p값: 0.9775
  • 양측검정 : 유의수준 95% 하에서 표본평균이 70과 유의미하게 다르다고 주장 가능
  • 단측점정 (70 up) : 유의수준 95% 하에서 표본평균이 70보다 크다고 주장 가능
  • 단측점정 (70 down) : 유의수준 95% 하에서 표본평균이 70보다 작다고 주장 불가

 


3. 독립 표본 T test

서로 독립인 두 집단의 평균을 비교하여 통계적으로 유의한 차이가 있는지 검정.

  • 가설 설정
    • H₀ (귀무가설): μ1 = μ2 (표본 평균과 모집단 평균이 같다)
    • H₁ (대립가설): μ1 ≠ μ2 (표본 평균과 모집단 평균이 다르다)

1. Scipy 코드

import numpy as np
from scipy import stats

# 두 독립된 집단의 데이터
group1 = np.array([75, 78, 72, 74, 77, 76, 79, 73])  # A반 점수
group2 = np.array([68, 65, 70, 71, 67, 69, 72, 83])  # B반 점수

# 기술통계량 계산
print(f"A반 평균: {np.mean(group1):.2f}, 표준편차: {np.std(group1, ddof=1):.2f}")
print(f"B반 평균: {np.mean(group2):.2f}, 표준편차: {np.std(group2, ddof=1):.2f}")

# 등분산성 검정 (Levene's test)
stat, p_levene = stats.levene(group1, group2)
print(f"\n등분산성 검정 p값: {p_levene:.4f}")

# 독립표본 t 검정
t_stat, p_two = stats.ttest_ind(group1, group2, alternative='two-sided')
t_stat, p_greater = stats.ttest_ind(group1, group2, alternative='greater')
t_stat, p_less = stats.ttest_ind(group1, group2, alternative='less')

print(f"\n양측검정 -> t통계량: {t_stat:.4f}, p값: {p_two:.4f}")
print(f"단측검정(group1 > group2) -> t통계량: {t_stat:.4f}, p값: {p_greater:.4f}")
print(f"단측검정(group1 < group2) -> t통계량: {t_stat:.4f}, p값: {p_less:.4f}")

# A반 평균: 75.50, 표준편차: 2.45
# B반 평균: 70.62, 표준편차: 5.48

# 등분산성 검정 p값: 0.3973

# 양측검정 -> t통계량: 2.2987, p값: 0.0374
# 단측검정(group1 > group2) -> t통계량: 2.2987, p값: 0.0187
# 단측검정(group1 < group2) -> t통계량: 2.2987, p값: 0.9813
  • Levene의 등분산성 검정 : p value보다 크거나 같아서 등분산성 만족 
  • 양측검정 : 유의수준 95% 하에서 u1 != u2라고 주장 가능
  • 단측점정 (A>B) : 유의수준 95% 하에서 u1 > u2라고 주장 가능
  • 단측점정 (A<B) : 유의수준 95% 하에서 u1 < u2라고 주장 불가
# 등분산성 위배 시 Welch's t-test 사용
t_stat, p_value = stats.ttest_ind(group1, group2, equal_var=False)
# p val이 0.05보다 작을 때 사용 (귀무가설 : 등분산성을 만족한다)

 

2. Researchpy 코드

import researchpy as rp
import numpy as np
import pandas as pd

# 데이터프레임 생성
group1 = np.array([75, 78, 72, 74, 77, 76, 79, 73])
group2 = np.array([68, 65, 70, 71, 67, 69, 72, 83])

df = pd.DataFrame({
    'scores': np.concatenate([group1, group2]),
    'group': ['A반'] * len(group1) + ['B반'] * len(group2)
})

# 독립표본 t-test 수행
descriptive, results = rp.ttest(group1=df[df['group']=='A반']['scores'],
                              group2=df[df['group']=='B반']['scores'],
                              group1_name='A반',
                              group2_name='B반')

print("기술통계량:")
print(descriptive)
print("\n검정 결과:")
print(results)

기술통계량:
#    Variable     N     Mean        SD        SE  95% Conf.   Interval
# 0        A반   8.0  75.5000  2.449490  0.866025  73.452175  77.547825
# 1        B반   8.0  70.6250  5.475595  1.935915  66.047288  75.202712
# 2  combined  16.0  73.0625  4.809279  1.202320  70.499816  75.625184

# 검정 결과:
#           Independent t-test  results
# 0    Difference (A반 - B반) =    4.8750
# 1      Degrees of freedom =   14.0000
# 2                       t =    2.2987
# 3   Two side test p value =    0.0374
# 4  Difference < 0 p value =    0.9813
# 5  Difference > 0 p value =    0.0187
# 6               Cohen's d =    1.1493
# 7               Hedge's g =    1.0866
# 8          Glass's delta1 =    1.9902
# 9        Point-Biserial r =    0.5235
  • researchpy를 이용하면 양측 검정을 사용할 수 있다.
  • 양측점정 p value 0.0374가 똑같이 나오는 것을 확인할 수 있다.
  • 밑에 4개는 효과 크기이다.
    • Cohen's d (1.1493): 두 집단 간 차이가 매우 큼(>0.8)
    • Hedge's g (1.0866): 작은 표본에서의 보정된 효과크기
    • Glass's delta (1.9902): 통제집단의 표준편차로 표준화한 효과크기
    • Point-Biserial r (0.5235): 두 변수 간의 상관관계 강도

4. 대응 표본 T test

동일한 대상의 전후 측정값을 비교하여 차이가 있는지 검정.

  • 가설 설정
    • H₀ (귀무가설): d = 0 (사전 사후에 차이가 없다)
    • H₁ (대립가설): d != 0( 사전 사후에 차이가 있다)

 

1. Scipy 코드

import numpy as np
from scipy import stats

# 실험 전후 데이터
before = np.array([68, 75, 82, 65, 70, 72, 69, 74])
after = np.array([71, 75, 83, 66, 73, 76, 70, 72])

# 기술통계량
print(f"실험 전 평균: {np.mean(before):.2f}")
print(f"실험 후 평균: {np.mean(after):.2f}")
print(f"평균 차이: {np.mean(after - before):.2f}")

# 대응표본 t 검정
t_stat, p_two = stats.ttest_rel(after, before, alternative='two-sided')
t_stat, p_greater = stats.ttest_rel(after, before, alternative='greater')
t_stat, p_less = stats.ttest_rel(after, before, alternative='less')

print(f"\n양측검정 -> t통계량: {t_stat:.4f}, p값: {p_two:.4f}")
print(f"단측검정(after > before) -> t통계량: {t_stat:.4f}, p값: {p_greater:.4f}")
print(f"단측검정(after < before) -> t통계량: {t_stat:.4f}, p값: {p_less:.4f}")

# 실험 전 평균: 71.88
# 실험 후 평균: 73.25
# 평균 차이: 1.38

# 양측검정 -> t통계량: 2.0228, p값: 0.0828
# 단측검정(after > before) -> t통계량: 2.0228, p값: 0.0414
# 단측검정(after < before) -> t통계량: 2.0228, p값: 0.9586
  • 양측검정 : 유의수준 95% 하에서 d(ua-ub) != 0라고 주장 불가능
  • 단측점정 (after>before) : 유의수준 95% 하에서 u2 > u1라고 주장 가능
  • 단측점정 (after<before) : 유의수준 95% 하에서 u2 < u1라고 주장 불가

'Data Analysis > Scipy' 카테고리의 다른 글

4. [Python] Chi-Square test  (0) 2022.10.08
3. [Python] Time Series Decomposition  (0) 2022.10.02
2. [Python] ANOVA  (0) 2022.09.25

댓글