다운로드
작성자: admin 작성일시: 2018-06-23 15:25:07 조회수: 1402 다운로드: 86
카테고리: 기타 태그목록:

부분 회귀

만약 회귀분석을 한 후에 새로운 독립 변수를 추가하여 다시 회귀분석을 한다면 그 전에 회귀분석으로 구했던 가중치의 값은 변할까 변하지 않을까? 예를 들어 $x_1$이라는 독립 변수만으로 회귀분석한 결과가 다음과 같다고 하자.

$$ y = w_1 x_1 + e $$

이 때 새로운 독립 변수 $x_2$를 추가하여 회귀분석을 하게 되면 이 때 나오는 $w'_1$가 원래의 $w_1$과 같을까 다를까?

$$ y = w_1' x_1 + w_2' x_2 + e' $$

답부터 말하자면 일반적으로 $w'_1$의 값은 원래의 $w_1$의 값과 같지 않다. 즉 우리가 종속 변수에 영향을 미치는 모든 독립 변수를 회귀모형에 포함하지 않는 한 모형의 가중치는 항상 편향된(biased) 값이 된다. 이 사실은 다음과 같이 증명할 수 있다.

독립 변수 $x_1$만으로 이루어진 특징 행렬을 $X_1$, 독립 변수 $x_2$만으로 이루어진 특징 행렬을 $X_2$라고 하자.

$$ X = \begin{bmatrix} X_1 & X_2 \end{bmatrix} $$

만약 독립 변수 $x_1$만으로 회귀분석을 하면 가중치 벡터는 다음과 같다.

$$ w_1 = (X_1^TX_1)^{-1}X_1^T y $$

여기에 독립 변수 $x_2$를 같이 추가하여 다음과 같은 선형 회귀 모형을 생각해 보자.

$$ y = \hat{y} + e' = \begin{bmatrix} X_1 & X_2 \end{bmatrix} \begin{bmatrix} w'_1 \\ w'_2 \end{bmatrix} + e' $$

이 식에서 $w'_1, w'_2$ 새로운 모형의 가중치 벡터이고 $e'$는 새로운 모형의 잔차 벡터이다. 양변에 $X$를 곱하여 직교 방정식을 구하면,

$$ \begin{bmatrix} X_1^TX_1 & X_1^TX_2 \\ X_2^TX_1 & X_2^TX_2 \\ \end{bmatrix} \begin{bmatrix} w'_1 \\ w'_2 \end{bmatrix} = \begin{bmatrix} X_1^Ty \\ X_2^Ty \end{bmatrix} $$

부분행렬의 역행렬 공식을 사용하여 이 방정식을 풀면 다음과 같은 공식을 얻을 수 있다.

$$ \begin{eqnarray} w'_1 &=& (X_1^TX_1)^{-1}X_1^T(y - X_2 w'_2) \\ &=& (X_1^TX_1)^{-1}X_1^Ty - (X_1^TX_1)^{-1}X_1^T X_2 w'_2 \\ \end{eqnarray} $$

이 값은 독립 변수 $x_1$만으로 회귀분석을 한 결과와 다르다. 따라서 회귀분석할 때 새로운 독립 변수를 추가해서 다시 회귀분석을 한다면 그 전에 기존의 회귀분석으로 구했던 가중치 벡터의 값은 달라진다.

단 다음과 같은 경우에는 두 회귀분석 결과가 같아진다.

  1. $w'_2=0$. 즉 $X_2$와 $y$의 상관관계가 없는 경우
  2. $X_1^T X_2 = 0$. 즉 독립 변수 $x_1$과 독립 변수 $x_2$의 상관관계가 없는 경우

Frisch–Waugh–Lovell 정리

Frisch–Waugh–Lovell 정리 혹은 FWL 정리는 위 결과를 변형한 것이다.

특정한 독립 변수 $x_1$로 나머지 독립 변수 $x_2$를 선형 회귀분석하여 나온 잔차 $x_2^{\ast}$를 독립 변수로 하고 $x_1$로 종속 변수 $y$를 선형 회귀분석하여 나온 잔차 $y^{\ast}$를 종속 변수로 하여 다시 선형 회귀분석하여 구한 가중치는 $x_1, x_2$를 모두 사용하여 $y$를 선형 회귀분석하였을 때 $x_2$에 대한 가중치와 같다.

증명은 다음과 같다. 개의 독립 변수 $x_1$, $x_2$가 있을 때, $x_1$에 대한 가중치 벡터 $w_1$는 원래 다음 관계에서 구해야 한다.

$$ y = \begin{bmatrix} X_1 & X_2 \end{bmatrix} \begin{bmatrix} w_1 \\ w_2 \end{bmatrix} + e $$

이 때 직교 방정식은 다음과 같다.

$$ \begin{bmatrix} X_1^TX_1 & X_1^TX_2 \\ X_2^TX_1 & X_2^TX_2 \\ \end{bmatrix} \begin{bmatrix} w_1 \\ w_2 \end{bmatrix} = \begin{bmatrix} X_1^Ty \\ X_2^Ty \end{bmatrix} $$

이 식의 아랫 부분만 쓰면 다음과 같다.

$$ X_2^TX_1w_1 + X_2^TX_2w_2 = X_2^Ty $$

여기에 앞에서 구했던 $w_1$ 값을 대입하면,

$$ w_1 = (X_1^TX_1)^{-1}X_1^Ty - (X_1^TX_1)^{-1}X_1^T X_2 w_2 \\ $$

이 식을 정리하면

$$ X_2^TX_1(X_1^TX_1)^{-1}X_1^Ty - X_2^TX_1(X_1^TX_1)^{-1}X_1^T X_2 w_2 + X_2^TX_2w_2 = X_2^Ty $$$$ X_2^T( I - X_1(X_1^TX_1)^{-1}X_1^T) X_2 w_2 = X_2^T (I - X_1(X_1^TX_1)^{-1}X_1^T)y $$

여기에서 $x_1$으로 선형 회귀분석하였을 때의 잔차 행렬 $M_1$을 적용하면,

$$ X_2^T (M_1 X_2) w_2 = X_2^T (M_1 y) $$

이다. 잔차 행렬의 성질을 이용하면,

$$ (M_1 X_2)^T (M_1 X_2) w_2 = (M_1X_2)^T (M_1 y) $$

가 된다. $M_1 X_2$는 $x_2$를 $x_1$으로 회귀분석한 잔차 벡터이고 $M_1 y$는 $y$를 $x_1$으로 회귀분석한 잔차 벡터이므로 이 식은

$$ {X_2^{\ast}}^T X_2^{\ast} w_2 = {X_2^{\ast}}^T y^{\ast} $$

이 되어 $x_2^{\ast}$를 독립 변수, $y^{\ast}$를 종속 변수로 선형 회귀분석한 결과와 같아진다.

평균 제거 데이터

상수항이 결합된 독립 변수 행렬에서 상수항 부분과 다른 부분을 분리하여 생각해보자. 상수항만 사용하여 회귀분석을 하면 평균을 제거하는 것과 같아진다. 따라서 FWL 정리를 적용하면 다음과 같은 결과를 얻을 수 있다.

독립 변수에서 평균을 제거한 데이터와 종속 변수에서 평균을 제거한 데이터로 얻은 회귀분석 결과는 상수항을 포함하여 구한 회귀분석 결과와 같다.

평균을 제거한 데이터를 사용하는 경우에는 독립 변수에 상수항을 포함하지 않는다는 점에 주의한다.

부분 회귀 플롯

독립 변수의 갯수가 많을 경우에 특정한 하나의 독립 변수의 영향력을 시각화하는 방법이 부분 회귀 플롯(Partial Regression Plot)이다. Added Variable Plot이라고도 한다.

부분 회귀 플롯을 그리기 위해서는 3번의 선형 회귀분석을 해야 한다.

  1. 특정한 독립 변수 $z$를 제외한 나머지 독립 변수 $x$들로 종속 변수 $y$를 선형 회귀분석하여 잔차 $y^{\ast}$를 구한다.
  2. 특정한 독립 변수 $z$를 제외한 나머지 독립 변수 $x$들로 특정한 독립 변수 $z$를 선형 회귀분석하여 잔차 $z^{\ast}$를 구한다.
  3. 잔차 $z^{\ast}$를 독립 변수로, 잔차 $y^{\ast}$를 종속 변수로 하여 선형 회귀분석한다.

이렇게 구한 $z^{\ast}$, $y^{\ast}$의 스캐터 플롯과 회귀분석 결과를 나타낸 것이 부분 회귀 플롯이다.

보스턴 데이터를 대상으로 부분 회귀 플롯을 그리면 다음과 같다.

In [1]:
from sklearn.datasets import load_boston
boston = load_boston()
dfX0 = pd.DataFrame(boston.data, columns=boston.feature_names)
dfX = sm.add_constant(dfX0)
dfy = pd.DataFrame(boston.target, columns=["MEDV"])
df = pd.concat([dfX, dfy], axis=1)
model_boston = sm.OLS(dfy, dfX)
result_boston = model_boston.fit()

sm.graphics.plot_partregress 명령을 쓰면 부분 회귀 플롯을 그릴 수 있다. 다만 이 때는 다른 변수의 이름을 모두 지정해 주어야 한다. 인수 ret_coords=True로 하면 잔차 데이터를 반환한다.

In [2]:
others = list(set(df.columns).difference(set(["MEDV", "CRIM"])))
p, resids = sm.graphics.plot_partregress("MEDV", "CRIM", others, data=df, ret_coords=True)
plt.show()

부분 회귀 플롯에서 가로축의 값은 독립 변수 자체의 값이 아니라 어떤 독립 변수에서 다른 독립 변수의 영향을 제거한 일종의 "순수한 독립 변수 성분"을 뜻한다.

sm.graphics.plot_partregress_grid 명령을 쓰면 전체 데이터에 대해 한번에 부분 회귀 플롯을 그릴 수 있다.

In [3]:
fig = plt.figure(figsize=(8, 20))
sm.graphics.plot_partregress_grid(result_boston, fig=fig)
fig.suptitle("")
plt.show()