통계 분석은(는) 무엇을 하나요?
개요
가설 검정(t-검정, ANOVA, 카이제곱), 회귀 분석, 상관 분석 및 베이지안 분석을 체계적인 가정 확인, 효과 크기 계산, APA 스타일 보고와 함께 수행합니다. 목표는 검토자가 흠잡을 수 없는 분석 결과를 제공하는 것입니다: 올바른 검정, 검증된 가정, 정직한 효과 크기, 그리고 완전한 보고서.
이 스킬을 사용해야 하는 경우
다음과 같은 상황에서 이 스킬을 사용하세요:
- 통계적 가설 검정 수행 (t-검정, ANOVA, 카이제곱, 비모수 검정)
- 회귀 또는 상관 분석 수행
- 베이지안 통계 분석 수행
- 통계적 가정 및 진단 확인
- 효과 크기 계산 및 검정력 분석 수행
- APA 형식으로 통계 결과 보고
- 실험 또는 관찰 데이터 분석
설치
uv를 사용하여 이 스킬에서 사용하는 라이브러리를 설치하세요. 프로덕션에서는 버전을 고정하고, 탐색용으로는 고정하지 않은 설치도 괜찮습니다.
# 핵심 빈도주의 스택 (Python 3.10+; 최신 SciPy/ArviZ 사용 시 3.12+ 권장)
uv pip install "pingouin>=0.6" "scipy>=1.11" "statsmodels>=0.14.6" pandas matplotlib seaborn
# 베이지안 모델링 (PyMC 5 + ArviZ)
uv pip install "pymc>=5.0" "arviz>=1.0"
호환성 참고 사항 (pingouin 0.6.1, statsmodels 0.14.6, arviz 1.2 기준, 2026년):
- Pingouin 0.6.0에서 출력 열 이름이 변경되어 특수 문자가 제거되었습니다:
p_val,cohen_d,CI95,p_unc(이전 0.5.x에서는p-val,cohen-d,CI95%,p-unc). 아래 예제는 현재 이름을 사용합니다. 0.5.x에 머물러 있다면 하이픈 형태를 사용하세요. - statsmodels + SciPy: SciPy 1.16+에서 발생하는
_lazywhere가져오기 오류를 피하려면statsmodels>=0.14.6과scipy>=1.11을 사용하세요. - ArviZ 1.x:
az.summary()는 기본적으로 89% 구간(eti89열)을 사용하며 너비 매개변수는ci_prob입니다 (hdi_prob가 아님). 일반적인 95% 신뢰 구간을 보고하려면az.summary(trace, ci_prob=0.95)를 전달하세요. - 단측 베이즈 요인(Bayes Factor)은 Pingouin에서 제거됨:
pg.ttest(..., alternative='greater')는BF10열을 자동으로 제거하고,pg.bayesfactor_ttest는 단측 대안에서 오류를 발생시킵니다. 단측 베이지안 검정이 필요하면 PyMC를 직접 사용하거나(방향성 가설의 사후 확률 계산) JASP/R의 BayesFactor를 사용하세요.
모델별 API(OLS, GLM, ARIMA)에 대해서는 statsmodels 스킬을 참조하세요. PyMC 워크플로우에 대해서는 pymc 스킬을 참조하세요.
분석 워크플로우
모든 건전한 분석은 동일한 절차를 따릅니다. 단계를 건너뛰면 분석 결과가 철회될 수 있으므로 순서대로 작업하고 각 단계에서 수행한 작업을 설명하세요.
- 데이터를 보기 전에 질문을 명확히 하세요. 가설, 결과 및 예측 변수, 설계(독립 vs. 대응, 그룹 수)를 명시하세요. 지금 계획된 검정을 확정하세요 — 결과를 보고 검정을 선택하는 것은 무해한 의도라 할지라도 p-해킹(p-hacking)입니다.
- 데이터를 검사하세요. 각 그룹별: n, 평균, 표준편차(SD), 중앙값, 결측값 수. 검정 전에 원시 데이터를 히스토그램 또는 상자 그림으로 그리세요. 그룹 크기 불균형, 결측값, 바닥/천장 효과, 이상치는 모두 적절한 검정을 변경시킵니다 — 이를 조용히 우회하지 말고 사용자에게 표면화하세요.
- 아래 빠른 참조 또는
references/test_selection_guide.md를 사용하여 검정을 선택하세요 (기본 설계(카운트, 생존 시간, 신뢰도, 요인 설계)를 넘어서는 경우). scripts/assumption_checks.py로 가정을 확인하세요. 가정이 위반되면 수정 검정(아래 표)으로 전환하고 계획과 변경 사항을 모두 보고하세요.- 검정을 실행하고 항상 효과 크기를 함께 계산하세요 — p-값은 효과의 존재를 나타내고, 효과 크기는 누군가가 신경 써야 할지 여부를 알려줍니다.
- 아래 APA 템플릿을 사용하여 보고하세요. 기술 통계, 정확한 통계량, 신뢰 구간이 포함된 효과 크기, 수행된 가정 확인을 포함하세요.
사용자가 한 단계만 필요하다면(예: "몇 명의 참가자가 필요합니까?") 해당 섹션으로 바로 이동하세요 — 그래도 계산의 기반이 되는 설계 가정을 확인하세요.
검정 선택 가이드
빠른 참조: 올바른 검정 선택
포괄적인 지침(카운트, 생존, 신뢰도, 요인 설계)은 references/test_selection_guide.md를 사용하세요. 빠른 참조:
두 그룹 비교:
- 독립적, 연속형, 정규 분포 → 독립 표본 t-검정
- 독립적, 연속형, 비정규 분포 → Mann-Whitney U 검정
- 대응, 연속형, 정규 분포 → 대응 표본 t-검정
- 대응, 연속형, 비정규 분포 → Wilcoxon 부호 순위 검정
- 이분형 결과 → 카이제곱 검정 또는 Fisher의 정확 검정
3개 이상 그룹 비교:
- 독립적, 연속형, 정규 분포 → 일원 ANOVA
- 독립적, 연속형, 비정규 분포 → Kruskal-Wallis 검정
- 대응, 연속형, 정규 분포 → 반복 측정 ANOVA
- 대응, 연속형, 비정규 분포 → Friedman 검정
관계:
- 두 연속형 변수 → Pearson 상관(정규 분포) 또는 Spearman 상관(비정규 분포)
- 연속형 결과와 예측 변수 → 선형 회귀
- 이분형 결과와 예측 변수 → 로지스틱 회귀
베이지안 대안:
모든 검정에는 가설에 대한 직접적인 확률 진술, 증거를 정량화하는 베이즈 요인(Bayes Factor), 귀무 가설을 지지하는 기능을 제공하는 베이지안 버전이 있습니다. references/bayesian_statistics.md를 참조하세요.
가정 확인
검정 결과를 해석하기 전에 항상 가정을 확인하고 확인 결과를 보고하세요 — 검토자들이 이를 확인합니다.
번들로 제공되는 scripts/assumption_checks.py 모듈을 사용하세요. 스킬 디렉토리(skills/statistical-analysis/)에서 Python을 실행하거나 sys.path에 scripts/를 추가하세요:
from assumption_checks import comprehensive_assumption_check
# 이상치 + (그룹별) 정규성 + 등분산성, 그래프 포함
results = comprehensive_assumption_check(
data=df,
value_col='score',
group_col='group', # 선택 사항: 그룹 비교용
alpha=0.05
)
특정 확인을 위해 개별 함수를 가져올 수 있습니다:
from assumption_checks import (
check_normality, # Shapiro-Wilk + Q-Q plot + 히스토그램
check_normality_per_group,
check_homogeneity_of_variance, # Levene 검정 + 상자 그림
check_linearity, # 산점도 + 잔차 그림 (단순 회귀용)
check_regression_diagnostics, # 전체 OLS 진단 (아래 회귀 참조)
detect_outliers # IQR 또는 z-점수 방법
)
result = check_normality(data=df['score'], name='Test Score', alpha=0.05, plot=True)
print(result['interpretation'])
print(result['recommendation'])
가정이 위반되었을 때 대처 방법
정규성 위반:
- 경미한 위반 + 그룹당 n > 30 → 모수적 검정 진행 (강건함)
- 중간 수준 위반 → 비모수적 대안 사용
- 심각한 위반 → 데이터 변환 또는 비모수 검정 사용
등분산성 위반:
- t-검정의 경우 → Welch의 t-검정 사용 (
pg.ttest는correction='auto'로 자동 적용) - ANOVA의 경우 → Welch의 ANOVA (
pg.welch_anova) 또는 Brown-Forsythe 사용 - 회귀의 경우 → 강건 표준 오차 또는 가중 최소 제곱 사용
선형성 위반 (회귀):
- 다항식 항 추가, 변수 변환, 또는 비선형 모델 / GAM 사용
n이 증가함에 따라 공식 검정은 과민해집니다: n ≥ 100인 경우, Shapiro-Wilk p-값보다 Q-Q plot을 더 중요하게 고려하세요. 포괄적인 지침은 references/assumptions_and_diagnostics.md를 참조하세요.
통계 검정 실행
주요 라이브러리:
- pingouin: 사용자 친화적인 검정으로 기본적으로 효과 크기를 반환 — 표준 검정에 선호
- scipy.stats: 핵심 통계 검정
- statsmodels: 회귀, 진단, 검정력 분석
- pymc + arviz: 베이지안 모델링 및 진단
완전한 보고가 포함된 t-검정
import pingouin as pg
# correction='auto'는 분산이 같지 않을 때 Welch 보정 적용
result = pg.ttest(group_a, group_b, correction='auto')
# Pingouin >= 0.6 열 이름
t_stat = result['T'].values[0]
df = result['dof'].values[0]
p_value = result['p_val'].values[0]
cohens_d = result['cohen_d'].values[0]
ci_lower, ci_upper = result['CI95'].values[0] # 평균 차이의 CI
print(f"t({df:.0f}) = {t_stat:.2f}, p = {p_value:.3f}, d = {cohens_d:.2f}")
ANOVA와 사후 검정
import pingouin as pg
aov = pg.anova(dv='score', between='group', data=df, detailed=True)
print(aov)
# 효과 크기: 부분 에타 제곱
eta_p2 = aov['np2'].values[0]
# 유의하면 사후 검정 수행 (Tukey HSD는 가족 단위 오류 제어)
if aov['p_unc'].values[0] < 0.05:
posthoc = pg.pairwise_tukey(dv='score', between='group', data=df)
print(posthoc) # 각 쌍에 대한 Hedges' g 포함
진단이 포함된 선형 회귀
import statsmodels.api as sm
from assumption_checks import check_regression_diagnostics
X = sm.add_constant(X_predictors) # 절편 추가
model = sm.OLS(y, X).fit()
print(model.summary())
# 4-패널 잔차 그림 + Shapiro-Wilk, Breusch-Pagan, Durbin-Watson, VIF
diag = check_regression_diagnostics(model)
print(diag['interpretation'])
print(diag['vif'])
# 이분산성이 지적된 경우, 대신 강건 표준 오차 보고
robust = model.get_robustcov_results('HC3')
베이지안 t-검정
import pymc as pm
import arviz as az
import numpy as np
with pm.Model() as model:
# 사전 분포
mu1 = pm.Normal('mu_group1', mu=0, sigma=10)
mu2 = pm.Normal('mu_group2', mu=0, sigma=10)
sigma = pm.HalfNormal('sigma', sigma=10)
# 우도
y1 = pm.Normal('y1', mu=mu1, sigma=sigma, observed=group_a)
y2 = pm.Normal('y2', mu=mu2, sigma=sigma, observed=group_b)
# 파생량
diff = pm.Deterministic('difference', mu1 - mu2)
trace = pm.sample(2000, tune=1000)
# ArviZ 1.x는 기본적으로 89% 구간을 사용합니다. 보고용으로는 95%를 명시적으로 요청하세요.
print(az.summary(trace, var_names=['difference'], ci_prob=0.95))
# 직접 확률 진술 (단측 질문이 이렇게 됩니다)
prob_greater = np.mean(trace.posterior['difference'].values > 0)
print(f"P(mu1 > mu2 | data) = {prob_greater:.3f}")
# ArviZ 1.x는 az.plot_posterior를 제거했습니다. plot_dist를 사용하세요. (0.x에서는 plot_posterior가 여전히 작동합니다)
az.plot_dist(trace, var_names=['difference'], ci_prob=0.95)
사전 분포를 데이터에 맞게 조정하고(예: 표준편차가 10 근처인 결과에는 sigma=10이 적합, 관찰된 SD를 가이드로 사용) 보고서에 사전 분포를 명시하세요.
효과 크기
효과 크기는 크기를 정량화합니다. p-값은 존재만을 나타냅니다. 모든 검정에 대해 효과 크기를 보고하세요. 전체 가이드는 references/effect_sizes_and_power.md를 참조하세요.
빠른 참조: 일반적인 효과 크기
| 검정 | 효과 크기 | 작음 | 중간 | 큼 |
|---|---|---|---|---|
| t-검정 | Cohen's d | 0.20 | 0.50 | 0.80 |
| ANOVA | η²_p | 0.01 | 0.06 | 0.14 |
| 상관 | r | 0.10 | 0.30 | 0.50 |
| 회귀 | R² | 0.02 | 0.13 | 0.26 |
| 카이제곱 | Cramér's V | 0.07 | 0.21 | 0.35 |
기준은 관례일 뿐, 법칙이 아닙니다 — "작은" 효과가 엄청나게 중요할 수 있고(약물 부작용), "큰" 효과가 사소할 수 있습니다. 맥락에 따라 해석하세요.
효과 크기 계산
Pingouin은 검정과 함께 효과 크기를 반환합니다 (pg.ttest의 cohen_d, pg.anova의 np2, pg.pairwise_tukey의 hedges; pg.corr의 r은 자체로 효과 크기입니다).
효과 크기에 대한 신뢰 구간
효과 크기의 정밀도를 보여주기 위해 CI를 보고하세요. pg.compute_esci를 사용하세요 (참고: pg.compute_effsize_from_t는 점 추정치만 반환하며 CI를 반환하지 않습니다):
import pingouin as pg
d = pg.compute_effsize(group_a, group_b, eftype='cohen')
ci_lower, ci_upper = pg.compute_esci(stat=d, nx=len(group_a), ny=len(group_b),
eftype='cohen', confidence=0.95)
print(f"d = {d:.2f}, 95% CI [{ci_lower:.2f}, {ci_upper:.2f}]")
검정력 분석
사전 검정력 분석 (연구 계획)
데이터 수집 전에 필요한 표본 크기를 결정합니다:
from statsmodels.stats.power import tt_ind_solve_power, FTestAnovaPower
# t-검정: d = 0.5를 탐지하려면 그룹당 몇 명이 필요한가?
n_required = tt_ind_solve_power(
effect_size=0.5,
alpha=0.05,
power=0.80,
ratio=1.0,
alternative='two-sided'
)
print(f"필요한 그룹당 n: {n_required:.0f}")
# 일원 ANOVA: Cohen's f = 0.25를 탐지하려면 몇 명이 필요한가?
# 참고: k_groups는 그룹 수; effect_size는 Cohen's f (f = sqrt(eta2/(1-eta2)));
# solve_power는 그룹별 n이 아닌 전체 표본 크기를 반환합니다.
import math
anova_power = FTestAnovaPower()
n_total = anova_power.solve_power(
effect_size=0.25,
k_groups=3,
alpha=0.05,
power=0.80
)
print(f"필요한 전체 N: {math.ceil(n_total)} (그룹당 {math.ceil(n_total / 3)}명)")
민감도 분석 (연구 후)
연구가 어떤 효과 크기를 탐지할 수 있었는지 결정합니다:
# 그룹당 n=50일 때, 80% 검정력으로 탐지 가능한 효과 크기는?
detectable_d = tt_ind_solve_power(
effect_size=None, # 이것에 대해 풀기
nobs1=50,
alpha=0.05,
power=0.80,
ratio=1.0,
alternative='two-sided'
)
print(f"연구는 d >= {detectable_d:.2f}를 탐지할 수 있음")
참고: 사후 "관찰된 검정력"(관찰된 효과로 검정력 계산)은 순환적이며 오해의 소지가 있습니다 — 이는 p-값의 결정론적 함수입니다. 연구가 완료되었고 누군가 검정력에 대해 묻는다면, 대신 민감도 분석을 실행하세요.
자세한 지침은 references/effect_sizes_and_power.md를 참조하세요.
결과 보고
APA 스타일은 references/reporting_standards.md를 따르세요. 모든 보고서에는 다음이 필요합니다:
- 기술 통계: 모든 그룹/변수에 대한 M, SD, n
- 검정 통계량: 검정 이름, 통계량, 자유도, 정확한 p-값 (
p = .034,p < .05가 아님; .001 미만에서만p < .001사용) - 효과 크기: 신뢰 구간 포함
- 가정 확인: 실행된 검정, 결과, 취해진 조치
- 모든 계획된 분석: 유의하지 않은 결과도 포함 — 생략은 체리 피킹입니다
예시 보고 템플릿
독립 표본 t-검정
그룹 A (n = 48, M = 75.2, SD = 8.5)는 그룹 B (n = 52, M = 68.3, SD = 9.2)보다 유의하게 높은 점수를 보였으며,
t(98) = 3.42, p = .001, d = 0.68, 95% CI [0.30, 1.06]이었습니다.
일원 ANOVA
일원 ANOVA를 통해 그룹 간 점수에 유의한 차이가 있는 것으로 나타났습니다,
F(2, 147) = 5.23, p = .006, η²_p = .066, 90% CI [.012, .141].
Tukey HSD 사후 검정 결과, 그룹 A(M = 75.2, SD = 8.5)가 그룹 B(M = 68.3, SD = 9.2)보다 유의하게 높았으며,
p = .004, Hedges' g = 0.72입니다. 그룹 C와의 다른 차이는 유의하지 않았습니다(p > .05).
참고: ANOVA 부분 η²에 대한 보고 신뢰 구간은 90% CI입니다(Cohen, 1973; APA Publication Manual에 따름). pingouin 또는 scripts/effect_size_helpers.py의 compute_eta2_ci를 사용하세요.
추가 리소스
참조 문서:
references/bayesian_statistics.md— 가설 검정을 위한 베이지안 방법references/effect_sizes_and_power.md— 효과 크기 및 검정력 분석references/assumptions_and_diagnostics.md— 포괄적인 가정 확인references/test_selection_guide.md— 전체 검정 선택references/reporting_standards.md— APA 보고 기준
관련 스킬:
- statsmodels — 모델별 API (OLS, GLM, ARIMA)
- pymc — 베이지안 모델링 워크플로우