다중 표본 반복측정 ANOVA: 분할구획 설계의 수식과 직관

두 오차 층위, SS 완전 분해, E[MS] 유도, 교호작용 검정과 해석, 집단×시간 대비 분석

여러 집단을 여러 시점에 반복 측정하는 분할구획(Split-Plot) 설계의 통계 구조를 수식과 직관으로 상세히 설명한다. 피험자-내(within) 층위와 피험자-간(between) 층위의 분리, SS 완전 분해, 각 MS의 기댓값 유도, 집단 효과의 올바른 분모 선택, 집단×시간 교호작용의 직교 다항식 분해와 단순 효과 분석, 코드까지 다룬다.

Statistics
Longitudinal Data Analysis
저자

Kwangmin Kim

공개

2026년 04월 09일

1 개요

임상시험을 가정하자. 약물 집단 30명과 위약 집단 30명을 모집하여, 처치 전·2주·4주·8주에 걸쳐 우울 척도를 반복 측정한다. 이 연구가 답하려는 핵심 질문은 다음 세 가지다.

  1. 두 집단의 전체 평균이 다른가? (집단 주효과)
  2. 시간에 따라 모든 피험자의 평균이 변화하는가? (시간 주효과)
  3. 집단별 시간에 따른 변화 패턴이 서로 다른가? (집단 × 시간 교호작용)

특히 3번 교호작용이 임상적으로 가장 중요하다. “약물이 위약보다 우울을 더 빠르게 낮추는가?”가 바로 이 질문이다.

이 설계는 단일 표본 반복측정 ANOVA(임의블록 설계)를 집단 요인으로 확장한 것이다. 그런데 집단 효과와 시간 효과가 서로 다른 오차 층위(error stratum)를 갖는다는 점이 핵심 복잡성이다. 이것을 이해하면 다중 표본 반복측정 ANOVA의 논리 전체가 명확해진다.

이 포스트는 반복측정 ANOVA 개요단일 표본 반복측정 ANOVA 심화의 다중 표본 확장이다.


2 설계 구조와 모형

2.1 설계 구조: 분할구획

\(s\) 개 집단( \(h = 1, \ldots, s\) ), 집단 \(h\)\(N_h\) 명의 피험자( \(i = 1, \ldots, N_h\) ), \(n\) 개 시점( \(j = 1, \ldots, n\) )의 완전 균형 교차 설계.

\[ \text{전체 표본 크기}: N = \sum_{h=1}^s N_h \]

집단 피험자 시점 1 시점 2 \(\cdots\) 시점 \(n\)
1 1 \(y_{111}\) \(y_{112}\) \(\cdots\) \(y_{11n}\)
1 2 \(y_{121}\) \(y_{122}\) \(\cdots\) \(y_{12n}\)
\(\vdots\) \(\vdots\)
1 \(N_1\) \(y_{1N_1 1}\) \(y_{1N_1 2}\) \(\cdots\) \(y_{1N_1 n}\)
\(\vdots\)
\(s\) \(N_s\) \(y_{sN_s 1}\) \(y_{sN_s 2}\) \(\cdots\) \(y_{sN_s n}\)

구조적 특징: - 피험자는 집단에 Nested: 피험자 \(i\) 는 정확히 하나의 집단에 속한다. - 피험자는 시점에 Crossed: 각 피험자는 모든 시점에서 관측된다.

이 구조는 농업 실험의 분할구획 설계(Split-Plot Design)와 동일한 형태를 갖는다. 주구(whole plot)는 집단, 부구(sub-plot)는 시점에 해당한다.

2.2 모형 방정식

모형: 다중 표본 반복측정 ANOVA (분할구획 설계)

\[ y_{hij} = \mu + \gamma_h + \pi_{i(h)} + \tau_j + (\gamma\tau)_{hj} + e_{hij} \]

성분 종류 분포/제약 의미
\(\mu\) 고정, 상수 전체 평균
\(\gamma_h\) 고정 효과 \(\sum_h \gamma_h = 0\) 집단 \(h\) 의 평균 수준 차이
\(\pi_{i(h)}\) 랜덤 효과 \(\pi_{i(h)} \sim N(0, \sigma_\pi^2)\), 독립 집단 \(h\) 내 피험자 \(i\) 의 개인차
\(\tau_j\) 고정 효과 \(\sum_j \tau_j = 0\) 시점 \(j\) 의 주효과
\((\gamma\tau)_{hj}\) 고정 효과 \(\sum_h = \sum_j = 0\) 집단 × 시간 교호작용
\(e_{hij}\) 오차 \(e_{hij} \sim N(0, \sigma_e^2)\), 독립 피험자-내 잔차 오차

\(\pi_{i(h)}\)\(e_{hij}\) 는 서로 독립.

2.3 두 오차 층위의 핵심 직관

모형에는 두 가지 오차가 존재한다.

\(\pi_{i(h)}\) (피험자-간 오차): 집단 내에서 피험자마다 다른 기저 수준. “약물 집단 내에서 어떤 환자는 원래 우울 점수가 높고, 어떤 환자는 낮다.” 이 효과는 시간에 걸쳐 일정하므로, 집단 효과를 비교할 때의 기준 변동성이다.

\(e_{hij}\) (피험자-내 오차): 개인 특성과 모든 고정 효과로도 설명되지 않는 나머지. “이 환자가 2주차에 평균보다 조금 더 좋아진 것은 그 날의 컨디션 때문.” 이 효과는 시점별로 독립이고, 시간 효과와 교호작용을 비교할 때의 기준 변동성이다.

두 오차 층위가 서로 다른 분모를 만든다
효과 층위 오차 기준 분모
집단 주효과 \(\gamma_h\) 피험자-간(Between-Subjects) \(\pi_{i(h)}\) \(MS_{S(G)}\)
시간 주효과 \(\tau_j\) 피험자-내(Within-Subjects) \(e_{hij}\) \(MS_R\)
집단×시간 \((\gamma\tau)_{hj}\) 피험자-내(Within-Subjects) \(e_{hij}\) \(MS_R\)

이 분모 선택이 틀리면 F-통계량의 분포 자체가 달라져서 잘못된 추론을 하게 된다.


3 전체 변동의 분해: SS 항등식

3.1 관측값 분해

\(N = \sum_h N_h\) 라 하면, 균형 설계( \(N_1 = \cdots = N_s = N/s\) )에서 관측값 \(y_{hij}\) 의 전체 편차는 다음과 같이 분해된다.

\[ y_{hij} - \bar{y}_{...} = \underbrace{(\bar{y}_{h..} - \bar{y}_{...})}_{\text{집단 편차}} + \underbrace{(\bar{y}_{hi.} - \bar{y}_{h..})}_{\text{집단 내 피험자 편차}} + \underbrace{(\bar{y}_{..j} - \bar{y}_{...})}_{\text{시점 편차}} + \underbrace{(\bar{y}_{h.j} - \bar{y}_{h..} - \bar{y}_{..j} + \bar{y}_{...})}_{\text{집단×시간 교호작용 편차}} + \underbrace{(y_{hij} - \bar{y}_{hi.} - \bar{y}_{h.j} + \bar{y}_{h..})}_{\text{잔차}} \]

표기 정리:

표기 의미 평균 방향
\(\bar{y}_{...}\) 전체 평균 \(i, h, j\)
\(\bar{y}_{h..}\) 집단 \(h\) 평균 \(i, j\)
\(\bar{y}_{hi.}\) 피험자 \((h,i)\) 평균 \(j\)
\(\bar{y}_{..j}\) 시점 \(j\) 의 전체 평균 \(h, i\)
\(\bar{y}_{h.j}\) 집단 \(h\) 의 시점 \(j\) 평균 \(i\)

3.2 SS 항등식

양변을 제곱하여 \(h, i, j\) 에 대해 합산하면 교차항이 모두 0이 되어:

\[ \underbrace{SS_{\text{Total}}}_{Nn - 1 \text{ df}} = \underbrace{SS_G}_{s-1} + \underbrace{SS_{S(G)}}_{N-s} + \underbrace{SS_T}_{n-1} + \underbrace{SS_{GT}}_{(s-1)(n-1)} + \underbrace{SS_R}_{(N-s)(n-1)} \]

각 SS의 공식

\[ SS_G = n \sum_{h=1}^s N_h (\bar{y}_{h..} - \bar{y}_{...})^2 \]

\[ SS_{S(G)} = n \sum_{h=1}^s \sum_{i=1}^{N_h} (\bar{y}_{hi.} - \bar{y}_{h..})^2 \]

\[ SS_T = N \sum_{j=1}^n (\bar{y}_{..j} - \bar{y}_{...})^2 \]

\[ SS_{GT} = \sum_{h=1}^s \sum_{j=1}^n N_h (\bar{y}_{h.j} - \bar{y}_{h..} - \bar{y}_{..j} + \bar{y}_{...})^2 \]

\[ SS_R = \sum_{h,i,j} (y_{hij} - \bar{y}_{hi.} - \bar{y}_{h.j} + \bar{y}_{h..})^2 \]

3.3 각 SS의 직관

\(SS_G\) (집단 제곱합): 집단 평균들이 전체 평균에서 얼마나 떨어져 있는가. “약물 집단의 4시점 평균과 위약 집단의 4시점 평균이 얼마나 다른가.” 이 변동을 판단하는 기준은 집단 내 피험자 간 변동 \(SS_{S(G)}\) 이다.

\(SS_{S(G)}\) (집단 내 피험자 제곱합): 각 집단 내에서 피험자 평균들의 분산. “약물 집단 30명의 4시점 평균이 서로 얼마나 다른가.” 이것은 집단 효과를 검정할 때의 자연스러운 오차 단위다. 같은 집단 내에서도 사람마다 다른 것은 집단 효과 때문이 아니라 순수 개인차 때문이다.

\(SS_T\) (시간 제곱합): 모든 집단을 합한 시점 평균들의 분산. “전체적으로 시간이 지남에 따라 평균 우울 점수가 감소하는가.”

\(SS_{GT}\) (집단 × 시간 교호작용 제곱합): 집단별 시간 프로파일의 차이. “약물 집단과 위약 집단의 시간 변화 패턴이 평행하지 않은 정도.” \(\bar{y}_{h.j} - \bar{y}_{h..} - \bar{y}_{..j} + \bar{y}_{...}\) 는 “집단 \(h\) 의 시점 \(j\) 편차에서 집단 주효과와 시점 주효과를 모두 제거한 나머지”이다. 교호작용이 없으면 이 값은 0에 가깝다.

\(SS_R\) (잔차 제곱합): 모든 고정 효과와 개인차를 제거한 후 남는 피험자-내 오차. 이것이 시간 효과와 교호작용을 검정할 때의 오차 기준이다.


4 자유도 분해

\[ \underbrace{Nn - 1}_{SS_{\text{Total}}} = \underbrace{(s-1)}_{SS_G} + \underbrace{(N-s)}_{SS_{S(G)}} + \underbrace{(n-1)}_{SS_T} + \underbrace{(s-1)(n-1)}_{SS_{GT}} + \underbrace{(N-s)(n-1)}_{SS_R} \]

자유도 직관:

  • \(df_G = s-1\): \(s\) 개 집단 평균에서 1개는 전체 평균에 의해 결정됨.
  • \(df_{S(G)} = N - s\): 전체 \(N\) 명의 피험자 중 \(s\) 개 집단 평균에 의해 각 집단의 1개씩 총 \(s\) 개가 결정됨.
  • \(df_T = n-1\): \(n\) 개 시점 평균 중 합 제약으로 1개 결정됨.
  • \(df_{GT} = (s-1)(n-1)\): 집단과 시간 자유도의 곱. 교호작용 패턴의 독립 차원.
  • \(df_R = (N-s)(n-1)\): 집단 내 피험자 자유도 \((N-s)\) 와 시점 자유도 \((n-1)\) 의 곱.

검산: \((s-1) + (N-s) + (n-1) + (s-1)(n-1) + (N-s)(n-1)\) \(= (s-1+N-s)(1 + n-1) + (n-1) + (-n+1) = \cdots = Nn - 1.\) 항상 성립.


5 평균제곱의 기댓값: E[MS] 유도

각 F-검정의 분모를 결정하는 핵심은 \(E[MS]\) 이다.

5.1 \(E[MS_R]\) (잔차 평균제곱)

잔차 \(y_{hij} - \bar{y}_{hi.} - \bar{y}_{h.j} + \bar{y}_{h..}\) 에 모형을 대입하면 \(\mu, \gamma_h, \tau_j, (\gamma\tau)_{hj}, \pi_{i(h)}\) 는 모두 소거되고 오차 성분만 남는다:

\[ y_{hij} - \bar{y}_{hi.} - \bar{y}_{h.j} + \bar{y}_{h..} = e_{hij} - \bar{e}_{hi.} - \bar{e}_{h.j} + \bar{e}_{h..}. \]

따라서

\[ E[MS_R] = \sigma_e^2. \]

\(MS_R\)피험자-내 오차 분산 \(\sigma_e^2\) 의 불편추정량이다.

5.2 \(E[MS_{S(G)}]\) (집단 내 피험자 평균제곱)

피험자 평균 편차 \(\bar{y}_{hi.} - \bar{y}_{h..}\) 에 모형을 대입:

\[ \bar{y}_{hi.} - \bar{y}_{h..} = \pi_{i(h)} - \bar{\pi}_{h} + \bar{e}_{hi.} - \bar{e}_{h..}. \]

\(\tau_j\)\((\gamma\tau)_{hj}\)\(j\) 에 대한 평균에서 소거된다( \(\sum_j \tau_j = 0\) ).

\[ E[SS_{S(G)}] = n \sum_h \sum_i E[(\pi_{i(h)} + \bar{e}_{hi.} - \bar{e}_{h..})^2] = n(N-s)\sigma_\pi^2 + (N-s)\sigma_e^2. \]

따라서

\[ E[MS_{S(G)}] = \sigma_e^2 + n\sigma_\pi^2. \]

이는 단일 표본 \(E[MS_S]\) 와 동일한 구조다. 집단 내 피험자 평균제곱은 피험자-간 오차 분산 \(\sigma_\pi^2\) 와 피험자-내 오차 분산 \(\sigma_e^2\) 를 모두 포함한다.

5.3 \(E[MS_G]\) (집단 평균제곱)

집단 평균 편차 \(\bar{y}_{h..} - \bar{y}_{...}\) 에 모형을 대입:

\[ \bar{y}_{h..} - \bar{y}_{...} = \gamma_h - \bar{\gamma} + \bar{\pi}_{h} - \bar{\pi}_{...} + \bar{e}_{h..} - \bar{e}_{...}. \]

\(\tau_j\)\((\gamma\tau)_{hj}\)\(j\) 평균에서 소거됨. 정리하면

\[ E[MS_G] = \sigma_e^2 + n\sigma_\pi^2 + \frac{n \sum_h N_h \gamma_h^2}{s-1}. \]

직관: \(E[MS_G]\) 는 오차 \(\sigma_e^2\) + 개인차 \(n\sigma_\pi^2\) + 집단 효과 신호로 구성된다. \(H_0: \gamma_h = 0\) 하에서는 \(E[MS_G] = \sigma_e^2 + n\sigma_\pi^2 = E[MS_{S(G)}]\) 가 된다. 따라서 집단 효과의 올바른 분모는 \(MS_{S(G)}\) 이다.

5.4 \(E[MS_T]\) (시간 평균제곱)

시점 평균 편차 \(\bar{y}_{..j} - \bar{y}_{...}\) 에 모형을 대입:

\[ \bar{y}_{..j} - \bar{y}_{...} = \tau_j + \bar{e}_{..j} - \bar{e}_{...}. \]

\(\pi_{i(h)}\)\(h, i\) 평균에서 소거, \(\gamma_h\)\((\gamma\tau)_{hj}\) 도 전체 평균에서 소거(합 = 0).

\[ E[MS_T] = \sigma_e^2 + \frac{N \sum_j \tau_j^2}{n-1}. \]

5.5 \(E[MS_{GT}]\) (집단×시간 평균제곱)

교호작용 편차 \(\bar{y}_{h.j} - \bar{y}_{h..} - \bar{y}_{..j} + \bar{y}_{...}\) 에 모형 대입:

\[ \bar{y}_{h.j} - \bar{y}_{h..} - \bar{y}_{..j} + \bar{y}_{...} = (\gamma\tau)_{hj} + \bar{e}_{h.j} - \bar{e}_{h..} - \bar{e}_{..j} + \bar{e}_{...}. \]

\(\pi_{i(h)}\)\(i\) 평균에서 소거됨.

\[ E[MS_{GT}] = \sigma_e^2 + \frac{\sum_h N_h \sum_j (\gamma\tau)_{hj}^2}{(s-1)(n-1)}. \]

5.6 E[MS] 요약표

변동 원인 \(df\) \(E[MS]\) \(H_0\) 하에서
집단(\(G\)) \(s-1\) \(\sigma_e^2 + n\sigma_\pi^2 + \frac{n\sum_h N_h \gamma_h^2}{s-1}\) \(\sigma_e^2 + n\sigma_\pi^2\)
집단 내 피험자 \(S(G)\) \(N-s\) \(\sigma_e^2 + n\sigma_\pi^2\) (항상)
시간(\(T\)) \(n-1\) \(\sigma_e^2 + \frac{N\sum_j\tau_j^2}{n-1}\) \(\sigma_e^2\)
집단×시간(\(GT\)) \((s-1)(n-1)\) \(\sigma_e^2 + \frac{\sum_{hj} N_h(\gamma\tau)_{hj}^2}{(s-1)(n-1)}\) \(\sigma_e^2\)
잔차(\(R\)) \((N-s)(n-1)\) \(\sigma_e^2\) (항상)

6 ANOVA 표와 F-검정

6.1 완전 ANOVA 표

변동 원인 \(df\) \(SS\) \(MS\) \(F\) 분모
집단 \(s-1\) \(SS_G\) \(MS_G\) \(MS_G / MS_{S(G)}\) \(MS_{S(G)}\)
집단 내 피험자 \(N-s\) \(SS_{S(G)}\) \(MS_{S(G)}\) \(MS_{S(G)}/MS_R\) \(MS_R\)
시간 \(n-1\) \(SS_T\) \(MS_T\) \(MS_T / MS_R\) \(MS_R\)
집단×시간 \((s-1)(n-1)\) \(SS_{GT}\) \(MS_{GT}\) \(MS_{GT} / MS_R\) \(MS_R\)
잔차 \((N-s)(n-1)\) \(SS_R\) \(MS_R\)
합계 \(Nn-1\) \(SS_{\text{Total}}\)

6.2 가설과 F-통계량

집단 주효과:

\[ H_G: \gamma_1 = \cdots = \gamma_s = 0 \quad F_G = \frac{MS_G}{MS_{S(G)}} \sim F_{s-1,\, N-s} \text{ under } H_G. \]

시간 주효과:

\[ H_T: \tau_1 = \cdots = \tau_n = 0 \quad F_T = \frac{MS_T}{MS_R} \sim F_{n-1,\, (N-s)(n-1)} \text{ under } H_T. \]

집단 × 시간 교호작용:

\[ H_{GT}: (\gamma\tau)_{hj} = 0 \; \forall h, j \quad F_{GT} = \frac{MS_{GT}}{MS_R} \sim F_{(s-1)(n-1),\, (N-s)(n-1)} \text{ under } H_{GT}. \]

집단 내 피험자 효과 (ICC 검정):

\[ H_{S(G)}: \sigma_\pi^2 = 0 \quad F_{S(G)} = \frac{MS_{S(G)}}{MS_R} \sim F_{N-s,\, (N-s)(n-1)} \text{ under } H_{S(G)}. \]


7 두 분모의 논리: 왜 F_G ≠ F_T의 분모

이 구조에서 가장 혼동하기 쉬운 부분이 집단 효과와 시간 효과의 분모가 다르다는 점이다.

7.1 집단 효과는 왜 \(MS_{S(G)}\)가 분모인가

집단에 대한 비교는 독립 집단 간 비교다. 피험자 1이 약물 집단에 속하면 위약 집단에는 절대 속하지 않는다(독립). 따라서 집단 간 차이를 검정할 때 오차의 기준은 같은 집단 내에서 피험자들이 얼마나 다른가, 즉 \(\sigma_\pi^2\)\(\sigma_e^2\) 를 합한 \(MS_{S(G)}\) 이다.

\(E[MS_G] = \sigma_e^2 + n\sigma_\pi^2 + \text{집단 신호}\)
\(E[MS_{S(G)}] = \sigma_e^2 + n\sigma_\pi^2\)

두 기댓값의 차이가 집단 신호이므로 \(F_G = MS_G / MS_{S(G)}\) 가 자연스럽다.

7.2 시간 효과와 교호작용은 왜 \(MS_R\)이 분모인가

시간 비교는 동일 피험자 내 비교다. 피험자 1이 2주차와 4주차 모두 측정된다(반복). 동일 피험자 내에서 시점 간 차이를 볼 때, 개인 특성 \(\pi_{i(h)}\)두 시점에 동일하게 작용하므로 차이를 취할 때 소거된다. 남는 오차는 순수 피험자-내 오차 \(\sigma_e^2\), 즉 \(MS_R\) 이다.

\(E[MS_T] = \sigma_e^2 + \text{시간 신호}\)
\(E[MS_R] = \sigma_e^2\)

따라서 \(F_T = MS_T / MS_R\) 이고, 이 F값은 개인차를 제거한 후의 시간 신호/노이즈 비이다.

흔한 실수: 집단 효과에 \(MS_R\)을 사용하는 경우

\(MS_R\) 을 집단 효과의 분모로 사용하면 \(\sigma_\pi^2\) 가 분모에서 빠지게 된다. 실제로는 \(E[MS_G]/E[MS_R] = 1 + n\sigma_\pi^2/\sigma_e^2 + \text{집단 신호}/\sigma_e^2\) 이어서 귀무가설 하에서도 F > 1 이 체계적으로 발생한다. 즉 1종 오류가 크게 증가한다.


8 가설 검정 전략

8.1 검정 순서 (교호작용 우선 원칙)

1단계: H_GT 검정 (집단×시간 교호작용)
         ↓
   유의? → 2a단계
   유의하지 않음? → 2b단계

2a단계 (교호작용 유의):
   - 집단별 시간 효과를 따로 분석 (단순 효과)
   - 시간별 집단 차이를 따로 분석 (단순 효과)
   - 주효과는 교호작용 맥락에서만 해석

2b단계 (교호작용 없음):
   - H_T: 시간 주효과 검정 (분모 MS_R)
   - H_G: 집단 주효과 검정 (분모 MS_S(G))
   - 두 주효과를 독립적으로 해석 가능

왜 교호작용을 먼저 검정하는가?

교호작용이 있으면 집단 주효과를 “시간 전반에 걸친 평균 집단 차이”로 요약하는 것이 의미를 잃는다. 예를 들어, 8주 시점에는 약물 집단이 더 낮고, 처음에는 두 집단이 비슷하다면 집단 주효과는 0에 가깝지만 분명히 의미 있는 처치 효과가 존재한다. 교호작용이 이것을 포착한다.

8.2 교호작용 해석: 네 가지 패턴

패턴 교호작용 의미
두 집단이 동일하게 시간에 따라 변화 없음 시간 주효과만 유의
두 집단이 시간에 무관하게 항상 다름 없음 집단 주효과만 유의
두 집단의 변화 기울기가 다름 있음 처치가 시간적 변화를 조절
두 집단이 교차 (순서가 바뀜) 있음 처치 효과가 반전됨

9 분산 성분 추정과 ICC

\(E[MS_{S(G)}] = \sigma_e^2 + n\sigma_\pi^2\)\(E[MS_R] = \sigma_e^2\) 를 역산:

\[ \widehat{\sigma}_e^2 = MS_R, \]

\[ \widehat{\sigma}_\pi^2 = \frac{MS_{S(G)} - MS_R}{n}. \]

\(MS_{S(G)} < MS_R\) 이면 \(\widehat{\sigma}_\pi^2 = 0\) 으로 처리한다.

급내상관계수(ICC):

\[ \widehat{\text{ICC}} = \frac{\widehat{\sigma}_\pi^2}{\widehat{\sigma}_\pi^2 + \widehat{\sigma}_e^2} = \frac{MS_{S(G)} - MS_R}{MS_{S(G)} + (n-1) MS_R}. \]

해석: ICC는 집단·시간·교호작용 고정 효과로 설명되지 않은 변동 중 피험자 간 개인차가 차지하는 비율이다. 다중 표본의 ICC는 집단 효과를 제거한 후의 개인차 수준을 반영한다.


10 집단×시간 교호작용의 심화 분해

10.1 교호작용을 직교 다항식으로 분해하는 이유

\(F_{GT}\) 가 유의하면 “어떤 종류의 교호작용인가?”를 파악해야 한다. 집단×시간 SS를 다항식 성분으로 분해하면 이를 정밀하게 진단할 수 있다.

선형 교호작용: “두 집단의 선형 변화 기울기가 다른가?”
→ 약물 집단은 매주 평균 2점 감소, 위약 집단은 0.5점 감소.

이차 교호작용: “두 집단의 변화 가속도/감속도가 다른가?”
→ 약물 집단은 초반에 빠르게 감소하다 안정화, 위약 집단은 선형.

10.2 수식

집단 \(h\) 의 시점별 평균 벡터를 \(\bar{\mathbf{y}}_{h.} = (\bar{y}_{h.1}, \ldots, \bar{y}_{h.n})'\) 라 하면, \(k\) 차 직교 다항식 대비 벡터 \(\mathbf{c}_k\) ( \(\|\mathbf{c}_k\| = 1\), 정규화)에 대해

\[ L_{hk} = \mathbf{c}_k' \bar{\mathbf{y}}_{h.} \quad \Rightarrow \quad \bar{L}_{.k} = \frac{1}{N}\sum_h N_h L_{hk}. \]

\(k\) 차 교호작용 SS:

\[ SS_{GT_k} = \sum_h N_h (L_{hk} - \bar{L}_{.k})^2, \quad df = s-1. \]

전체 교호작용 SS는

\[ \sum_{k=1}^{n-1} SS_{GT_k} = SS_{GT}. \]

각 성분의 F-통계량:

\[ F_{GT_k} = \frac{SS_{GT_k} / (s-1)}{MS_R} \sim F_{s-1,\,(N-s)(n-1)} \text{ under } H_0. \]

10.3 2개 집단, 4시점 예제 계산

약물 집단( \(N_1 = 30\) )과 위약 집단( \(N_2 = 30\) )의 시점별 평균이 다음과 같다고 하자.

시점 약물 위약
\(j=1\) (0주) 18.5 18.2
\(j=2\) (2주) 14.3 16.8
\(j=3\) (4주) 11.2 15.6
\(j=4\) (8주) 9.0 14.9

전체 시점 평균: \(\bar{y}_{..j}\) = \((13.85, 15.55, 13.40, 11.95)\)… (집단 가중 평균)

\(n=4\) 표준화 직교 다항식 계수:

\[ \mathbf{c}_1 = (-0.671, -0.224, 0.224, 0.671) \quad (\text{선형}) \]

\[ \mathbf{c}_2 = (0.5, -0.5, -0.5, 0.5) \quad (\text{이차}) \]

약물 집단 선형 대비:

\[ L_{1,1} = (-0.671)(18.5) + (-0.224)(14.3) + (0.224)(11.2) + (0.671)(9.0) = -4.99 \]

위약 집단 선형 대비:

\[ L_{2,1} = (-0.671)(18.2) + (-0.224)(16.8) + (0.224)(15.6) + (0.671)(14.9) = -1.32 \]

평균 선형 대비: \(\bar{L}_{.1} = (30 \times (-4.99) + 30 \times (-1.32))/60 = -3.155\)

선형 교호작용 SS:

\[ SS_{GT_1} = 30(-4.99 + 3.155)^2 + 30(-1.32 + 3.155)^2 = 30(3.363) + 30(3.363) = 201.8 + 100.8 = \cdots \]

해석: 약물 집단은 강한 음의 선형 추세( \(L = -4.99\) ), 위약 집단은 약한 음의 선형 추세 ( \(L = -1.32\) ). 선형 교호작용이 크면 “두 집단의 감소 속도가 다르다”는 결론이 나온다.


11 단순 효과 분석 (교호작용 유의 시)

교호작용이 유의하면 주효과만으로는 충분하지 않다. 단순 효과(simple effects)를 분석하여 구체적인 패턴을 파악한다.

11.1 방법 1: 각 집단 내 시간 효과

각 집단 \(h\) 에 대해 단일 표본 반복측정 ANOVA를 수행한다:

\[ F_{T|h} = \frac{SS_{T|h} / (n-1)}{SS_{R|h} / [(N_h-1)(n-1)]} \sim F_{n-1,\,(N_h-1)(n-1)}. \]

  • 약물 집단만 분석: “약물 집단에서 시간 효과가 유의한가?”
  • 위약 집단만 분석: “위약 집단에서 시간 효과가 유의한가?”

11.2 방법 2: 각 시점에서 집단 차이

시점 \(j\) 마다 독립 집단 \(t\)-검정 또는 일원 ANOVA를 수행한다:

\[ t_{j} = \frac{\bar{y}_{1.j} - \bar{y}_{2.j}}{\sqrt{MS_{S(G)}(1/N_1 + 1/N_2)}}. \]

주의: \(MS_{S(G)}\) 를 오차 기준으로 사용한다. \(MS_R\) 은 피험자-내 오차이므로 집단 간 비교에 부적절하다.

11.3 다중비교 조정

단순 효과는 복수의 검정이므로 Bonferroni 또는 Holm 조정을 적용한다:

  • 집단별 시간 효과: \(s\) 개 검정 → \(\alpha^* = \alpha/s\)
  • 시점별 집단 차이: \(n\) 개 검정 → \(\alpha^* = \alpha/n\)

12 예제: 임상시험 우울 척도 데이터

12.1 자료 설정

약물(Drug, \(N_1 = 30\)) vs. 위약(Placebo, \(N_2 = 30\)), 4시점(0, 2, 4, 8주). 종속변수: Hamilton 우울 척도(HAMD, 낮을수록 개선).

시점 평균(가상):

시점 Drug Placebo 전체
0주 18.5 18.2 18.35
2주 14.3 16.8 15.55
4주 11.2 15.6 13.40
8주 9.0 14.9 11.95
평균 13.25 16.375 14.81

12.2 ANOVA 표 (가상)

변동 원인 \(df\) \(SS\) \(MS\) \(F\) \(p\)
집단(G) 1 710.5 710.5 12.4 .001
집단 내 피험자 S(G) 58 3324.2 57.3 22.7 < .001
시간(T) 3 4253.8 1417.9 561.3 < .001
집단×시간(GT) 3 412.3 137.4 54.4 < .001
잔차(R) 174 439.8 2.53
합계 239 9140.6

12.3 분산 성분 추정

\[ \widehat{\sigma}_e^2 = MS_R = 2.53, \]

\[ \widehat{\sigma}_\pi^2 = \frac{MS_{S(G)} - MS_R}{n} = \frac{57.3 - 2.53}{4} = 13.69, \]

\[ \widehat{\text{ICC}} = \frac{13.69}{13.69 + 2.53} = 0.844. \]

해석: 피험자 간 개인차가 전체 변동의 84%를 설명한다. 같은 처치를 받아도 개인 반응이 매우 다양하다. 이 높은 ICC는 반복측정 설계의 검정력 이득이 크다는 것을 의미한다.

12.4 해석 순서

  1. 교호작용 유의 (\(F_{GT} = 54.4\), \(p < .001\)): 두 집단의 시간 변화 패턴이 다르다. 주효과 단독 해석은 부적절하다.

  2. 약물 집단 단순 시간 효과: HAMD가 18.5 → 9.0으로 급격히 감소. 직교 다항식 분해에서 강한 선형 추세와 유의한 감속(이차) 성분이 나타날 것으로 예상.

  3. 위약 집단 단순 시간 효과: HAMD가 18.2 → 14.9로 완만하게 감소. 선형 추세만 유의할 가능성이 높음.

  4. 교호작용 직교 분해: 선형 교호작용( \(F_{GT_1}\) )이 주도적이면 “두 집단의 감소 속도 차이”가 핵심 신호임을 확인.


13 Python · R 코드

13.1 Step 1: 순수 Python 구현 (원리 이해)

import numpy as np

# 실험 파라미터
s = 2       # 집단 수 (Drug, Placebo)
Nh = 30     # 집단당 피험자 수 (균형 설계)
n = 4       # 시점 수
N = s * Nh  # 전체 피험자 수

rng = np.random.default_rng(2026)

# 분산 성분 설정 (위 예제 근사)
sigma_pi = np.sqrt(13.69)
sigma_e  = np.sqrt(2.53)
mu = 14.81
gamma = np.array([-1.56, 1.56])          # 집단 효과 (합 = 0)
tau   = np.array([3.54, 0.74, -1.41, -2.86])  # 시간 효과 (합 ≈ 0)
# 교호작용: 약물은 더 빠른 감소
gt = np.array([
    [ 1.5,  0.8, -0.8, -1.5],   # Drug (h=0)
    [-1.5, -0.8,  0.8,  1.5],   # Placebo (h=1)
])

# 데이터 생성 (N x n 행렬, group 레이블)
pi_ih  = rng.normal(0, sigma_pi, N)          # 개인차
e_hij  = rng.normal(0, sigma_e,  (N, n))     # 오차
group  = np.repeat([0, 1], Nh)               # 0=Drug, 1=Placebo

Y = (mu
     + gamma[group][:, None]
     + pi_ih[:, None]
     + tau[None, :]
     + gt[group]
     + e_hij)   # N × n 행렬

# ---- SS 분해 ----
grand  = Y.mean()                          # 전체 평균
y_h    = np.array([Y[group==h].mean() for h in range(s)])  # 집단 평균 (s,)
y_hi   = Y.mean(axis=1)                    # 피험자 평균 (N,)
y_j    = Y.mean(axis=0)                    # 시점 전체 평균 (n,)
y_hj   = np.array([Y[group==h].mean(axis=0) for h in range(s)])  # (s, n)

SS_G    = n * sum(Nh * (y_h[h] - grand)**2 for h in range(s))
SS_SG   = n * sum(((y_hi[group==h] - y_h[h])**2).sum() for h in range(s))
SS_T    = N * ((y_j - grand)**2).sum()
SS_GT   = sum(Nh * ((y_hj[h] - y_h[h] - y_j + grand)**2).sum() for h in range(s))
SS_R    = sum(
    ((Y[group==h] - y_hi[group==h, None]
      - y_hj[h][None, :] + y_h[h])**2).sum()
    for h in range(s)
)
SS_tot  = ((Y - grand)**2).sum()

df_G, df_SG = s-1, N-s
df_T, df_GT, df_R = n-1, (s-1)*(n-1), (N-s)*(n-1)

MS = {k: v for k, v in zip(
    ['G', 'SG', 'T', 'GT', 'R'],
    [SS_G/df_G, SS_SG/df_SG, SS_T/df_T, SS_GT/df_GT, SS_R/df_R]
)}

F_G  = MS['G']  / MS['SG']
F_T  = MS['T']  / MS['R']
F_GT = MS['GT'] / MS['R']
F_SG = MS['SG'] / MS['R']

print("=== SS 분해 검산 ===")
print(f"SS 합계: {SS_G+SS_SG+SS_T+SS_GT+SS_R:.4f} vs {SS_tot:.4f}")

print("\n=== ANOVA 표 ===")
for name, df, ss, ms, f_val in [
    ('집단(G)',        df_G,  SS_G,  MS['G'],  F_G),
    ('집단내피험자',   df_SG, SS_SG, MS['SG'], F_SG),
    ('시간(T)',        df_T,  SS_T,  MS['T'],  F_T),
    ('집단×시간(GT)', df_GT, SS_GT, MS['GT'], F_GT),
    ('잔차(R)',        df_R,  SS_R,  MS['R'],  None),
]:
    f_str = f"{f_val:.2f}" if f_val else "—"
    print(f"  {name:<15} df={df:4d}  SS={ss:8.2f}  MS={ms:7.3f}  F={f_str}")

# 분산 성분 추정
sig_e2  = MS['R']
sig_pi2 = max((MS['SG'] - MS['R']) / n, 0)
icc     = sig_pi2 / (sig_pi2 + sig_e2)
print(f"\n분산 성분: σ²_e={sig_e2:.3f}, σ²_π={sig_pi2:.3f}, ICC={icc:.3f}")

# 직교 다항식 교호작용 분해 (선형, 이차, 삼차)
C = np.array([
    [-0.6708, -0.2236,  0.2236,  0.6708],
    [ 0.5,    -0.5,    -0.5,     0.5   ],
    [-0.2236,  0.6708, -0.6708,  0.2236],
])  # (3, n)

L_hk = (C @ y_hj.T).T   # (s, n-1) 집단별 다항식 대비
L_bar = (np.array([Nh]*s)[:, None] * L_hk).sum(axis=0) / N

print("\n=== 집단×시간 교호작용 직교 분해 ===")
for k, name in enumerate(['선형', '이차', '삼차']):
    ss_k = sum(Nh * (L_hk[h, k] - L_bar[k])**2 for h in range(s))
    f_k  = (ss_k / (s-1)) / MS['R']
    print(f"  {name}: L_Drug={L_hk[0,k]:.3f}, L_Placebo={L_hk[1,k]:.3f}, "
          f"SS={ss_k:.2f}, F={(s-1) and f_k:.2f}")

13.2 Step 2: R 구현 (실무)

library(tidyverse)
library(rstatix)
library(emmeans)

# ---- 데이터 준비 ----
set.seed(2026)
N_per_group <- 30
n_time      <- 4

clinical <- data.frame(
  subject = rep(1:(2 * N_per_group), each = n_time),
  group   = rep(c("Drug", "Placebo"), each = N_per_group * n_time),
  time    = rep(factor(c(0, 2, 4, 8)), times = 2 * N_per_group),
  hamd    = c(
    rnorm(N_per_group * n_time, mean = rep(c(18.5, 14.3, 11.2, 9.0), N_per_group)),
    rnorm(N_per_group * n_time, mean = rep(c(18.2, 16.8, 15.6, 14.9), N_per_group))
  )
)

# ---- 반복측정 ANOVA ----
res <- anova_test(
  data    = clinical,
  dv      = hamd,
  wid     = subject,
  between = group,
  within  = time
)

# GGe 보정 포함 ANOVA 표
get_anova_table(res)

# 구형성 검정
res$`Mauchly's Test for Sphericity`
res$`Sphericity Corrections`

# ---- 직교 다항식 교호작용 분해 ----
model_aov <- aov(hamd ~ group * time + Error(subject / time), data = clinical)
emm <- emmeans(model_aov, ~ time | group)

# 집단별 다항식 추세
contrast(emm, "poly")

# ---- 단순 효과: 집단별 시간 효과 ----
emm_by_group <- emmeans(model_aov, ~ time | group)
joint_tests(emm_by_group)          # 각 집단의 시간 효과 F-검정

# 집단별 사후 대비 (기준셀 = 0주)
contrast(emm_by_group, "trt.vs.ctrl", ref = "0")

# ---- 단순 효과: 시점별 집단 차이 ----
emm_by_time <- emmeans(model_aov, ~ group | time)
pairs(emm_by_time, adjust = "bonferroni")  # 각 시점에서 집단 비교

13.3 Step 3: Python statsmodels (실무)

import pandas as pd
import numpy as np
from statsmodels.stats.anova import AnovaRM
import statsmodels.formula.api as smf

# long format 데이터 (subject, group, time, hamd)
# AnovaRM은 within-subjects 요인만 처리
# group은 between 요인 — 직접 구현 또는 mixedlm 활용

# ---- 방법 1: 집단별 단순 시간 효과 ----
for g in ['Drug', 'Placebo']:
    sub = clinical[clinical['group'] == g]
    res_g = AnovaRM(data=sub, depvar='hamd', subject='subject', within=['time']).fit()
    print(f"\n{g} 집단 내 시간 효과:")
    print(res_g.summary())

# ---- 방법 2: Linear Mixed Model로 전체 검정 ----
model = smf.mixedlm(
    "hamd ~ group * time",
    data    = clinical,
    groups  = clinical["subject"],
    re_formula = "~1"   # random intercept (≈ σ²_π)
).fit()
print(model.summary())

# 교호작용 포함 여부 비교 (LRT)
model_no_int = smf.mixedlm(
    "hamd ~ group + time",
    data    = clinical,
    groups  = clinical["subject"],
).fit()

LRT_stat = -2 * (model_no_int.llf - model.llf)
from scipy.stats import chi2
p_lrt = chi2.sf(LRT_stat, df=n_time - 1)
print(f"\nLRT 교호작용 검정: χ²={LRT_stat:.2f}, df={n_time-1}, p={p_lrt:.4f}")

14 단일 표본과 다중 표본 반복측정 ANOVA 비교

특성 단일 표본 다중 표본
설계 이름 임의블록(Randomized Blocks) 분할구획(Split-Plot)
집단 수 1 \(s \geq 2\)
피험자-집단 관계 해당 없음 Nested
핵심 관심사 시간 주효과 집단×시간 교호작용
집단 분모 해당 없음 \(MS_{S(G)}\)
시간 분모 \(MS_R\) \(MS_R\)
오차 층위 수 1 2
집단 효과 자유도 해당 없음 \(s-1\)
잔차 자유도 \((N-1)(n-1)\) \((N-s)(n-1)\)

15 관련 주제

선행 지식

후속 주제

  • MANOVA — 다변량 반복측정: 구형성 가정 없음 (./144-manova.qmd)
  • Linear Mixed Model — MAR 결측 허용, 임의기울기 가능 (./LDA/01-mixed-model-intro.qmd)
  • GEE — 집단 평균 추정, 반공분산 구조 유연 (./LDA/08-mixed-model-gee-intro.qmd)

관련 개념

Subscribe

Enjoy this blog? Get notified of new posts by email: