1 개요
통계학 입문 교육에서 ANOVA와 회귀분석은 별개의 방법론으로 소개된다. ANOVA는 “그룹 간 평균이 같은가?”를, 회귀는 “X가 변할 때 Y가 얼마나 변하는가?”를 묻는다고 배운다. 하지만 Casella & Berger (2002, Ch.11)는 두 방법을 하나의 챕터에서 함께 다룬다 — 그 이유는 수학적 구조가 동일하기 때문이다.
이 포스트는 Casella & Berger Ch.11의 순서를 따라, 일원 분산분석과 단순 선형 회귀를 같은 선형 모델 프레임워크 안에서 정리한다.
2 일원 분산분석 (One-Way ANOVA)
2.1 모형 정의
Casella & Berger는 일원 분산분석을 두 가지 동치인 방식으로 정의한다 (Casella & Berger, 2002, Ch.11).
\[ Y_{ij} = \theta_i + \epsilon_{ij}, \quad i = 1, \ldots, k, \quad j = 1, \ldots, n_i \]
- \(Y_{ij}\): \(i\) 번째 처리(그룹)의 \(j\) 번째 관측값
- \(\theta_i\): 처리 \(i\) 의 모평균 (추정할 미지 모수)
- \(\epsilon_{ij}\): 오차항 — \(E\epsilon_{ij} = 0\), \(\text{Var}\,\epsilon_{ij} = \sigma^2\)
\(E\,\epsilon_{ij} = 0\) 이므로 \(E\,Y_{ij} = \theta_i\). 즉, \(\theta_i\) 는 처리 \(i\) 의 기대값이다.
학교의 여러 반에서 학생 키를 측정한다고 하자. 각 반의 평균 키가 \(\theta_i\) 이고, 개별 학생은 반 평균 주위에서 \(\epsilon_{ij}\) 만큼 흩어진다. 셀 평균 모형은 ’반 효과(어느 반인가)’와 ’개인 변동(같은 반 안에서의 차이)’을 분리하는 것이다.
\[ Y_{ij} = \mu + \tau_i + \epsilon_{ij}, \quad i = 1, \ldots, k, \quad j = 1, \ldots, n_i \]
- \(\mu\): 전체 평균(grand mean) — 처리들의 공통 기준 수준
- \(\tau_i\): 처리 \(i\) 의 효과 — 전체 평균으로부터의 이탈량
\(E\,Y_{ij} = \mu + \tau_i\) 이므로, \(k\) 개 처리 평균에 대해 \(k + 1\) 개의 모수 \((\mu, \tau_1, \ldots, \tau_k)\) 가 존재한다. 이는 식별불가능(not identifiable) 모형이다.
식별성 제약 (identifiability constraint): \(\sum_{i=1}^k \tau_i = 0\)
이 제약을 추가하면 \(\tau_i\) 의 해석이 “전체 평균으로부터의 이탈”로 명확해지고 모형이 식별 가능해진다.
키 차이를 설명할 때 ’전체 평균이 170이고 A반은 +5, B반은 +5, C반은 -10’이라고 하자. 그런데 전체 평균을 175로 잡으면 A반은 0, B반은 0, C반은 -15가 된다. 결과(예측값)는 같지만 모수가 다르다 — 이것이 식별불가능이다. \(\sum \tau_i = 0\) 제약은 기준선을 고정해 이 모호함을 제거한다.
두 모형은 동치다. \(\theta_i = \mu + \tau_i\) 로 놓으면 같은 분포를 기술한다. Casella & Berger는 해석이 더 직관적인 세포 평균 모형 (11.2.1)을 선호하지만, 복잡한 ANOVA 설계에서는 과모수화 모형 (11.2.2)의 해석적 이점이 있다.
과모수화 모형 \(Y_{ij} = \mu + \tau_i + \epsilon_{ij}\) 를 행렬로 쓰면 \(\mathbf{Y} = \mathbf{X}\boldsymbol{\beta} + \boldsymbol{\epsilon}\) 이다. 설계 행렬 \(\mathbf{X}\) 는 전체 평균을 나타내는 열(상수 1로 구성)과 각 처리 효과 \(\tau_i\) 를 나타내는 \(k\) 개의 열로 구성된다.
핵심 문제는 선형 종속(linear dependence) 이다. 처리 열들의 합이 상수 열과 완전히 일치한다:
\[ \text{(상수 열)} = \sum_{i=1}^{k} \text{(처리 } i \text{ 열)} \]
이 구조에서는 임의의 상수 \(c\) 에 대해 \(\mu \to \mu + c\), \(\tau_i \to \tau_i - c\) 로 동시에 바꿔도 예측값 \(\mu + \tau_i\) 가 변하지 않는다. 따라서 최소제곱 정규방정식 \((X^TX)\hat{\boldsymbol{\beta}} = X^T\mathbf{Y}\) 에서 \(X^TX\) 의 역행렬이 존재하지 않아 고유한 해를 구할 수 없다 — 이것이 Rank Deficiency의 실체다.
\[ \text{rank}(\mathbf{X}) = k < k + 1 = \text{열 수} \]
제약 \(\sum \tau_i = 0\) 은 이 자유도를 하나 제거하여 \(\mathbf{X}\) 를 full rank로 만들고, 역행렬의 존재를 회복한다.
식별성을 확보하는 방법은 두 가지가 있으며, 어느 쪽을 택해도 모형의 예측력(fit)은 동일하다. 달라지는 것은 \(\tau_i\) 의 해석뿐이다.
| 제약 방식 | 조건 | \(\tau_i\) 의 해석 | 주요 사용처 |
|---|---|---|---|
| Sum Constraint (합-0 제약) | \(\sum_{i=1}^k \tau_i = 0\) | “전체 평균으로부터의 이탈량” | 교재, 실험계획법, 균형 설계 |
| Corner-point Constraint (처리 제약) | \(\tau_1 = 0\) (기준 집단 고정) | “기준 집단 대비 차이” | R의 lm(), Python statsmodels의 기본값 |
R이나 Python에서 범주형 변수를 회귀에 넣으면 Corner-point 방식을 기본으로 사용한다. 따라서 소프트웨어 출력에서 \(\tau_2, \tau_3, \ldots\) 의 계수는 “기준 집단 \(\tau_1 = 0\) 대비 차이”로 해석해야 한다.
불균형 설계(unbalanced design)에서의 Sum Constraint: 집단별 샘플 사이즈 \(n_i\) 가 다를 때, 단순 합 제약(\(\sum \tau_i = 0\)) 대신 가중 합 제약을 사용해야 \(\mu\) 가 전체 가중 평균으로서의 의미를 유지한다:
\[ \sum_{i=1}^k n_i \tau_i = 0 \]
2.2 가정
일원 ANOVA의 고전적 세 가지 가정이다 (Casella & Berger, 2002, Ch.11):
| 번호 | 가정 | 내용 |
|---|---|---|
| (i) | 비상관(uncorrelated) 오차 | \(E\epsilon_{ij} = 0\), \(\text{Var}\,\epsilon_{ij} = \sigma_i^2 < \infty\); 서로 다른 오차 간 공분산 0 |
| (ii) | 정규 오차(normal errors) | \(\epsilon_{ij} \sim N(0, \sigma^2)\) |
| (iii) | 등분산(homoscedasticity) | \(\sigma_i^2 = \sigma^2\) for all \(i\) |
가정 (iii)은 가정 (ii)와 연관성이 크다. Box (1954)는 정규성 가정에 대한 F 검정의 강건성이 등분산성 충족 여부에 크게 의존한다고 보였다.
2.3 귀무가설
ANOVA의 고전적 귀무가설은 모든 처리 평균의 동일성이다 (Casella & Berger, 2002, 식 11.2.3):
\[ H_0: \theta_1 = \theta_2 = \cdots = \theta_k \quad \text{vs} \quad H_1: \theta_i \neq \theta_j \text{ for some } i, j \]
Casella & Berger는 이 귀무가설이 종종 “말이 안 되는(silly)” 가설이라고 지적한다 — 처리들이 완전히 동일한 효과를 가질 것이라고 믿는 실험자는 드물기 때문이다. 실제 관심은 어떤 처리가 더 나은가를 추정하는 것에 있다. F 검정은 이를 위한 출발점이지, 최종 목표가 아니다.
2.4 대비 (Contrasts)
ANOVA 귀무가설을 더 작고 해석 가능한 조각으로 분해하는 핵심 도구가 대비이다 (Casella & Berger, 2002, 정의 11.2.4).
\(t = (t_1, \ldots, t_k)\) 가 모수 또는 통계량들이고, \(a = (a_1, \ldots, a_k)\) 가 알려진 상수들일 때, \(\sum_{i=1}^k a_i t_i\) 를 선형 결합(linear combination)이라 한다.
이 중 \(\sum_{i=1}^k a_i = 0\) 을 추가로 만족하면 대비(contrast)라 한다.
예를 들어 \(a = (1, -1, 0, \ldots, 0)\) 으로 정의한 대비 \(\sum a_i \theta_i = \theta_1 - \theta_2\) 는 처리 1과 처리 2의 평균 차이를 나타낸다.
핵심 정리 (Casella & Berger, 정리 11.2.5): \(\theta_1 = \theta_2 = \cdots = \theta_k\) 일 필요충분조건은 \(\sum_{i=1}^k a_i = 0\) 을 만족하는 모든 \(a\) 에 대해 \(\sum_{i=1}^k a_i \theta_i = 0\) 이 성립하는 것이다.
이로부터 ANOVA 귀무가설 \(H_0\)는 모든 대비가 0이라는 가설과 동치임이 따른다. 이 관점은 검정을 단변량 t 검정들의 합집합-교집합(union-intersection) 구조로 이해하게 해 준다.
대비를 이용한 단일 선형 결합의 t 검정 (Casella & Berger, 식 11.2.6):
\[ \frac{\sum_{i=1}^k a_i \bar{Y}_{i\cdot} - \sum_{i=1}^k a_i \theta_i}{\sqrt{S_p^2 \sum_{i=1}^k a_i^2 / n_i}} \sim t_{N-k} \]
여기서 합동 분산 추정량(pooled variance estimator) \(S_p^2\) 는 다음과 같다 (Casella & Berger, 식 11.2.5):
\[ S_p^2 = \frac{1}{N - k} \sum_{i=1}^k \sum_{j=1}^{n_i} (Y_{ij} - \bar{Y}_{i\cdot})^2 \]
\(N = \sum_{i=1}^k n_i\), \((N - k)S_p^2/\sigma^2 \sim \chi^2_{N-k}\).
왜 풀링(pooling)하는가? 각 집단의 표본 분산은 \(n_i\) 가 작으면 불안정하다. 모든 집단이 같은 \(\sigma^2\) 를 공유한다고 가정하면, \(k\) 개의 불안정한 추정치를 자유도 가중 평균으로 합쳐 하나의 안정적 추정치를 얻는다. 이것이 풀링의 핵심이다.
2.5 분산 분해: SST = SSB + SSW
ANOVA의 핵심 결과는 총 변동을 처리 간(between) 변동과 처리 내(within) 변동으로 분해하는 것이다 (Casella & Berger, 정리 11.2.11, 식 11.2.15):
\[ \underbrace{\sum_{i=1}^k \sum_{j=1}^{n_i} (Y_{ij} - \bar{\bar{Y}})^2}_{\text{SST}} = \underbrace{\sum_{i=1}^k n_i (\bar{Y}_{i\cdot} - \bar{\bar{Y}})^2}_{\text{SSB}} + \underbrace{\sum_{i=1}^k \sum_{j=1}^{n_i} (Y_{ij} - \bar{Y}_{i\cdot})^2}_{\text{SSW}} \]
표기: \(\bar{Y}_{i\cdot} = \frac{1}{n_i}\sum_j Y_{ij}\) (처리 \(i\) 의 표본평균), \(\bar{\bar{Y}} = \frac{1}{N}\sum_i\sum_j Y_{ij}\) (전체 표본평균).
| 항 | 이름 | 의미 | 자유도 |
|---|---|---|---|
| SST | Total Sum of Squares | 전체 변동 | \(N - 1\) |
| SSB | Between-treatment Sum of Squares | 처리 간 변동 | \(k - 1\) |
| SSW | Within-treatment Sum of Squares | 처리 내 변동(오차) | \(N - k\) |
정규성 가정 하에서 분포 (Casella & Berger, 식 11.2.16-11.2.17):
\[ \frac{\text{SSW}}{\sigma^2} \sim \chi^2_{N-k} \quad (\text{항상 성립}) \]
\[ \frac{\text{SSB}}{\sigma^2} \sim \chi^2_{k-1} \quad (H_0 \text{ 하에서만}) \]
SSB와 SSW는 독립이므로, \(H_0\) 하에서:
\[ F = \frac{\text{SSB}/(k-1)}{\text{SSW}/(N-k)} = \frac{\text{MSB}}{\text{MSW}} \sim F_{k-1,\, N-k} \]
\(H_1\) 이 참이면 SSB 가 커져서 \(F\) 값도 커지는 경향이 있다. 따라서 기각역은 우측 꼬리( \(F > F_{k-1,N-k,\alpha}\) )에 설정한다.
\(H_0\) 하에서 집단 평균의 차이는 순전히 잡음이다. SSB 는 잡음의 제곱합이므로 \(\chi^2\) 을 따른다. \(H_1\) 하에서는 진짜 처리 효과가 집단 평균을 밀어내므로 SSB 가 \(\chi^2\) 보다 더 커진다. 반면 SSW 는 집단 내부 변동이라 처리 효과와 무관하게 항상 \(\chi^2\) 이다. 따라서 \(F = \text{MSB}/\text{MSW}\) 가 1보다 크면 처리 효과의 증거이다.
2.6 ANOVA 표 (Table 11.2.1, Casella & Berger)
| 변동 원천 | 자유도 | 제곱합 | 평균제곱 | F 통계량 |
|---|---|---|---|---|
| 처리 간(Between) | \(k - 1\) | \(\text{SSB} = \sum n_i(\bar{Y}_{i\cdot} - \bar{\bar{Y}})^2\) | \(\text{MSB} = \text{SSB}/(k-1)\) | \(F = \text{MSB}/\text{MSW}\) |
| 처리 내(Within) | \(N - k\) | \(\text{SSW} = \sum\sum(Y_{ij} - \bar{Y}_{i\cdot})^2\) | \(\text{MSW} = \text{SSW}/(N-k)\) | |
| 전체(Total) | \(N - 1\) | \(\text{SST} = \sum\sum(Y_{ij} - \bar{\bar{Y}})^2\) |
3 단순 선형 회귀 (Simple Linear Regression)
3.1 모형 정의
단순 선형 회귀는 반응변수 \(Y_i\) 와 예측변수 \(x_i\) 사이의 선형 관계를 모형화한다 (Casella & Berger, 2002, §11.3):
\[ Y_i = \alpha + \beta x_i + \epsilon_i, \quad i = 1, \ldots, n \]
- \(\alpha\): 절편(intercept) — 미지 모수
- \(\beta\): 기울기(slope) — 미지 모수
- \(x_i\): 예측변수 — 고정된 관측값
- \(\epsilon_i\): 오차항 — \(E\epsilon_i = 0\)
모집단 회귀함수(population regression function):
\[ E(Y_i | x_i) = \alpha + \beta x_i \]
\(\beta\) 의 해석: \(x_i\) 가 한 단위 증가할 때 \(Y_i\) 의 기대값이 \(\beta\) 만큼 변한다.
“선형 회귀”는 모수에 대한 선형성을 의미한다. \(E(Y_i|x_i) = \alpha + \beta x_i^2\) 도 선형 회귀이고 (모수 \(\alpha, \beta\) 에 대한 선형), \(E(Y_i|x_i) = \alpha + \beta^2 x_i\) 는 선형 회귀가 아니다.
3.2 최소제곱 추정량
다음 기본 통계량을 정의한다 (Casella & Berger, 식 11.3.5-11.3.7):
\[ S_{xx} = \sum_{i=1}^n (x_i - \bar{x})^2, \quad S_{yy} = \sum_{i=1}^n (y_i - \bar{y})^2, \quad S_{xy} = \sum_{i=1}^n (x_i - \bar{x})(y_i - \bar{y}) \]
잔차제곱합(RSS) \(\sum_{i=1}^n (y_i - (c + dx_i))^2\) 를 최소화하는 추정량은 (Casella & Berger, 식 11.3.8-11.3.10):
\[ \hat{\beta} = b = \frac{S_{xy}}{S_{xx}}, \qquad \hat{\alpha} = a = \bar{y} - b\bar{x} \]
이는 정규방정식(normal equations)을 풀거나, 편미분을 0으로 놓아 구한다. 분포 가정이 없어도 이 공식은 항상 성립한다(순수 수학적 최소화 결과).
가우스-마르코프 정리의 맥락: 정규 오차 가정 하에서 \(b = S_{xy}/S_{xx}\) 는 \(\beta\) 의 UMVUE이기도 하다.
결정계수( \(R^2\) )는 예측변수가 반응변수 분산의 몇 %를 설명하는지를 나타낸다:
\[ R^2 = \frac{S_{xy}^2}{S_{xx} \cdot S_{yy}} = \frac{\text{SSReg}}{\text{SST}} \]
\(R^2 \in [0, 1]\). ANOVA에서는 동일한 양을 eta-squared( \(\eta^2\) )라 부른다.
4 통합 프레임워크: 선형 모델
ANOVA와 회귀 모두 설계 행렬(design matrix) \(\mathbf{X}\) 를 통해 동일한 수식으로 표현된다 (Casella & Berger, 2002, Ch.11):
\[ \mathbf{Y} = \mathbf{X}\boldsymbol{\beta} + \boldsymbol{\varepsilon}, \quad \boldsymbol{\varepsilon} \sim N(\mathbf{0}, \sigma^2 \mathbf{I}_n) \]
OLS 추정량:
\[ \hat{\boldsymbol{\beta}} = (\mathbf{X}^\top \mathbf{X})^{-1} \mathbf{X}^\top \mathbf{Y} \]
사영 행렬(hat matrix):
\[ \mathbf{H} = \mathbf{X}(\mathbf{X}^\top \mathbf{X})^{-1}\mathbf{X}^\top, \quad \hat{\mathbf{Y}} = \mathbf{H}\mathbf{Y} \]
\(\mathbf{H}\) 는 \(\mathbf{Y}\) 를 \(\mathbf{X}\) 의 열공간으로 직교사영한다. \(\text{SS}_\text{Reg} = \hat{\mathbf{Y}}^\top\hat{\mathbf{Y}} - N\bar{Y}^2 = \|\mathbf{H}\mathbf{Y} - \bar{Y}\mathbf{1}\|^2\).
설계 행렬 \(\mathbf{X}\) 의 내용이 무엇인가에 따라 회귀와 ANOVA가 갈린다.
| \(\mathbf{X}\) 의 내용 | 방법론 | 연구 질문 |
|---|---|---|
| 연속형 예측변수 | 단순/다중 회귀 | \(x\) 가 한 단위 증가할 때 \(Y\) 는 얼마나 변하는가? |
| 더미변수 (범주형) | ANOVA | 그룹 간 평균에 차이가 있는가? |
| 연속형 + 더미변수 혼합 | ANCOVA | 공변량을 통제한 후 그룹 차이가 있는가? |
세 경우 모두 \(\hat{\boldsymbol{\beta}} = (\mathbf{X}^\top \mathbf{X})^{-1} \mathbf{X}^\top \mathbf{Y}\) 로 추정한다.
4.1 ANOVA를 회귀로 표현하기: 더미변수 코딩
\(k = 3\) 그룹(A, B, C) 일원 ANOVA를 회귀로 표현하면:
처리 코딩(treatment coding): 그룹 A를 기준 범주(reference)로 설정하고, \(k-1 = 2\) 개의 더미변수를 만든다.
\[ d_{1i} = \begin{cases} 1 & Y_{ij} \in \text{그룹 B} \\ 0 & \text{otherwise} \end{cases}, \qquad d_{2i} = \begin{cases} 1 & Y_{ij} \in \text{그룹 C} \\ 0 & \text{otherwise} \end{cases} \]
설계 행렬:
\[ \mathbf{X} = \begin{bmatrix} 1 & 0 & 0 \\[-2pt] \vdots & \vdots & \vdots \\[-2pt] 1 & 1 & 0 \\[-2pt] \vdots & \vdots & \vdots \\[-2pt] 1 & 0 & 1 \\[-2pt] \vdots & \vdots & \vdots \end{bmatrix} \leftarrow \text{(A 그룹 행들)} \]
OLS 추정량의 ANOVA 해석:
| 계수 | 세포평균 모형 해석 |
|---|---|
| \(\hat{\beta}_0 = \hat{\alpha}\) | 기준 그룹(A)의 표본평균 \(\bar{Y}_{A\cdot}\) |
| \(\hat{\beta}_1\) | \(\bar{Y}_{B\cdot} - \bar{Y}_{A\cdot}\) (B vs A 대비) |
| \(\hat{\beta}_2\) | \(\bar{Y}_{C\cdot} - \bar{Y}_{A\cdot}\) (C vs A 대비) |
ANOVA 귀무가설 \(H_0: \theta_1 = \theta_2 = \theta_3\) 은 회귀에서 \(H_0: \beta_1 = \beta_2 = 0\) 과 동치이다.
4.2 t 검정은 ANOVA의 특수 경우
\(k = 2\) 인 경우, ANOVA F 통계량과 독립표본 t 통계량 사이에 다음이 성립한다.
\[ F_{1,\,N-2} = t_{N-2}^2 \]
분자 자유도가 1인 F 분포는 항상 t 분포의 제곱과 동일하다. 즉, 두 그룹 비교(t 검정)는 k=2 ANOVA의 특수 경우이고, ANOVA는 두 그룹 이상으로의 일반화이다.
\[ \text{t-test } (k=2) \subset \text{ANOVA } (k \geq 2) \subset \text{선형 회귀} \subset \text{GLM} \]
5 수치 예시: Casella 독소 데이터
Casella & Berger 예제 11.2.1 — 세 가지 독소와 대조군이 송어 간에 미치는 영향.
| 독소 1 | 독소 2 | 독소 3 | 대조군 |
|---|---|---|---|
| 28, 23, 14, 27 | 33, 36, 34, 29, 31, 34 | 18, 21, 20, 22, 24 | 11, 14, 11, 16 |
그룹 평균: \(\bar{Y}_{1\cdot} = 23.0\), \(\bar{Y}_{2\cdot} = 32.83\), \(\bar{Y}_{3\cdot} = 21.0\), \(\bar{Y}_{4\cdot} = 13.0\). 전체 \(N = 19\), \(k = 4\).
ANOVA 표 (Casella 예제 11.2.12):
| 변동 원천 | df | SS | MS | F |
|---|---|---|---|---|
| 처리 간 | 3 | 975.47 | 325.16 | 40.00 |
| 처리 내 | 15 | 121.93 | 8.13 | |
| 전체 | 18 | 1097.40 |
\(F = 40.00 > F_{3,15,0.05} \approx 3.29\) → 독소 간 간 손상 평균에 통계적으로 유의한 차이가 있다.
6 코드 예시
6.1 Step 1: 직접 구현 — Casella 독소 데이터 재현
import numpy as np
import pandas as pd
# Casella 예제 11.2.1: 독소 데이터
data = {
"y": [28, 23, 14, 27, # 독소 1
33, 36, 34, 29, 31, 34, # 독소 2
18, 21, 20, 22, 24, # 독소 3
11, 14, 11, 16], # 대조군
"group": ["T1"]*4 + ["T2"]*6 + ["T3"]*5 + ["Ctrl"]*4
}
df = pd.DataFrame(data)
# 그룹 평균
group_means = df.groupby("group")["y"].mean()
grand_mean = df["y"].mean()
N = len(df)
k = df["group"].nunique()
print(f"그룹 평균:\n{group_means}")
print(f"\n전체 평균 (grand mean): {grand_mean:.4f}")
# SS 분해: Casella 정리 11.2.11
SSB = sum(
n_i * (y_bar_i - grand_mean)**2
for (grp, n_i), y_bar_i in zip(
df.groupby("group").size().items(),
group_means
)
)
SSW = sum(
(y - group_means[grp])**2
for grp, y in zip(df["group"], df["y"])
)
SST = sum((y - grand_mean)**2 for y in df["y"])
df_between = k - 1 # k - 1
df_within = N - k # N - k
df_total = N - 1 # N - 1
MSB = SSB / df_between
MSW = SSW / df_within
F_stat = MSB / MSW
print(f"\n=== ANOVA 표 (Casella Table 11.2.1) ===")
print(f"{'변동 원천':<12} {'df':>5} {'SS':>10} {'MS':>10} {'F':>8}")
print("-" * 48)
print(f"{'처리 간(SSB)':<12} {df_between:>5} {SSB:>10.3f} {MSB:>10.3f} {F_stat:>8.3f}")
print(f"{'처리 내(SSW)':<12} {df_within:>5} {SSW:>10.3f} {MSW:>10.3f}")
print(f"{'전체(SST)':<12} {df_total:>5} {SST:>10.3f}")
# 확인: SST = SSB + SSW
assert np.isclose(SST, SSB + SSW), "SS 분해 오류"
print(f"\nSST = SSB + SSW: {SST:.3f} = {SSB:.3f} + {SSW:.3f}")6.2 Step 2: ANOVA ↔︎ 회귀의 동일성 (statsmodels)
import statsmodels.formula.api as smf
import statsmodels.api as sm
# 방법 1: aov() 스타일 — ANOVA 표 직접 출력
model_ols = smf.ols("y ~ C(group)", data=df).fit()
anova_table = sm.stats.anova_lm(model_ols, typ=1)
print("=== ANOVA 표 (via OLS) ===")
print(anova_table)
# 방법 2: 더미변수를 직접 구성하여 OLS 적합
# 처리 코딩: Ctrl이 기준(알파벳 순서 최초)
X_dummy = pd.get_dummies(df["group"], drop_first=True).astype(float)
X = sm.add_constant(X_dummy)
model_explicit = sm.OLS(df["y"], X).fit()
print("\n=== OLS 계수 (처리 코딩) ===")
print(model_explicit.summary().tables[1])
# β̂₀ = Ctrl 그룹 평균
# β̂(T1) = T1 평균 - Ctrl 평균
# β̂(T2) = T2 평균 - Ctrl 평균
# β̂(T3) = T3 평균 - Ctrl 평균
# F 통계량 동일성 확인
F_anova = anova_table["F"].values[0]
F_ols = model_ols.fvalue
print(f"\nANOVA F = {F_anova:.4f}, OLS F = {F_ols:.4f}, 동일: {np.isclose(F_anova, F_ols)}")# R: aov()와 lm()의 동일성
toxin_data <- data.frame(
y = c(28, 23, 14, 27,
33, 36, 34, 29, 31, 34,
18, 21, 20, 22, 24,
11, 14, 11, 16),
group = factor(c(rep("T1", 4), rep("T2", 6),
rep("T3", 5), rep("Ctrl", 4)))
)
# ANOVA (전통적 방식)
fit_aov <- aov(y ~ group, data = toxin_data)
summary(fit_aov)
# Df Sum Sq Mean Sq F value Pr(>F)
# group 3 975.5 325.2 40.0 1.7e-07 ***
# Residuals 15 121.9 8.1
# 회귀 (더미변수 방식)
fit_lm <- lm(y ~ group, data = toxin_data)
summary(fit_lm)
# (Intercept): Ctrl 그룹 평균 = 13.0
# groupT1: T1 - Ctrl = 23.0 - 13.0 = 10.0
# groupT2: T2 - Ctrl = 32.83 - 13.0 = 19.83
# groupT3: T3 - Ctrl = 21.0 - 13.0 = 8.0
# F 통계량: 동일
all.equal(summary(fit_aov)[[1]][["F value"]][1],
summary(fit_lm)$fstatistic[1]) # TRUE6.3 Step 3: 최소제곱 추정량 — Casella 식 11.3.8-11.3.10
# Casella 예제 11.3.1: 포도 군집 수(x)와 수확량(y) 회귀
x = np.array([116.37, 82.77, 110.68, 97.50, 115.88,
80.19, 125.24, 116.15, 117.36, 93.31, 107.46, 122.30])
y = np.array([5.6, 3.2, 4.5, 4.2, 5.2,
2.7, 4.8, 4.9, 4.7, 4.1, 4.4, 5.4])
x_bar, y_bar = x.mean(), y.mean()
# Casella 식 11.3.5-11.3.7
S_xx = np.sum((x - x_bar)**2)
S_yy = np.sum((y - y_bar)**2)
S_xy = np.sum((x - x_bar) * (y - y_bar))
# Casella 식 11.3.8-11.3.10: OLS 추정량
b_hat = S_xy / S_xx # 기울기 β̂ = S_{xy}/S_{xx}
a_hat = y_bar - b_hat * x_bar # 절편 α̂ = ȳ - b̂x̄
print(f"S_xx = {S_xx:.3f}, S_yy = {S_yy:.3f}, S_xy = {S_xy:.3f}")
print(f"기울기 β̂ = S_xy/S_xx = {b_hat:.5f}")
print(f"절편 α̂ = ȳ - β̂·x̄ = {a_hat:.5f}")
# R² = S_{xy}²/(S_{xx}·S_{yy})
R2 = S_xy**2 / (S_xx * S_yy)
print(f"R² = {R2:.4f}")
# 해석: x(군집 수)가 1 증가할 때 y(수확량)는 β̂ ≈ 0.043 증가6.4 Step 4: t 검정 = F 검정 (k=2 특수 경우)
from scipy import stats
# k=2 경우: t²=F 관계 확인
group_a = np.array([28, 23, 14, 27]) # 독소 1
group_ctrl = np.array([11, 14, 11, 16]) # 대조군
# 독립표본 t 검정
t_stat, p_t = stats.ttest_ind(group_a, group_ctrl)
# 두 그룹 ANOVA
df_2grp = pd.DataFrame({
"y": np.concatenate([group_a, group_ctrl]),
"group": ["T1"]*4 + ["Ctrl"]*4
})
model_2grp = smf.ols("y ~ C(group)", data=df_2grp).fit()
F_stat_2grp = model_2grp.fvalue
print(f"t 통계량 = {t_stat:.4f}")
print(f"t² = {t_stat**2:.4f}")
print(f"F 통계량 = {F_stat_2grp:.4f}")
print(f"t² = F? {np.isclose(t_stat**2, F_stat_2grp)}") # → True7 두 방법의 비교: 같은 도구, 다른 질문
| 관점 | 회귀분석 | ANOVA |
|---|---|---|
| 연구 질문 | \(x\) 와 \(Y\) 의 선형 관계 크기는? | 그룹 간 평균이 다른가? |
| 예측변수 | 주로 연속형 | 주로 범주형(그룹) |
| Casella 모형 | \(Y_i = \alpha + \beta x_i + \epsilon_i\) (§11.3) | \(Y_{ij} = \theta_i + \epsilon_{ij}\) (식 11.2.1) |
| 핵심 모수 | 기울기 \(\beta\) (한 단위 변화 효과) | 그룹 평균 \(\theta_i\) (대비로 비교) |
| SS 용어 | SSReg vs SSRes | SSB vs SSW |
| 사후 검정 | 불필요 (연속형 \(x\)) | Bonferroni, Scheffé (Casella §11.2.5) |
| 연구 분야 | 예측, 관찰 연구, 기계학습 | 임상시험, 농업 실험, 심리학 |
Casella & Berger는 두 방법을 한 챕터(Ch.11)에서 함께 다루면서, ANOVA의 핵심이 F 검정이 아닌 대비(contrast)를 통한 처리 평균 추정과 구간추정에 있음을 강조한다. \(H_0: \theta_1 = \cdots = \theta_k\) 를 기각하는 것만으로는 “어떤 처리가 얼마나 더 나은가”를 알 수 없다. 대비를 이용한 개별 가설 검정과 신뢰구간이 실질적 정보를 제공한다.
회귀에서도 마찬가지다 — \(F\) 검정으로 전체 모형이 유의한지 확인하는 것이 아닌, 각 \(\beta_i\) 의 추정값과 신뢰구간이 핵심이다.
8 관련 주제
선행 지식
- Oneway ANOVA: 고전적 가설, F 검정
- F 분포와 카이제곱 분포 — \(\chi^2\), \(t\), \(F\) 분포의 유도
- 점추정 개요
후속 주제
- GLM — t-test부터 로지스틱 회귀까지 — 반응변수가 정규분포를 따르지 않을 때의 확장
- ANCOVA — 연속형 공변량과 범주형 예측변수 혼합
- Multiple Linear Regression ← placeholder
- Regression Models — Casella Ch.12 ← placeholder (측정오차 회귀, 로지스틱, 강건 회귀)
다른 카테고리 연결
- A/B Test 실험 설계 — 두 그룹 평균 비교를 실험으로 설계하는 방법
- Ablation Study — 모델 컴포넌트 기여도 분석 (ANOVA와 유사한 “요인 제거 후 효과 측정” 구조)