일반 \(a \times b\) within design 의 multivariate 확장

Maxwell Ch.14.2 General a×b Within Multivariate Extension

\(2 \times 2\) 의 단순 형태에서 일반 \(a \times b\) within design 으로의 확장. 각 효과의 D variable 차원, 검정 통계량 (Hotelling \(T^2\), Wilks Λ) 의 자유도와 적용 절차, 직교 다항식 기반 trend 분해와의 통합, 작은 표본에서의 multivariate 한계를 정리한다. Maxwell Ch.6 (G-MAX6) 의 trend analysis 가 within-subjects 의 양적 시점 변수에 어떻게 자연스럽게 확장되는지 단계적으로 보여 준다.

Experimentation
DOE
저자

Kwangmin Kim

공개

2026년 05월 08일

1 \(a \times b\) Within 의 효과 차원

정의: 일반 \(a \times b\) within multivariate

피험자 \(i = 1, \ldots, n\)\(a \times b\) 모든 셀에서 측정. 셀 평균 \(Y_{ijk}\) (\(j = 1, \ldots, a\); \(k = 1, \ldots, b\)).

세 효과의 차원:

효과 자유도 D 차원 검정
\(A\) main \(a-1\) \(a-1\) one-sample \(T^2\)
\(B\) main \(b-1\) \(b-1\) one-sample \(T^2\)
\(A \times B\) \((a-1)(b-1)\) \((a-1)(b-1)\) one-sample \(T^2\)

자유도 1 효과 (\(a=2\) 또는 \(b=2\)) 는 paired \(t\)-test.

2 D variable 의 일반 구성

2.1 \(A\) main (across \(B\) 평균)

각 피험자 \(i\) 에 대해: \[ \bar Y^{(A)}_{ij} = \frac{1}{b} \sum_{k=1}^{b} Y_{ijk}, \quad j = 1, \ldots, a \]

D variable (직교 contrast 적용 가능): \[ D^{(A)}_{ij} = \sum_{j' = 1}^a c_{j'}^{(j)} \bar Y^{(A)}_{ij'}, \quad j = 1, \ldots, a-1 \]

2.2 \(B\) main

비슷하게 across \(A\) 평균: \[ \bar Y^{(B)}_{ik} = \frac{1}{a} \sum_{j=1}^a Y_{ijk} \] \[ D^{(B)}_{ik} = \sum_{k'} c_{k'}^{(k)} \bar Y^{(B)}_{ik'}, \quad k = 1, \ldots, b-1 \]

2.3 \(A \times B\) 의 D variable

직교 contrast 의 곱 (Kronecker product): \[ D^{(AB)}_{i, jk} = \sum_{j', k'} c_{j'}^{(j)} c_{k'}^{(k)} Y_{i, j', k'} \]

\((a-1)(b-1)\) 차원.

3 \(3 \times 4\) 사례

\(A\) = 3 약 종류 (A, B, C), \(B\) = 4 시점 (1, 2, 4, 8 시간 후), \(n = 18\).

3.1 차원

효과 \(df\) D 차원
\(A\) main 2 2
\(B\) main 3 3
\(A \times B\) 6 6

3.2 검정의 자유도

각 효과의 Hotelling \(T^2\)\(F\) 분포:

  • \(A\): \(F(p, n-p) = F(2, 16)\).
  • \(B\): \(F(p, n-p) = F(3, 15)\).
  • \(A \times B\): \(F(p, n-p) = F(6, 12)\).

3.3 검정력 점검 — \(A \times B\) 의 검정력 약

자유도 \((6, 12)\)\(F\) 검정 — 분모 자유도 12 작음. 효과 크기 보통 (\(f^2 \approx 0.1\)) 에서 검정력 ≈ 60%. 권장 표본:

차원 권장 \(n\) 추가 점
1 10 paired \(t\) 충분
2 15 \(T^2\) 권장
3 20 분모 ≥ 17
6 25 분모 ≥ 19
9 30+ 더 큰 표본

multivariate within 은 차원에 따라 표본 요구 ↑.

4 직교 다항식 기반 trend 분해

\(B\) 가 양적 (시점) 이면 D variable 을 직교 다항식으로 구성:

4.1 \(B\) main 의 trend 분해

\(B\) levels 양적 (1, 2, 4, 8 시간) — 등간격 아님. 직교 다항식 재계산 (G-MAX6-3) 필요.

또는 로그 변환 후 등간격 (\(\log_2 = 0, 1, 2, 3\)) → 표준 직교 다항식 사용:

선형: \((-3, -1, +1, +3)\). 이차: \((+1, -1, -1, +1)\). 삼차: \((-1, +3, -3, +1)\).

각 D variable: \[ D^{(B, \text{lin})}_i = \sum_k c_k^{\text{lin}} \bar Y^{(B)}_{ik} \] \[ D^{(B, \text{quad})}_i = \sum_k c_k^{\text{quad}} \bar Y^{(B)}_{ik} \] \[ D^{(B, \text{cub})}_i = \sum_k c_k^{\text{cub}} \bar Y^{(B)}_{ik} \]

각 차원이 독립적 의미 — 선형 trend, 이차 trend, 삼차 trend.

4.2 \(A \times B\) 의 trend 분해

\(A\) contrast × \(B\) trend contrast = 6 개 1 자유도 대비:

  • \(A_1 \times B_{\text{lin}}\)
  • \(A_1 \times B_{\text{quad}}\)
  • \(A_1 \times B_{\text{cub}}\)
  • \(A_2 \times B_{\text{lin}}\)
  • \(A_2 \times B_{\text{quad}}\)
  • \(A_2 \times B_{\text{cub}}\)

여기서 \(A_1, A_2\)\(A\) 의 두 직교 contrast (예: A vs B+C, B vs C).

각 1 자유도가 의미 있는 가설: - “\(A\) 의 첫 contrast 에서 \(B\) 의 선형 추세가 다른가?” → \(A_1 \times B_{\text{lin}}\). - “\(A\) 의 둘째 contrast 에서 \(B\) 의 이차 추세가 다른가?” → \(A_2 \times B_{\text{quad}}\).

5 Multivariate 통합 + Univariate 분해

직관: omnibus + 차원별 검정

multivariate \(T^2\) 는 omnibus — 효과가 어느 차원에서 오는지 모름.

omnibus 유의 → 각 차원의 univariate \(t\)-test 로 follow-up.

직교 다항식 사용 시 각 차원이 독립적 의미 (선형, 이차, …) — 해석 명확.

명목 contrast 사용 시 각 차원이 dose comparison (예: dose 1 vs dose 2 평균).

5.1 Bonferroni 보정

차원별 검정 시 FWER 보정:

\[ \alpha_{\text{corrected}} = \alpha / p \]

\(p\) = D 차원.

Bonferroni 가 보수적. Holm-Bonferroni 또는 step-down 더 강력.

5.2 Closed Testing Procedure

  1. omnibus \(T^2\) 가 유의해야 차원별 검정 진행.
  2. 각 차원의 univariate \(t\)\(p\) 값을 보정.

이는 Bonferroni 보다 검정력 ↑ — strong control of FWER.

6 가설 데이터 분석

6.1 약물 dose 별 시간 trajectory

요인: - \(A\) = 약 (placebo, drug A, drug B), 3 levels. - \(B\) = 시점 (1, 2, 4, 8 시간 후), 4 levels (로그 등간격).

피험자: \(n = 18\) 환자, 각 환자 모든 12 cell 측정.

6.2 가상 셀 평균

1h 2h 4h 8h
Placebo 80 78 75 70
Drug A 82 75 65 50
Drug B 81 78 70 60

해석 (visual): - Placebo: 시간 ↑ → 약간 ↓ (자연 회복). - Drug A: 시간 ↑ → 강한 ↓ (강한 효과). - Drug B: 시간 ↑ → 중간 ↓.

6.3 A main 의 multivariate

\(A\) levels 별 평균 응답 (across \(B\)):

  • Placebo: \((80+78+75+70)/4 = 75.75\)
  • Drug A: \((82+75+65+50)/4 = 68\)
  • Drug B: \((81+78+70+60)/4 = 72.25\)

D variable (Helmert contrast 가정): \[ D_1^{(A)} = \text{Drug A} - \text{Placebo} = -7.75 \] \[ D_2^{(A)} = \text{Drug B} - \text{Placebo} = -3.5 \]

Hotelling \(T^2\) on \(\bar{\mathbf{D}}^{(A)} = (-7.75, -3.5)\) — 2 차원.

6.4 B main 의 trend

\(\log_2 d \in \{0, 1, 2, 3\}\) 등간격. 표준 직교 다항식.

각 시점의 평균 응답 (across \(A\)):

  • 1h: \((80+82+81)/3 = 81\)
  • 2h: \(77\)
  • 4h: \(70\)
  • 8h: \(60\)

D variables: - \(D^{B,\text{lin}}\): \(-3(81) - 1(77) + 1(70) + 3(60) = -243 - 77 + 70 + 180 = -70\). - \(D^{B,\text{quad}}\): \(1(81) - 1(77) - 1(70) + 1(60) = -6\). - \(D^{B,\text{cub}}\): \(-1(81) + 3(77) - 3(70) + 1(60) = -81 + 231 - 210 + 60 = 0\).

해석: 강한 선형 감소, 약한 이차 (ceiling 효과 약), 삼차 0.

각 차원의 univariate \(t\) 검정: - linear \(t \approx -10\): 매우 유의. - quadratic \(t \approx -1\): 비유의. - cubic \(t \approx 0\): 비유의.

6.5 A × B 의 trend 분해

\(A_1\) (Drug A vs Placebo), \(A_2\) (Drug B vs Placebo), \(B\) trend 와 곱:

Contrast 의미
\(A_1 \times B_{\text{lin}}\) Drug A 의 선형 감소가 Placebo 와 다른가?
\(A_2 \times B_{\text{lin}}\) Drug B 의 선형 감소가 Placebo 와 다른가?
\(A_1 \times B_{\text{quad}}\) Drug A 의 이차 추세가 Placebo 와 다른가?

Drug A 가 가장 강한 선형 감소 → \(A_1 \times B_{\text{lin}}\) 강하게 유의.

7 Python 코드 — 일반 \(a \times b\)

import numpy as np
import pandas as pd
from scipy import stats

np.random.seed(2026)
n = 18
A_levels = ["Placebo", "DrugA", "DrugB"]
B_levels = [1, 2, 4, 8]  # 시간 (hours)
log2_B = [0, 1, 2, 3]  # log2 등간격

cell_means = {
    ("Placebo", 1): 80, ("Placebo", 2): 78, ("Placebo", 4): 75, ("Placebo", 8): 70,
    ("DrugA", 1): 82, ("DrugA", 2): 75, ("DrugA", 4): 65, ("DrugA", 8): 50,
    ("DrugB", 1): 81, ("DrugB", 2): 78, ("DrugB", 4): 70, ("DrugB", 8): 60,
}

records = []
for subj in range(n):
    pi = np.random.normal(0, 5)
    for a in A_levels:
        for b in B_levels:
            y = cell_means[(a, b)] + pi + np.random.normal(0, 2)
            records.append({"subject": subj, "A": a, "B": b, "Y": y})
data = pd.DataFrame(records)

# A main (across B 평균)
A_means = data.groupby(["subject", "A"])["Y"].mean().unstack()
D_A = pd.DataFrame({
    "DrugA-Placebo": A_means["DrugA"] - A_means["Placebo"],
    "DrugB-Placebo": A_means["DrugB"] - A_means["Placebo"],
})
D_bar_A = D_A.mean().values
S_D_A = D_A.cov().values
T2_A = n * D_bar_A @ np.linalg.inv(S_D_A) @ D_bar_A
F_A = (n - 2) / (2 * (n - 1)) * T2_A
p_A = 1 - stats.f.cdf(F_A, 2, n - 2)
print(f"=== A main ===")
print(f"  D̄ = {D_bar_A}")
print(f"  T² = {T2_A:.2f}, F({2}, {n-2}) = {F_A:.2f}, p = {p_A:.4f}")

# B main with orthogonal polynomial contrasts (log_2 등간격)
B_means = data.groupby(["subject", "B"])["Y"].mean().unstack()
c_lin = np.array([-3, -1, 1, 3]) / np.sqrt(20)
c_quad = np.array([1, -1, -1, 1]) / 2
c_cub = np.array([-1, 3, -3, 1]) / np.sqrt(20)
D_B = pd.DataFrame({
    "B_lin": B_means.values @ c_lin,
    "B_quad": B_means.values @ c_quad,
    "B_cub": B_means.values @ c_cub,
})
D_bar_B = D_B.mean().values
S_D_B = D_B.cov().values
T2_B = n * D_bar_B @ np.linalg.inv(S_D_B) @ D_bar_B
F_B = (n - 3) / (3 * (n - 1)) * T2_B
p_B = 1 - stats.f.cdf(F_B, 3, n - 3)
print(f"\n=== B main (linear/quadratic/cubic) ===")
print(f"  D̄ = {D_bar_B}")
print(f"  T² = {T2_B:.2f}, F = {F_B:.2f}, p = {p_B:.4f}")

# 차원별 univariate t-test
print("\n=== B trend 차원별 검정 ===")
for col in D_B.columns:
    t, p = stats.ttest_1samp(D_B[col], 0)
    bon_p = min(1, p * 3)
    print(f"  {col}: t = {t:.2f}, raw p = {p:.4f}, Bonferroni p = {bon_p:.4f}")

# A × B interaction (단순화)
# 각 피험자에 대해 12 차원 vector → 직교 contrast 곱으로 6 차원 D
# (구현 복잡 — statsmodels 의 MANOVA 활용 권장)
from statsmodels.multivariate.manova import MANOVA
wide = data.pivot_table(index="subject", columns=["A", "B"], values="Y").reset_index()
# MANOVA 형식으로 long → wide 변환 후 fit

8 가정과 한계

8.1 Multivariate 정규성

각 D variable 의 다변량 정규.

검정: Mardia’s test, Henze-Zirkler. 큰 \(n\) 에서 robust.

8.2 표본 충분

$n > $ 가장 큰 D 차원. 권장 $n $ 차원.

8.3 Sphericity 회피의 trade-off

multivariate 는 sphericity 가정 없지만 자유도 손실. 작은 \(n\) 에서는 univariate + ε 조정이 검정력 ↑.

8.4 결측 데이터

multivariate 는 listwise. 한 cell 결측이면 그 피험자 전체 제거.

대안: multilevel model (REML) 로 결측 자동 처리.

9 Multilevel 과의 통합

직관: multivariate 와 multilevel 의 동치성

균등 완전 데이터에서 두 framework 가 동일 결과:

  • Multivariate (D variable + Hotelling \(T^2\)): UN covariance 가정.
  • Multilevel (mixed model with UN R structure): 동일 가정.

차이: - Multivariate: 명시적 vector 표현. 결측 시 listwise. - Multilevel: long format, 결측 자동 처리.

실무 권장: multilevel (R lme4, Python mixedlm) — 결측 우위, 비균등 데이터에 강. 정통 DOE textbook 의 multivariate 는 균등 데이터에 simple.

10 응용 — 실무 사례

10.1 1. 임상 longitudinal RCT

처치 (between, \(A\)) × 시점 (within, \(B\)). 시점이 양적이면 trend 분해.

가장 관심: \(A \times B_{\text{linear}}\) — “처치군이 시간에 따라 다른 변화율?”

10.2 2. 발달 심리학

연령 (within) × 학습 condition (within). 같은 어린이가 여러 연령에서 측정.

10.3 3. 운동학

처치 (within) × 측정 위치 (within) — 같은 사람의 다른 근육에 다른 처치.

10.4 4. ML hyperparameter

같은 모델 architecture × 다른 epoch (시점) 측정. epoch 의 trend.

11 본 시리즈

G-MAX14-0  개관
G-MAX14-1  2×2 D Variable Formation
G-MAX14-2  a×b Extension  ← 현재 글
G-MAX14-3  Split-Plot Multivariate + Decision
    ↓
G-MAX15 (Multilevel — 통합)

12 관련 주제

선행 지식

후속 주제

다른 카테고리 연결

13 더 읽을 거리

  • Maxwell, S. E., Delaney, H. D. (2004). “Designing Experiments and Analyzing Data: A Model Comparison Perspective” (2nd ed). Lawrence Erlbaum.
  • Davis, C. S. (2002). “Statistical Methods for the Analysis of Repeated Measurements.” Springer — repeated measurements 의 종합.
  • Tabachnick, B. G., Fidell, L. S. (2019). “Using Multivariate Statistics” (7th ed). Pearson.
  • Hand, D. J., Taylor, C. C. (1987). “Multivariate Analysis of Variance and Repeated Measures.” Chapman & Hall.

Subscribe

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