파이썬으로 통계 분석하기

Python
Data science
Statistics
T-test
ANOVA
Author

Taeyoon Kim

Published

January 23, 2023

Modified

June 30, 2025

Pingouin간단하지만 완전한 통계 기능를 위해 설계되었습니다. 예를 들어 기존의 SciPy 패키지의 ttest_ind 함수는 T-valuep-value만 알려주지만 Pingouin의 ttest 함수는 T-value, p-value뿐만 아니라 자유도, 효과 크기(Cohen ’s d), 95% 신뢰 구간, 통계적 검정력등을 동시에 출력합니다. 아래의 목록은 할 수 있는 대표적인 분석입니다.

  1. 분산 분석(ANOVAs): N-ways, repeated measures, mixed, ancova
  2. Pairwise 사후 검정(post-hocs tests), pairwise 상관관계
  3. 견고한(Robust), 부분(partial), 거리(distance), 반복 측정 상관관계
  4. 선형(Linear) 회귀, 로지스틱(logistic) 회귀, 매개(mediation) 분석
  5. 베이즈 인자(Bayes factor)
  6. 다변량(Multivariate) 테스트
  7. 신뢰성과 일관성 검정
  8. 효과 크기 및 검정력 분석
  9. 효과 크기 또는 상관 계수의 모수(Parametric) 혹은 부트스트랩(bootstrapped) 신뢰구간
  10. 순환(Circular) 통계
  11. 카이제곱 검정(chi-squared test)
  12. Bland-Altman plot, Q-Q plot, paired plot, robust correlation 시각화

더 자세한 것은 공식 홈페이지를 참고하세요.

1 설치하기

conda install -c conda-forge pingouin

아직 Pingouin은 개발 중에 있으며 버그 수정을 위해 새로운 버전이 계속 배포되고 있습니다(한 달에 약 1 회). 그러니 항상 최신 버전의 Pingouin을 사용하고 있는지 확인하세요. 자세한 내용은 Pingouin 공식 페이지을 참고하세요.

2 예제 살펴보기

먼저 필요한 패키지를 불러옵니다.

import numpy as np
import pingouin as pg

np.random.seed(42)

2.1 One-sample T-test

  • 모집단의 평균은 4로 가정
mu = 4
x = [5.5, 2.4, 6.8, 9.6, 4.2]
pg.ttest(x, mu)

자유도(dof)는 4, T-value(T)는 1.3973 이며 p-Value가 일반적인 기준(0.05) 이상이기 때문에 표본 x의 평균은 모집단의 평균과 차이가 없다(귀무가설)고 볼 수 있다.

2.2 Paired T-test

꼬리를 one-sided로 설정하면 pingouin이 알아서 꼬리의 방향을 알려줍니다. 아래 코드의 경우 T-value가 음수이기 때문에 꼬리의 방향이 less로 표현됩니다.

pre = [5.5, 2.4, 6.8, 9.6, 4.2]
post = [6.4, 3.4, 6.4, 11.0, 4.8]
pg.ttest(pre, post, paired=True, tail="one-sided")

꼬리의 방향이 less라는 것은 표본 x의 평균이 표본 y의 평균보다 작다는 것을 뜻합니다.

일부러 꼬리의 방향을 반대(greater)로 한 대립 가설을 확인해 봅니다.

pg.ttest(pre, post, paired=True, tail="greater")

p-value가 엉망인것을 알 수 있습니다.

2.3 Two-sample T-test

2.3.1 표본 크기가 같은 경우

x = np.random.normal(loc=7, size=20)
y = np.random.normal(loc=4, size=20)
pg.ttest(x, y, correction="auto")

2.3.2 표본 크기가 다른경우

x = np.random.normal(loc=7, size=20)
y = np.random.normal(loc=4, size=15)
pg.ttest(x, y, correction="auto")

2.4 Pearson’s correlation

mean, cov, n = [4, 5], [(1, 0.6), (0.6, 1)], 30
x, y = np.random.multivariate_normal(mean, cov, n).T
pg.corr(x, y)

2.5 Robust correlation

# 표본 x에 아웃라이어 추가
x[5] = 18
# Use the robust Shepherd's pi correlation
pg.corr(x, y, method="shepherd")

2.6 데이터의 정규성 테스트

pingouin.normality()함수를 pandas의 데이터 프레임형식에 사용할 수 있습니다.

# 일변량 정규성(Univariate normality)
pg.normality(x)
# 다변량 정규성(Multivariate normality)
pg.multivariate_normality(np.column_stack((x, y)))

2.7 Q-Q plot 시각화

x = np.random.normal(size=50)
ax = pg.qqplot(x, dist="norm")

2.8 One-way ANOVA

기본 내장되어 있는 데이터프레임(mixed_anova)을 사용합니다.

# Read an example dataset
df = pg.read_dataset("mixed_anova")
df.tail()
# Run the ANOVA
aov = pg.anova(data=df, dv="Scores", between="Group", detailed=True)
aov

2.9 Repeated measures ANOVA

pg.rm_anova(data=df, dv="Scores", within="Time", subject="Subject", detailed=True)

2.10 Post-hoc tests corrected for multiple-comparisons

# FDR-corrected post hocs with Hedges'g effect size
posthoc = pg.pairwise_ttests(
    data=df,
    dv="Scores",
    within="Time",
    subject="Subject",
    parametric=True,
    padjust="fdr_bh",
    effsize="hedges",
)

posthoc

2.11 Two-way mixed ANOVA

# Compute the two-way mixed ANOVA and export to a .csv file
aov = pg.mixed_anova(
    data=df,
    dv="Scores",
    between="Group",
    within="Time",
    subject="Subject",
    correction=False,
    effsize="np2",
)
aov

2.12 Bland-Altman plot

mean, cov = [10, 11], [[1, 0.8], [0.8, 1]]
x, y = np.random.multivariate_normal(mean, cov, 30).T
ax = pg.plot_blandaltman(x, y)

2.13 paired T-test 검정력 시각화

T-검정의 표본 크기와 효과 크기(Cohen’d)에 따른 검정력 곡선을 시각화합니다.

import matplotlib.pyplot as plt
import seaborn as sns

sns.set(style="ticks", context="notebook", font_scale=1.2)
d = 0.5  # Fixed effect size
n = np.arange(5, 80, 5)  # Incrementing sample size
# Compute the achieved power
pwr = pg.power_ttest(d=d, n=n, contrast="paired", tail="two-sided")
plt.plot(n, pwr, "ko-.")
plt.axhline(0.8, color="r", ls=":")
plt.xlabel("Sample size")
plt.ylabel("Power (1 - type II error)")
plt.title("Achieved power of a paired T-test")
sns.despine()

2.14 Paired plot

mixed_anova데이터셋을 가지고 명상이 학교 성적에 미치는 영향에 대한 시각화를 해본다.

df = pg.read_dataset("mixed_anova").query("Group == 'Meditation' and Time != 'January'")

pg.plot_paired(data=df, dv="Scores", within="Time", subject="Subject")

3 마치며

파이썬을 사용한 통계 분석은 R언어에 비해 사용법과 기능이 부족했습니다. 그렇기 때문에 pingouin의 등장이 반갑습니다. 아직 초기 버전이지만 기존에 존재했던 통계 분석 패키지들을 뛰어 넘는 성능과 완성도를 보여주고 있어 앞으로의 발전이 기대 됩니다.