Analysis of Variance and Regression

같은 수식, 다른 질문 — Casella & Berger Ch.11 중심

ANOVA와 회귀분석은 서로 다른 방법론처럼 보이지만, 수학적으로는 동일한 선형 모델 Y = Xβ + ε의 두 가지 적용이다. Casella & Berger Ch.11의 모형 정의, 분산 분해(SST = SSB + SSW), F 검정, 최소제곱 추정을 중심으로 두 방법의 통합된 이해를 코드와 함께 제시한다.

Statistics
Regression
저자

Kwangmin Kim

공개

2026년 04월 05일

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).

정의: 세포 평균 모형 (Cell Means Model, 식 11.2.1)

\[ 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}\) 만큼 흩어진다. 셀 평균 모형은 ’반 효과(어느 반인가)’와 ’개인 변동(같은 반 안에서의 차이)’을 분리하는 것이다.

정의: 과모수화 모형 (Overparameterized Model, 식 11.2.2)

\[ 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)의 해석적 이점이 있다.

심화: 설계 행렬 Rank Deficiency — 식별불가능의 수학적 근거

과모수화 모형 \(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로 만들고, 역행렬의 존재를 회복한다.

두 가지 식별성 제약 — Sum Constraint vs Corner-point Constraint

식별성을 확보하는 방법은 두 가지가 있으며, 어느 쪽을 택해도 모형의 예측력(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).

정의: 대비 (Contrast)

\(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}\) )에 설정한다.

직관: 카이제곱에서 F 분포로

\(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):

정의: 단순 선형 회귀 모형 (식 11.3.1)

\[ 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):

정의: 선형 모델 (Linear Model)

\[ \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])  # TRUE

6.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)}")  # → True

7 두 방법의 비교: 같은 도구, 다른 질문

관점 회귀분석 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의 핵심 시각

Casella & Berger는 두 방법을 한 챕터(Ch.11)에서 함께 다루면서, ANOVA의 핵심이 F 검정이 아닌 대비(contrast)를 통한 처리 평균 추정과 구간추정에 있음을 강조한다. \(H_0: \theta_1 = \cdots = \theta_k\) 를 기각하는 것만으로는 “어떤 처리가 얼마나 더 나은가”를 알 수 없다. 대비를 이용한 개별 가설 검정과 신뢰구간이 실질적 정보를 제공한다.

회귀에서도 마찬가지다 — \(F\) 검정으로 전체 모형이 유의한지 확인하는 것이 아닌, 각 \(\beta_i\) 의 추정값과 신뢰구간이 핵심이다.

8 관련 주제

선행 지식

후속 주제

다른 카테고리 연결

  • A/B Test 실험 설계 — 두 그룹 평균 비교를 실험으로 설계하는 방법
  • Ablation Study — 모델 컴포넌트 기여도 분석 (ANOVA와 유사한 “요인 제거 후 효과 측정” 구조)

Subscribe

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