ANOVA with OLS

이정훈·2026년 5월 1일

0. OLS 기본 개념

1. SST / SSR / SSE 개념

  • SST: 설명변수XX를 고려하지 않았을 때 실제 관측지 yy값들의 평균을 중심으로 퍼져있는 정도
  • SSR: y값의 평균을 기준으로 회귀모형에 의헤 설명되는 변동의 제곱의 합
  • SSE: y값의 평균을 기준으로 회귀모형으로도 설명이 되지 않는 변동의 제곱의 합

2. SST = SSR + SSE

  • SST의 수식 안에 있는 y^i\hat{y}_i를 빼고 더하는 트릭을 사용

    SST=i=1n(yiyˉ)2=i=1n((yiy^i)+(y^iyˉ))2\begin{aligned} SST &= \sum_{i=1}^n (y_i - \bar{y})^2 \\[1.5em] &= \sum_{i=1}^n \left( (y_i - \hat{y}_i) + (\hat{y}_i - \bar{y}) \right)^2 \\[1.5em] \end{aligned}
    SST=i=1n((yiy^i)2+(y^iyˉ)2+2(yiy^i)(y^iyˉ))=i=1n(yiy^i)2+i=1n(y^iyˉ)2+2i=1n(yiy^i)(y^iyˉ)=SSE+SSR+2i=1nei(y^iyˉ)\begin{aligned} SST &= \sum_{i=1}^n \left( (y_i - \hat{y}_i)^2 + (\hat{y}_i - \bar{y})^2 + 2(y_i - \hat{y}_i)(\hat{y}_i - \bar{y}) \right) \\[1.5em] &= \sum_{i=1}^n (y_i - \hat{y}_i)^2 + \sum_{i=1}^n (\hat{y}_i - \bar{y})^2 + 2 \sum_{i=1}^n (y_i - \hat{y}_i)(\hat{y}_i - \bar{y}) \\[1.5em] &= SSE + SSR + 2 \sum_{i=1}^n e_i (\hat{y}_i - \bar{y}) \end{aligned}
  • 마지막 항이 0이됨을 증명

    i=1nei(y^iyˉ)=i=1neiy^ii=1neiyˉ=i=1neiy^iyˉi=1nei\begin{aligned} \sum_{i=1}^n e_i (\hat{y}_i - \bar{y})&= \sum_{i=1}^n e_i \hat{y}_i - \sum_{i=1}^n e_i \bar{y} \\[1.5em] &= \sum_{i=1}^n e_i \hat{y}_i - \bar{y} \sum_{i=1}^n e_i \end{aligned}

3. 자유도

SST (전체 자유도) → n1n-1

  • 편차의 합은 항상 0이 되어야 한다는 제약조건 ((yiyˉ)=0\sum (y_i - \bar{y}) = 0)
  • n1n-1개의 편차가 정해지면 마지막 1개의 편차는 자동으로 결정
  • 독립변수의 개수(kk)와 관계없이 항상 n1n-1로 고정

SSR (회귀 자유도) → kk

  • kk는 독립변수(기울기)의 개수 (intercept는 포함 안됨)
  • 단순선형회귀(Y=β0+β1XY = \beta_0 + \beta_1 X)라면 β1\beta_1가 정해지면 β0\beta_0는 자동으로 결정됨으로 k=1k=1

SSE (잔차/오차 자유도) → nk1n-k-1

  • nn개의 데이터에서 회귀 모형을 만들기 위해 총 k+1k+1개의 파라미터를 추정
  • 파라미터를 추정할 때마다 자유도를 1씩 소모
  • n(k+1)=nk1n - (k + 1) = n - k - 1

4. F-table

변동 요인 (Source)제곱합 (SS)자유도 (df)평균제곱 (MS)F-통계량
회귀 (Regression)SSRSSRkkMSR=SSRkMSR = \frac{SSR}{k}F=MSRMSEF = \frac{MSR}{MSE}
오차 (Error)SSESSEnk1n - k - 1MSE=SSEnk1MSE = \frac{SSE}{n - k - 1}
전체 (Total)SSTSSTn1n - 1

5. lm에 대한 ANOVA

회귀계수 쪽으로 이동

5. 회귀 계수 검증 방법

  • β\beta구하는 행렬식

    β^=(XTX)1XTy\hat{\boldsymbol{\beta}} = (\mathbf{X}^T\mathbf{X})^{-1}\mathbf{X}^T\mathbf{y}
  • 공통 노이즈 기준으로 MSE

MSE=SSEnk1MSE = \frac{SSE}{n - k - 1}
  • 각각 독립 변수의 개별 차이 계산
    • 공분산에서 분산이 크면 공분산의 역수를 곱해줌으로 분산은 작아짐
    • 즉, 분산이 므면 양끝을 늘려주는 닻이 길게 꼽혀있어서 β\beta의 분산은 작아짐
Var(β^)=MSE(XTX)1Var(\hat{\boldsymbol{\beta}}) = MSE \cdot (\mathbf{X}^T\mathbf{X})^{-1}
  • 가설검정: H0H_0: 모집단에서의 기울기(β\beta)는 0
    • 중심이 0이고 폭이 위에서 계산된 Var(β^)Var(\hat{\boldsymbol{\beta}})인 분포를 그림
    • 실제 데이터에서 구한 기울기 값(예: 2.5)을 이 곡선 위에 찍어봤을 때의 통계량 & p-value
    • 개별 통계량(t-value) 도출
      SE(β^j)=Var(β^j)SE(\hat{\beta}_j) = \sqrt{Var(\hat{\beta}_j)}
      tj=β^jSE(β^j)t_j = \frac{\hat{\beta}_j}{SE(\hat{\beta}_j)}

6. CODE

# ==========================================
# statsmodels (sm.OLS) 라이브러리를 통한 계산
# ==========================================
# 독립변수 행렬에 상수항(절편 1) 추가
X_data = np.column_stack((X1, X2))
X_sm = sm.add_constant(X_data) 

model = sm.OLS(y, X_sm)
results = model.fit()

results.summary()

# ==========================================
# 행렬 연산을 통한 수동 계산 (Manual Calculation)
# ==========================================
# 설계 행렬 X (절편 포함)와 y 벡터 설정

X = X_sm
k = X.shape[1]
df = n-k

beta_hat = np.linalg.inv(X.T @ X)  @ X.T @ y
y_pred = X @ beta_hat
SSE = np.sum((y - y_pred) ** 2)

MSE = SSE / df
var_beta_matrix = MSE * np.linalg.inv(X.T @ X)

se = np.sqrt(np.diag(var_beta_matrix))
t_stats = beta_hat / se
p_values = 2 * (1 - stats.t.cdf(np.abs(t_stats), df))

print(f"회귀 계수 (Beta): {beta_hat}")
print(f"표준 오차 (SE):   {se}")
print(f"t-통계량 (t):     {t_stats}")
print(f"p-value:          {p_values}")
profile
AngDDo

0개의 댓글