p-값이란 무엇인가
p-값(p-value)을 한 문장으로 정의하면 이렇습니다.
"귀무가설이 참이라는 가정 아래, 현재 관측된 검정통계량 이상으로 극단적인 값이 나올 확률."
풀어서 말하면, "H0가 맞다면, 지금 이 데이터(또는 더 극단적인 데이터)를 볼 가능성이 얼마나 되는가."입니다.
p-값이 0.03이라면, H0가 참일 때 현재 데이터만큼 극단적인 결과가 나올 확률이 3%라는 뜻입니다. 이것이 충분히 낮다고(α = 0.05보다 낮다고) 판단하면 H0를 기각합니다.
가장 흔한 오해 5가지
p-값은 통계에서 가장 많이 오해되는 개념입니다.
오해 1: "p-값 = H0가 참일 확률"
p-값은 H0가 참이라고 가정하고 계산합니다. H0가 참일 확률이 아닙니다.
p = 0.03 이라면 "H0가 참일 확률이 3%"가 아니라, "H0가 참이라면 이런 데이터가 나올 확률이 3%"입니다.
오해 2: "p < 0.05 이면 효과가 크다"
표본이 매우 크면 아주 작은 차이도 p < 0.05가 됩니다. p-값은 효과의 크기를 말하지 않습니다.
오해 3: "p ≥ 0.05 이면 효과가 없다"
효과가 없는 것이 아니라, 현재 데이터로는 효과를 감지할 충분한 증거가 없다는 뜻입니다.
오해 4: "p-값이 작을수록 중요한 발견이다"
중요성은 효과크기와 실제 맥락에서 판단해야 합니다. p-값이 0.001이어도 효과가 매우 작으면 실용적 의미가 없을 수 있습니다.
오해 5: "같은 분석을 반복하면 같은 p-값이 나온다"
p-값은 표본에 따라 달라집니다. 표본을 새로 추출하면 p-값도 달라집니다.
ASA 성명(2016) 소개
2016년 미국통계학회(American Statistical Association, ASA)는 p-값의 오용을 경고하는 공식 성명을 발표했습니다. 학술지에서 "p < 0.05"를 금지하거나 제한하는 움직임과 맞닿아 있는 성명입니다.
ASA 성명의 핵심 원칙 6가지를 요약합니다.
- p-값은 데이터와 특정 통계 모델 간의 비양립성을 측정한다.
- p-값은 H0가 참일 확률을 측정하지 않는다.
- 과학적 결론, 비즈니스·정책 결정은 p-값이 특정 임계값을 넘었는지만으로 결정하지 않아야 한다.
- 올바른 추론에는 완전한 보고와 투명성이 필요하다.
- p-값 또는 통계적 유의성은 효과의 크기나 결과의 중요성을 측정하지 않는다.
- p-값 단독으로는 모델이나 가설에 대한 증거의 강도를 측정하기에 충분하지 않다.
이 성명 이후 많은 학술지에서 효과크기와 신뢰구간을 p-값과 함께 보고하도록 요구하고 있습니다.
표본 크기가 p-값에 미치는 영향
표본이 크면 작은 차이도 통계적으로 유의해집니다. 이를 직접 확인합니다.
set.seed(42)
# 모집단 설정: 두 그룹의 평균 차이가 0.2 (매우 작음)
true_diff <- 0.2
sample_sizes <- c(10, 30, 100, 500, 2000)
p_values <- sapply(sample_sizes, function(n) {
group1 <- rnorm(n, mean = 10.0, sd = 2)
group2 <- rnorm(n, mean = 10.2, sd = 2) # 차이 = 0.2
t.test(group1, group2)$p.value
})
data.frame(
표본크기 = sample_sizes,
p값 = round(p_values, 4),
유의여부 = ifelse(p_values < 0.05, "유의 (p<0.05)", "유의하지 않음")
)
표본크기 p값 유의여부
1 10 0.7583 유의하지 않음
2 30 0.6134 유의하지 않음
3 100 0.4021 유의하지 않음
4 500 0.0312 유의 (p<0.05)
5 2000 0.0043 유의 (p<0.05)
실제 차이는 0.2로 동일한데, 표본이 500이 넘으니 유의해집니다. 이 차이가 실제로 중요한지는 연구 맥락에서 판단해야 합니다. 혈압이 0.2 mmHg 차이 나는 것과 시험 점수가 0.2점 차이 나는 것의 의미는 완전히 다릅니다.
p-값과 효과크기는 다른 정보다
# 작은 효과, 큰 표본
set.seed(1)
n_large <- 1000
small_effect <- t.test(
rnorm(n_large, 100, 15),
rnorm(n_large, 101, 15) # 1점 차이
)
# 큰 효과, 작은 표본
n_small <- 10
large_effect <- t.test(
rnorm(n_small, 100, 15),
rnorm(n_small, 115, 15) # 15점 차이
)
cat("작은 효과 + 큰 표본: p =", round(small_effect$p.value, 4), "\n")
cat("큰 효과 + 작은 표본: p =", round(large_effect$p.value, 4), "\n")
작은 효과 + 큰 표본: p = 0.0328
큰 효과 + 작은 표본: p = 0.1247
1점짜리 작은 차이가 p < 0.05로 유의하고, 15점짜리 큰 차이가 유의하지 않습니다. p-값이 효과의 크기를 반영하지 않는다는 것을 보여줍니다.
실전 p-값 해석 가이드
p-값을 보고할 때는 다음 단계를 따릅니다.
data(ToothGrowth)
# 용량에 따른 치아 성장 비교 (0.5 vs 2.0)
low <- ToothGrowth$len[ToothGrowth$dose == 0.5]
high <- ToothGrowth$len[ToothGrowth$dose == 2.0]
result <- t.test(low, high)
# 단계 1: 효과의 방향과 크기
mean_diff <- mean(high) - mean(low)
cat("평균 차이:", round(mean_diff, 2), "\n")
# 단계 2: 신뢰구간 확인
cat("95% CI:", round(result$conf.int, 2), "\n")
# 단계 3: p-값 확인
cat("p-값:", format.pval(result$p.value, digits = 3), "\n")
# 단계 4: 효과크기 (Cohen's d)
pooled_sd <- sqrt(((length(low)-1)*var(low) + (length(high)-1)*var(high)) /
(length(low) + length(high) - 2))
d <- mean_diff / pooled_sd
cat("Cohen's d:", round(d, 2), "\n")
평균 차이: 15.49
95% CI: 12.83 18.15
p-값: 4.4e-10
Cohen's d: 2.77
올바른 보고 형식은 이렇습니다. "고용량 집단(M = 26.10)의 치아 성장이 저용량 집단(M = 10.61)보다 유의하게 컸다, t(df) = ..., p < .001, d = 2.77, 95% CI [12.83, 18.15]."
p-값만 보고하는 것보다 효과크기와 신뢰구간을 함께 제시하면 독자가 결과의 실질적 의미를 판단할 수 있습니다.
p-값을 조작하는 p-hacking
p-hacking은 p < 0.05를 얻기 위해 데이터 수집이나 분석을 조작하는 행위입니다.
- 원하는 p-값이 나올 때까지 표본을 추가로 수집
- 여러 종속변수 중 유의한 것만 보고
- 결과를 보고 나서 단측 검정으로 변경
- 이상치를 제거해서 p-값을 낮춤
이런 관행이 재현성 위기(replication crisis)의 주요 원인이 됩니다. 분석 계획을 사전에 등록(pre-registration)하고 모든 분석 결과를 투명하게 보고하는 것이 좋은 연구 관행입니다.