작성자: admin 작성일시: 2016-06-05 08:42:32 조회수: 3113 다운로드: 191
카테고리: 머신 러닝 태그목록:

회귀분석 결과의 진단

회귀분석 결과의 진단(diagnosis)이란 회귀분석에 사용된 데이터가 회귀분석에 사용된 모형 가정을 제대로 만족하고 있는지를 확인하는 과정이다.

잔차 정규성

데이터가 모형 가정을 만족하면 분석결과로 나온 잔차는 정규분포를 따라야 한다. 예를 들어 다음과 같이 2차 비선형 관계를 가지는 데이터를 선형 모형으로 회귀 분석한 경우를 살펴보자.

In:
def make_regression2(n_sample = 100, bias=0, noise=0.3, random_state=0):
    np.random.seed(random_state)
    x = np.random.rand(n_sample) * 4
    epsilon = noise * np.random.randn(n_sample)
    y = x ** 2 + bias + epsilon
    return x, y

x2, y2 = make_regression2()
plt.scatter(x2, y2)
plt.show()
In:
dfX20 = pd.DataFrame(x2, columns=["X1"])
dfX2 = sm.add_constant(dfX20)
dfy2 = pd.DataFrame(y2, columns=["y"])

model2 = sm.OLS(dfy2, dfX2)
result2 = model2.fit()

QQ플롯과 정규성 검정에서 보듯이 잔차는 정규 분포를 따르지 않는다.

In:
sp.stats.probplot(result2.resid, plot=plt)
plt.show()
In:
test = sms.omni_normtest(result2.resid)
for xi in zip(['Chi^2', 'P-value'], test):
    print("%-12s: %6.3f" % xi)
Chi^2       :  9.520
P-value     :  0.009

잔차와 독립 변수의 관계

이번에는 또다른 데이터를 살펴보자. 이 데이터도 2차 함수 관계를 따르고 있으므로 선형 모형을 따르지 않는다.

In:
def make_regression3(n_sample = 100, bias=0, noise=0.5, random_state=0):
    np.random.seed(random_state)
    x = np.random.rand(n_sample) * 3 - 1
    epsilon = noise * np.random.randn(n_sample)
    y = x ** 2 + bias + epsilon
    return x, y

x3, y3 = make_regression3()
plt.scatter(x3, y3)
plt.show()
In:
dfX30 = pd.DataFrame(x3, columns=["X1"])
dfX3 = sm.add_constant(dfX30)
dfy3 = pd.DataFrame(y3, columns=["y"])

model3 = sm.OLS(dfy3, dfX3)
result3 = model3.fit()
In:
sp.stats.probplot(result3.resid, plot=plt)
plt.show()
In:
test = sms.omni_normtest(result3.resid)
for xi in zip(['Chi^2', 'P-value'], test):
    print("%-12s: %6.3f" % xi)
Chi^2       :  1.202
P-value     :  0.548

데이터가 모형 가정을 따르지 않지만 잔차는 정규 분포를 따르는 것을 알 수 있다.

이러한 경우에는 잔차와 독립 변수간의 관계를 살펴보는 것이 도움이 될 수 있다. 데이터가 올바른 모형으로 분석되었다면 잔차는 더이상 독립 변수와 상관관계를 가지지 않아야 한다. 만약 잔차와 독립 변수간에 어떤 비선형 상관관계를 찾을 수 있다면 올바른 모형이 아니다.

다만 잔차와 특정 독립 변수간의 관계를 전체 모형이 올바른 모형이 아니라는 것을 알려줄 뿐이지 어떤 모형이 올바른 모형인지에 대한 정보는 주지 않는다.

In:
plt.plot(x3, result3.resid, 'o')
plt.axhline(y=0, c='k')
plt.xlabel("X1")
plt.ylabel("Residual")
plt.show()

Partial Regression Plot

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

Partial Regression Plot을 그리기 위해서는 3번의 선형회귀를 해야한다.

  1. 특정한 독립변수 Z를 제외한 나머지 독립변수 X들로 종속변수를 선형회귀하여 잔차 $e_{YX}$를 구한다.
  2. 나머지 독립변수 X들로 특정한 독립변수 선형회귀하여 잔차 $e_{ZX}$를 구한다.
  3. 잔차 $e_{ZX}$를 독립변수로, 잔차 $e_{YX}$를 종속변수로 하여 선형회귀한다.

위와 같이 잔차 $e_{ZX}$와 잔차 $e_{YX}$의 관계를 구하면 이 선형회귀 결과의 가중치 계수는 원래 Z의 가중치 계수와 같은 값이 나온다. 즉,

$$Y = w_X X + w_Z Z + e $$

일 때

$$e_{YX} = w_Z e_{ZX} + e' $$

가 된다.

잔차 $e_{ZX}$와 잔차 $e_{YX}$의 스캐터 플롯과 회귀 모형 결과를 나타낸 것이 Partial Regression Plot이다.

Statsmodel에서는 plot_regress_exog 명령 또는 sm.graphics.plot_partregress_grid 명령으로 Partial Regression Plot을 그릴 수 있다.

In:
fig = sm.graphics.plot_regress_exog(result3, "X1")
fig.suptitle("")
plt.show()