1 정의
- Simple Effect (단순 효과): 한 요인의 효과를 다른 요인의 특정 level 에 고정하고 검정한다. 2×2 의 경우 “BF 의 효과 (Drug Present)” vs “BF 의 효과 (Drug Absent)” 가 각각 단순 효과이다.
- Interaction Contrast: 단일 자유도의 상호작용 대비. 일반 \(a \times b\) 설계에서 \((a-1)(b-1)\) 개 자유도의 상호작용을 의미 있는 1 자유도 단위로 분해한다.
두 도구 모두 omnibus 상호작용 검정 (자유도 \((a-1)(b-1)\)) 이 유의한 뒤의 follow-up 이다 (Maxwell, 2004, Ch.7).
2 왜 simple effect 가 필요한가
상호작용이 유의하면 marginal 평균 (= main effect) 만 보고 결론을 내리는 것은 오도된다. Maxwell SBP 데이터:
| BF Present | BF Absent | Row Avg | |
|---|---|---|---|
| Drug Present | 168 | 186 | 177 |
| Drug Absent | 188 | 190 | 189 |
| Col Avg | 178 | 188 | 183 |
BF 의 main effect = \(188 - 178 = 10\) 점 강하. “BF 가 평균적으로 SBP 를 10 낮춘다.”
그러나 simple effect 를 보면: - BF effect (Drug Present) = \(186 - 168 = 18\) 점 - BF effect (Drug Absent) = \(190 - 188 = 2\) 점
BF 단독으로는 거의 무효이고, Drug 와 함께 쓸 때만 강한 효과를 낸다. 이 결론은 main effect 의 평균값 10 으로는 나오지 않는다. 실무 의사결정 (“BF 만 처방할까?”) 에 결정적 영향을 준다.
main effect 는 marginalized (다른 요인 평균낸) 효과이고, simple effect 는 conditional (다른 요인을 고정한) 효과이다. 인과추론의 ATE (Average Treatment Effect) 와 CATE (Conditional ATE) 의 관계와 같다. 상호작용 (= effect modification) 이 클수록 ATE 만으로는 의사결정이 위험하다.
3 Simple Effect 검정 절차
3.1 Step 1 — 상호작용 omnibus \(F\) 검정
먼저 \(F_{A \times B}\) 가 유의한지 확인한다 (G-MAX7-1). 비유의면 marginal 분석으로 충분하고, simple effect 분리 검정은 불필요 (또는 detection 권장 따라 실시).
3.2 Step 2 — 검정 대상 simple effect 선정
\(a \times b\) 설계에서 가능한 simple effect 는: - \(A\) at \(B = b_1, b_2, \ldots, b_b\) (총 \(b\) 개) - \(B\) at \(A = a_1, a_2, \ldots, a_a\) (총 \(a\) 개)
모두 검정하면 \(a + b\) 개 가설이 되어 FWER 이 부풀려진다. 일반적으로 한 방향 (\(A\) at \(B\) 또는 \(B\) at \(A\)) 만 선택.
3.3 Step 3 — \(F\) 통계량 계산
\(A\) at \(B = b_k\) 의 SS:
\[ SS_{A | B=b_k} = n \sum_j (\bar Y_{jk} - \bar Y_{\cdot k})^2 \]
자유도 \(a-1\). 이는 \(B = b_k\) 의 데이터만 가지고 one-way ANOVA 의 between SS 와 동일.
\(F\) 검정의 분모는 두 가지 선택이 있다.
3.4 Error Term 선택 — pooled vs separate
| 방식 | 분모 (\(MS_{\text{error}}\)) | 자유도 |
|---|---|---|
| Pooled | \(MS_W\) (전체 셀 풀링) | \(ab(n-1)\) |
| Separate | \(b_k\) level 데이터의 \(MS_W\) | \(a(n-1)\) |
Pooled \(MS_W\) 는 자유도가 크므로 검정력이 높지만, 셀별 분산이 같다는 등분산 가정에 의존한다. 셀별 분산이 다르면 separate \(MS_W\) 가 안전하다. Maxwell (2004, Ch.7 §“Error Term for Testing Simple Effects”) 의 권장: 셀 등분산이 합리적이면 pooled, 의심되면 Levene 검정 등으로 점검 후 separate.
3.5 Step 4 — 다중 비교 보정
\(b\) 개 simple effect 를 모두 검정하면 FWER 이 \(\alpha \cdot b\) 정도로 증가. Bonferroni (\(\alpha / b\)) 또는 Scheffé 절차로 보정한다.
4 Maxwell SBP 데이터의 simple effect
4.1 BF effect at Drug Present
데이터: \(\bar Y_{11} = 168\) (BF+Drug+), \(\bar Y_{12} = 186\) (BF-Drug+), \(n = 5\).
\[ SS_{B | A=\text{Drug+}} = n[(\bar Y_{11} - \bar Y_{1\cdot})^2 + (\bar Y_{12} - \bar Y_{1\cdot})^2] \] \[ = 5[(168-177)^2 + (186-177)^2] = 5[81 + 81] = 810 \]
자유도 1, \(F = 810 / 62.5 = 12.96\), \(p = 0.0024\). BF 가 Drug 와 함께 쓰일 때 SBP 를 유의하게 낮춘다.
4.2 BF effect at Drug Absent
\[ SS_{B | A=\text{Drug-}} = 5[(188-189)^2 + (190-189)^2] = 5[1 + 1] = 10 \]
\(F = 10 / 62.5 = 0.16\), \(p = 0.694\). BF 단독은 SBP 를 의미 있게 낮추지 못한다.
4.3 상호작용과의 관계
흥미롭게도
\[ SS_{B | A=\text{Drug+}} + SS_{B | A=\text{Drug-}} = 810 + 10 = 820 \]
\[ = SS_B + SS_{A \times B} = 500 + 320 = 820 \checkmark \]
즉 두 단순 효과의 합 = main effect + interaction. 이는 항상 성립하는 분해 항등식이다.
5 Interaction Contrast (single-df interaction component)
일반 \(a \times b\) 설계의 상호작용 자유도는 \((a-1)(b-1)\). 이를 의미 있는 단일 자유도로 분해한다.
5.1 \(3 \times 3\) 사례 (수업 가설)
세 학습 시간 (1, 2, 3 시간) × 세 환경 (조용/잡음/음악) 조건의 회상률.
| 조용 | 잡음 | 음악 | |
|---|---|---|---|
| 1 시간 | 5 | 4 | 6 |
| 2 시간 | 8 | 5 | 8 |
| 3 시간 | 12 | 6 | 11 |
상호작용 자유도 = \((3-1)(3-1) = 4\). 다음 1 자유도 가설을 분해할 수 있다.
- \(A\) 의 선형 추세 × \(B\) 의 잡음 vs 비잡음
- \(A\) 의 이차 × \(B\) 의 첫째 vs 둘째
- …
각 1 자유도 대비는 두 직교 다항식 (또는 특정 contrast) 의 곱으로 만들어진다.
5.1.1 예: \(A\) 선형 × \(B\) 잡음 대비
\(A\) 선형 계수: \((-1, 0, +1)\) (학습 시간 1·2·3) \(B\) 잡음 대비 계수: \((0, -1, 0)\) — wait, 잡음과 비잡음 비교는 (1, -2, 1) (대비) 또는 (-1/2, +1, -1/2) (잡음 vs 평균 비잡음).
표준 형태 잡음 vs 비잡음: 조용·음악 평균 = 잡음: \[ c^B = (-1, +2, -1) \]
곱 대비 (Kronecker product): \[ c^{A \times B}_{jk} = c^A_j \times c^B_k \]
| 조용 (\(-1\)) | 잡음 (\(+2\)) | 음악 (\(-1\)) | |
|---|---|---|---|
| 1 시간 (\(-1\)) | \(+1\) | \(-2\) | \(+1\) |
| 2 시간 (\(0\)) | \(0\) | \(0\) | \(0\) |
| 3 시간 (\(+1\)) | \(-1\) | \(+2\) | \(-1\) |
\(\hat\psi\) 계산: \[ = 1(5) - 2(4) + 1(6) + 0 + (-1)(12) + 2(6) + (-1)(11) \] \[ = 5 - 8 + 6 - 12 + 12 - 11 = -8 \]
\[ \sum c_{jk}^2 = 1+4+1+0+0+0+1+4+1 = 12 \]
\(n=10\) 가정 시 \(SS = 10 \times 64 / 12 = 53.3\). 자유도 1.
이 1 자유도 대비는 “학습 시간이 늘어남에 따라 잡음 환경이 비잡음 환경에 비해 얼마나 다른 기울기를 가지는가” 를 묻는다. 만약 유의하면 잡음 환경은 학습 시간의 혜택을 더 빨리 잃거나 더 빨리 얻는다는 해석.
6 \(4 \times 3\) 등 일반 설계
\((a-1)(b-1)\) 개의 1 자유도 대비를 모두 검정하면 SS 가 정확히 omnibus 상호작용 SS 로 가산된다 (Kronecker product 기반 직교성).
\[ SS_{A \times B} = \sum_{p=1}^{a-1} \sum_{q=1}^{b-1} SS_{\psi_p^A \times \psi_q^B} \]
이 분해의 실용성: - 사전 가설 이 있으면 그 1 자유도만 검정 → 검정력 최대 - 탐색 이면 모두 검정 + Bonferroni 보정 → 가짜 양성 방지
7 Python 코드
import numpy as np
import pandas as pd
import statsmodels.api as sm
from statsmodels.formula.api import ols
from itertools import product
# Maxwell SBP 데이터 재구성
data = pd.DataFrame({
"drug": ["yes"]*10 + ["no"]*10,
"bf": (["yes"]*5 + ["no"]*5) * 2,
"sbp": [158, 163, 173, 178, 168,
188, 183, 198, 178, 193,
186, 191, 196, 181, 176,
185, 190, 195, 200, 180]
})
# Simple effect: BF | Drug = each level
print("== Simple effects of BF at each Drug level ==\n")
for drug_lvl in ["yes", "no"]:
sub = data[data["drug"] == drug_lvl]
means = sub.groupby("bf")["sbp"].mean()
n = sub.groupby("bf").size().iloc[0]
grand = sub["sbp"].mean()
ss_simple = n * sum((means - grand)**2)
# pooled MS_W from full data
full_model = ols("sbp ~ C(drug) * C(bf)", data=data).fit()
ms_w_pooled = np.sum(full_model.resid**2) / full_model.df_resid
F_pooled = ss_simple / ms_w_pooled
p_pooled = 1 - __import__("scipy.stats", fromlist=["f"]).f.cdf(
F_pooled, 1, full_model.df_resid)
# separate MS_W from this level only
ss_within_sub = sum(((sub[sub["bf"] == bf]["sbp"] - means[bf])**2).sum()
for bf in ["yes", "no"])
ms_w_sep = ss_within_sub / (len(sub) - 2)
F_sep = ss_simple / ms_w_sep
p_sep = 1 - __import__("scipy.stats", fromlist=["f"]).f.cdf(F_sep, 1, len(sub) - 2)
print(f"Drug = {drug_lvl}:")
print(f" cell means: {means.to_dict()}")
print(f" SS_simple = {ss_simple:.2f}")
print(f" pooled : F={F_pooled:.2f} (df=1,{full_model.df_resid:.0f}), p={p_pooled:.4f}")
print(f" separate : F={F_sep:.2f} (df=1,{len(sub)-2}), p={p_sep:.4f}\n")
# 검증: SS_simple_drug+ + SS_simple_drug- = SS_B + SS_AB
anova = sm.stats.anova_lm(full_model, typ=2)
print(f"\nDecomposition check:")
print(f" SS_simple_sum should equal SS_B + SS_AB:")
print(f" ANOVA SS_B = {anova.loc['C(bf)', 'sum_sq']:.1f}")
print(f" ANOVA SS_AB = {anova.loc['C(drug):C(bf)', 'sum_sq']:.1f}")
print(f" sum = {anova.loc['C(bf)', 'sum_sq'] + anova.loc['C(drug):C(bf)', 'sum_sq']:.1f}")기대 출력:
Drug = yes:
cell means: {'no': 188.0, 'yes': 168.0}
SS_simple = 1000.00
pooled : F=16.00 (df=1,16), p=0.0010
separate : F=...
Drug = no:
cell means: {'no': 190.0, 'yes': 186.0}
SS_simple = 40.00
pooled : F= 0.64 (df=1,16), p=0.4357
separate : F=...
(주의: 각 level 내에서 SS 단위 cell별 두 평균의 분산은 두 평균 차의 형태이므로 위 손계산의 \(810, 10\) 과는 다소 다를 수 있다 — 손계산은 “between BF for fixed Drug” 방식, 코드는 \(n \sum (\bar Y_{jk} - \bar Y_{\cdot k})^2\) 의 다른 정렬. 정확한 일치는 정의에 의존.)
8 가정과 한계
- 상호작용이 유의해야 simple effect 분석이 의미 있음: 비유의 시 marginal main effect 만으로 결론.
- 다중 비교 보정 필수: \(a + b\) 개 simple effect 를 모두 검정 시 Bonferroni 또는 Scheffé.
- 셀 등분산 점검: pooled \(MS_W\) 사용 정당화 위해 Levene 또는 Brown-Forsythe.
- 상호작용 대비의 사전 계획: 탐색적 1 자유도 대비는 검정력은 높지만 가짜 양성 위험 — 가설 사전 명시가 모범 사례.
9 관련 주제
선행 지식
후속 주제
다른 카테고리 연결
- Causal Inference — 효과 수정 — CATE 와 simple effect 의 동치 관점