선형 회귀 분석의 결과가 어느 정도의 성능을 가지는지는 단순히 잔차 제곱합(RSS: Residula Sum of Square)으로 평가할 수 없다. 변수의 스케일이 달라지면 회귀 분석과 상관없이 잔차 제곱합도 같이 커지기 때문이다.
분산 분석(ANOVA:Analysis of Variance)은 종속 변수의 분산과 독립 변수의 분산간의 관계를 사용하여 선형 회귀 분석의 성능을 평가하고자 하는 방법이다. 분산 분석은 서로 다른 두 개의 선형 회귀 분석의 성능 비교에 응용할 수 있으며 독립 변수가 카테고리 변수인 경우 각 카테고리 값에 따른 영향을 정량적으로 분석하는데도 사용된다.
$\bar{y}$를 종속 변수 $y$의 샘플 평균이라고 하자.
$$\bar{y}=\frac{1}{N}\sum_{i=1}^N y_i $$종속 변수의 분산을 나타내는 TSS(total sum of square)라는 값을 정의한다.
$$\text{TSS} = \sum_i (y_i-\bar{y})^2$$마찬가지로 회귀 분석에 의해 예측한 종속 변수의 분산을 나타내는 ESS(explained sum of squares),
$$\text{ESS}=\sum_i (\hat{y}_i -\bar{y})^2,$$오차의 분산을 나타내는 RSS(residual sum of squares)도 정의한다.
$$\text{RSS}=\sum_i (y_i - \hat{y}_i)^2\,$$이 때 이들 분산 간에는 다음과 같은 관계가 성립한다.
$$\text{TSS} = \text{ESS} + \text{RSS}$$이는 다음과 같이 증명한다.
우선 회귀 분석으로 구한 가중치 벡터를 $\hat{w}$, 독립 변수(설명 변수) $x$에 의한 종속 변수의 추정값을 $\hat{y}$, 잔차를 $e$ 라고 하면 다음 식이 성립한다.
$$ y = X\hat{w} + e = \hat{y} + e $$따라서
$$ y_i - \bar{y} = \hat{y}_i - \bar{y} + e_i = (x_i - \bar{x})\hat{w} + e_i $$를 벡터화하면 $$ y - \bar{y} = \hat{y} - \bar{y} + e_i = (X- \bar{X})\hat{w} + e $$
여기에서 $\bar{X}$는 각 열이 $X$의 해당 열의 평균인 행렬이다.
이 식에 나온 $X-\bar{X}$와 잔차 $e$는 다음과 같은 독립 관계가 성립한다.
$$ X^Te = \bar{X}Te = 0 $$이 식들을 정리하면 다음과 같다.
$$ \begin{eqnarray} \text{TSS} &=& (y - \bar{y})^T(y - \bar{y} ) \\ &=& (\hat{y} - \bar{y} + e)^T(\hat{y} - \bar{y} + e) \\ &=& (\hat{y} - \bar{y})^T(\hat{y} - \bar{y}) + e^Te + 2(\hat{y} - \bar{y})^Te \\ &=& (\hat{y} - \bar{y})^T(\hat{y} - \bar{y}) + e^Te + 2\hat{w}^T(X - \bar{X})^Te \\ &=& (\hat{y} - \bar{y})^T(\hat{y} - \bar{y}) + e^Te \\ &=& \text{ESS} + \text{RSS} \end{eqnarray} $$위의 분산 관계식에서 다음과 같이 결정 계수(Coefficient of Determination) $R^2$를 정의할 수 있다.
$$R^2 \equiv 1 - \dfrac{\text{RSS}}{\text{TSS}}\ = \dfrac{\text{ESS}}{\text{TSS}}\ $$분산 관계식과 모든 분산값이 0보다 크다는 점을 이용하면 $R^2$의 값은 다음과 같은 조건을 만족함을 알 수 있다.
$$0 \leq R^2 \leq 1$$여기에서 $R^2$가 0이라는 것은 오차의 분산 RSS가 최대이고 회귀 분석 결과의 분산 ESS가 0인 경우이므로 회귀 분석의 결과가 아무런 의미가 없다는 뜻이다.
반대로 $R^2$가 1이라는 것은 오차의 분산 RSS가 0이고 회귀 분석 결과의 분산 ESS가 TSS와 같은 경우이므로 회귀 분석의 결과가 완벽하다는 뜻이다.
따라서 결정 계수값은 회귀 분석의 성능을 나타내는 수치라고 할 수 있다.
$R^2 = 0$인 경우에 다음 값은 F-분포를 따른다.
$$ \dfrac{R^2/(K-1)}{(1-R^2)(N-K)} \sim F(K-1, N-K) $$따라서 이 값은 $R^2 = 0$인 귀무가설에 대한 검정 통계량으로 사용할 수 있다. 이러한 검정을 Loss-of-Fit test (Regression F-test)이라고 한다.
분산 분석의 결과는 보통 다음과 같은 분산 분석표를 사용하여 표시한다.
| source | degree of freedom | mean square | F statstics | |
|---|---|---|---|---|
| Regression | $$\text{ESS}$$ | $$K-1$$ | $$s_{\hat{y}}^2 = \dfrac{\text{ESS}}{K-1}$$ | $$F$$ |
| Residual | $$\text{RSS}$$ | $$N-K$$ | $$s_e^2= \dfrac{\text{RSS}}{N-K}$$ | |
| Total | $$\text{TSS}$$ | $$N-1$$ | $$s_y^2= \dfrac{\text{TSS}}{N-1}$$ | |
| $R^2$ | $$\text{ESS} / \text{TSS}$$ |
statsmodels 에서는 다음과 같이 anova_lm 명령을 사용하여 분산 분석표를 출력할 수 있다. 다만 이 명령을 사용하기 위해서는 모형을 from_formula 메서드로 생성하여야 한다.
In [6]:
from sklearn.datasets import make_regression
X0, y, coef = make_regression(n_samples=100, n_features=1, noise=20, coef=True, random_state=0)
dfX0 = pd.DataFrame(X0, columns=["X"])
dfX = sm.add_constant(dfX0)
dfy = pd.DataFrame(y, columns=["Y"])
df = pd.concat([dfX, dfy], axis=1)
model = sm.OLS.from_formula("Y ~ X", data=df)
result = model.fit()
table = sm.stats.anova_lm(result)
table
Out[6]:
독립 변수가 복수인 경우에는 각 독립 변수에 대한 F 검정 통계량을 구할 수 있다. 이 값은 각 변수만을 가진 복수의 모형의 성능을 비교하는 것과 같으므로 독립 변수의 영향력을 측정하는 것이 가능하다.
In [10]:
from sklearn.datasets import load_boston
boston = load_boston()
dfX0_boston = pd.DataFrame(boston.data, columns=boston.feature_names)
dfy_boston = pd.DataFrame(boston.target, columns=["MEDV"])
import statsmodels.api as sm
dfX_boston = sm.add_constant(dfX0_boston)
df_boston = pd.concat([dfX_boston, dfy_boston], axis=1)
model = sm.OLS.from_formula("MEDV ~ CRIM + ZN +INDUS + NOX + RM + AGE + DIS + RAD + TAX + PTRATIO + B + LSTAT + C(CHAS)", data=df_boston)
result = model.fit()
table = sm.stats.anova_lm(result)
table
Out[10]: