2 분 소요

두 평균의 비교 Preview

  • 두 평균의 비교는 실무에서 자주 쓰이는 테스트이기 때문에 잘 배우도록 합니다.
  • 하나의 모수에 대해 두 그룹의 값이 같은지 검정하는 것
    • 만약 가정을 충족하면 Independent Sample T - Test
    • 가정을 충족하지 못하면 Mann-Whitney Test를 사용한다.

데이터 불러오기

  • 데이터를 불러오도록 한다.
  • 데이터는 각 tutor의 클래스별 학생들의 점수를 나열한 것이다.
    • Anastasia(N = 15) & Bernadette(N = 18)
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/ethanweed/pythonbook/main/Data/harpo.csv")

데이터 요약

  • 각 클래스 학생들의 데이터 분포 요약을 진행한다.
import numpy as np
df.groupby('tutor')['grade'].agg(['mean', 'std', 'count']).reset_index()

두 그룹 간 데이터 시각화

  • 두 그룹 간의 비교 그래프를 작성한다.

히스토그램

import matplotlib.pyplot as plt
import seaborn as sns

fig, axes = plt.subplots(1, 2, figsize = (15, 5))
Anastasia = pd.DataFrame(df.loc[df['tutor'] == 'Anastasia']['grade'])
Bernadette = pd.DataFrame(df.loc[df['tutor'] == 'Bernadette']['grade'])

sns.histplot(Anastasia['grade'], ax = axes[0], binwidth = 5)
sns.histplot(Bernadette['grade'], ax = axes[1], binwidth = 5)

axes[0].set_xlim(50, 100)
axes[1].set_xlim(50, 100)

axes[0].set_ylim(0, 7)
axes[1].set_ylim(0, 7)

axes[0].set_title('Anastasis')
axes[1].set_title('Bernadette')

sns.despine() # 그래프의 오른쪽과 상단의 spine을 제거하는 함수입니다.
plt.show()

두평균)

  • 위 두 개의 그래프를 통해 알 수 있는 건 Anastasia의 점수의 분포가 Bernadette 분포보다 높게 나온다는 것입니다.

pointplot()

  • 두 그룹의 학생에 대한 평균과 해당 신뢰 구간을 보여준다.
sns.pointplot(x = 'tutor', y = 'grade', data = df)
sns.despine()

두평균1

두 개의 검정

  • Student’s T-Test
    • 모수 검정: 엄격한 가정 적용
  • Welch’s
    • 비모수 검정: 가정에 대해 유연함

가정

  • 독립된 관측치 (Independent Observations)
    • 두 그룹의 관측값은 서로 특별한 관계가 없다.
  • 정규성(Nomality)
    • 정규 분포를 따른다. 만약 Sample Size가 N > 30 이면 고려하지 않아도 됨
  • 등분산성 가정
    • Levene’s 검정

가설

  • 귀무가설: 두 그룹의 평균은 같다.
  • 대립가설: 두 그룹의 평균은 다르다.
  • 이를 시각적으로 표현하면 아래와 같이 표현한다.
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import scipy.stats as stats

mu1 = 0
sigma = 1
mu2 = 2

x1 = np.linspace(mu1 - 4 * sigma, mu1 + 4 * sigma, 100)
y1 = 100 * stats.norm.pdf(x1, mu1, sigma)
x2 = np.linspace(mu2 - 4 * sigma, mu2 + 4 * sigma, 100)
y2 = 100 * stats.norm.pdf(x2, mu2, sigma)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize = (15, 5))

sns.lineplot(x = x1, y = y1, color = 'black', ax = ax1)

sns.lineplot(x = x1, y = y1, color = 'black', ax = ax2)
sns.lineplot(x = x2, y= y2, color = 'black', ax = ax2)

ax1.text(0, 43, 'null hypothesis', size = 20, ha = 'center')
ax2.text(0, 43, 'alternative hypothesis', size = 20, ha = 'center')

ax1.set_frame_on(False)
ax2.set_frame_on(False)
ax1.get_yaxis().set_visible(False)
ax2.get_yaxis().set_visible(False)
ax1.get_xaxis().set_visible(False)
ax2.get_xaxis().set_visible(False)
ax1.axhline(y = 0, color = 'black')
ax2.axhline(y = 0, color = 'black')

plt.show()

두평균2

  • 수식으로 풀어쓰면 다음과 같다.
  • 만약 귀무가설이 맞다면 두 그룹 간의 평균 차이는 0이다.
    • mu1 - mu2 = 0
  • 그러나, 만약 약간의 차이가 있다면 이를 어떻게 봐야할까?
    • 이것을 일반적으로 오차라 부르고, t 통계량을 구할 때는 표준오차를 사용한다.

데이터 가공

  • 기존 데이터의 Long 형태의 테이블에서 Wide 형태의 테이블로 변경해야 한다.
wide_df = pd.pivot(df, columns = 'tutor', values = 'grade')
wide_df.head()

두평균3

테스트

  • NaN은 숫자가 아님의 약자이다.
  • 별도로 처리해야 하지만, ttest()는 이를 적절하게 처리할 수 있는 기능이 있다.
from pingouin import ttest
ttest(wide_df['Anastasia'], wide_df['Bernadette'], correction = False)

두평균4

  • correction = False 가 의미하는 것은 실제로 indepenent t-test 를 수행하라는 말이다.
  • 결과 보고서는 아래와 같이 작성할 수 있다.
    • Anastasia’s 클래스의 평균 점수는 74.5점이고 (std dev = 9.0), 반면에 Bernadette 클래스의 평균 점수는 69.1이고 (std dev = 5.8)이다.
    • 독립 평균 샘플 t-test의 결과 약 5.4 점의 차이가 유의미하게 다르게 나타난다.(t(31) = 2.1, p < 0.05)

댓글남기기