단순회귀분석> 잔차의 검토

2020. 8. 30. 20:50데이터 분석 기본

반응형

단순회귀분석을 통하여 추정한 회귀모형을 활용할 때, 추정된 모형이 타당할 때, 이론적 근거가 성립할 것입니다. 그러므로, 추정된 모형이 타당한지에 대해 검토가 필요합니다. 

주로, 잔차를 활용하여 추정된 모형이 타당한지를 판단합니다.

잔차 $e_i$에 대한 가정은 다음과 같습니다.

(1) $e_i$의 평균은 0이다.

(2)$e_i$들은 서로 독립이다.(독립성)

(3)$e_i$의 분산은 $\sigma^2$이다.(등분산성)

(4)$e_i$는 정규분포 N(0, $\sigma^2$)을 따른다.(정규성)

이들 조건중에서 (1)은 절편($\beta_0$)을 이용하여 우리가 항상 만족하게끔 모형을 추정할 수 있지만, (2),(3),(4)는 모형을 추정하면서 만들기가 어렵습니다. 따라서 (2),(3),(4)항목에 대해서 타당성 검토가 필요합니다.

[잔차의 독립성 검토]

독립의 가정을 확인하는 방안으로는 연속적인 잔차의 쌍($e_{i-1}$, $e_i$)들의 산점도를 그려보는 것입니다. 연속적인 잔차의 쌍들의 산점도에서 일정한 Pattern을 발견하기 어렵다면, 잔차들을 독립으로 볼 수 있을 것입니다.

[잔차의 등분산성 검토]

등분산성의 가정을 확인하는 방안으로는 수평축에 예측값($\widehat{y_i}$)과 수직축에 잔차($e_i$)에 대해서 산점도를 그려보는 것입니다.만약 $e_i$=0을 중심으로 수평축에 전체적으로 평행한 띠를 형성한다면 등분산성을 만족하다고 판단할 수 있습니다. 만약  예측값($\widehat{y_i}$)이 커짐에 따라 잔차들이 커진다거나, 잔차들이 예측값($\widehat{y_i}$)에 따라 일정한 Pattern을 나타낸다면 등분산성을 위비했다고 볼 수 있습니다.

[잔차의 정규성 검토]

정규성의 가정을 확인하는 방안으론 잔차($e_i$)들에 대해서 히스토그램을 그려보는 것입니다. 다만 히스토그램으로는 확인이 어려울 수 있기 때문에 정규확률그림을 활용하여, 정규성을 판단합니다.(정규확률그림:https://direction-f.tistory.com/20). 정규확률그림이 직선에 가까울 수록 정규성을 만족한다고 판단합니다.

실습까지 지금까지 했던, 단순회귀모형을 추정하고 타당성을 검토해보겠습니다.

import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy.stats as stats

## x 데이터 생성
x = np.linspace(1,300,300).astype(float)
data_ = pd.DataFrame(x)
data_.columns = ["X"]

## y=2x+1 데이터 생성
def gen_linear(row):
    y= 2*row +1
    e=np.random.normal(0,1,1)
    
    return y+e

data_["linear"]=data_.apply(lambda x : gen_linear(x["X"]), axis =1).astype("float")

## y=3x^2+1 데이터 생성
def gen_quad(row):
    y= 3*row**2 +1
    e=np.random.normal(0,1,1)
    
    return y+e

data_["quad"]=data_.apply(lambda x : gen_quad(x["X"]), axis =1).astype("float")

## Random 데이터 생성
def gen_random(row):    
    
    return np.random.randint(10,1000,1)

data_["rand"]=data_.apply(lambda x : gen_random(x["X"]), axis =1).astype("float")

## 시각화
plt.plot(data_["X"], data_["linear"], "bo" ,alpha=0.5, ms= 3)
plt.title("linear")
plt.ylabel("Y")
plt.xlabel("X")
plt.show()

plt.plot(data_["X"], data_["quad"], "ro" ,alpha=0.5, ms= 3)
plt.title("quad")
plt.ylabel("Y")
plt.xlabel("X")
plt.show()

plt.plot(data_["X"], data_["rand"], "go" ,alpha=0.5, ms= 3)
plt.title("rand")
plt.ylabel("Y")
plt.xlabel("X")
plt.show()

### 모형 추정
reg_linear = smf.ols("linear ~ X", data=data_).fit()
reg_linear.summary()

reg_quad = smf.ols("quad ~ X", data=data_).fit()
reg_quad.summary()

reg_rand = smf.ols("rand ~ X", data=data_).fit()
reg_rand.summary()


## 잔차 계산
pred_linear = reg_linear.fittedvalues.copy()
resid_linear = data_["linear"]-pred_linear

pred_quad = reg_quad.fittedvalues.copy()
resid_quad = data_["quad"]-pred_quad

pred_rand = reg_rand.fittedvalues.copy()
resid_rand = data_["rand"]-pred_rand

## 독립성 검토
def ind_(resid):
    resid_pair_list =[]               
    
    for i in range(len(resid)-2):
        resid_pair_list.append(np.array(resid[i:i+2]))  

    resid_pair = pd.DataFrame(resid_pair_list, columns ={"e_i-1", "e_i"})
    line_0 = np.linspace(0,0, len(resid_pair))
    
    plt.plot(resid_pair, "go",alpha=0.5, ms= 3)
    plt.plot(line_0, "r-")
    plt.title("independence assumption")       
   
    
    return resid_pair
      
ind_(resid_linear)
ind_(resid_quad)
ind_(resid_rand)
        

## 등분산성 검토
def homoscedasticity_(pred,resid):
    
    plt.plot(pred, resid, "bo",alpha=0.5, ms= 3)
    plt.title("homoscedasticity assumption") 
    
homoscedasticity_(pred_linear, resid_linear)
homoscedasticity_(pred_quad, resid_quad)
homoscedasticity_(pred_rand, resid_rand)


## 정규성 검토
def normal_(resid):
    resid.plot(kind="hist", title = "normality assumption")
    plt.show()
    
    stats.probplot(resid, dist="norm", plot=plt)
    plt.title("normality assumption") 
    plt.show()
    
normal_(resid_lienar)
normal_(resid_quad)
normal_(resid_rand)


반응형

'데이터 분석 기본' 카테고리의 다른 글

분산분석(ANOVA) 2  (0) 2020.09.03
분산분석(ANOVA) 1  (0) 2020.08.31
단순회귀분석 > 선형관계의 강도  (0) 2020.08.30
단순회귀분석에서의 추론  (0) 2020.08.25
단순회귀분석  (0) 2020.08.24