Chapter 1. 단순회귀분석 (python)

2021. 3. 10. 15:36Statistics/회귀 분석

이 글은 Stat 512: Applied Regression Analysis (Siddhartha Nandy) (purdue.edu)  사이트의 Lecture 3 의 SAS 코드를 참고 하여 Python으로 작성된 글입니다.


회귀모형을 벡터로 표현하면 다음과 같다.

 

$$ Y = X \beta + \varepsilon, \varepsilon~N_n(0,\sigma^2I_N) $$

 

이때 \(Y = (Y_1,...,Y_N)^T, x_ik = (X)_{ik\bullet}\)

 

Chapter 1. 단순회귀분석 에서 언급한 최소제곱법으로 \(\beta\)를 추정할 때 잔차제곱합(residual sum of squares)을 최소화하는 \(\beta\)를 찾는다. 이 내용을 벡터로 표현하면 다음과 같다.

 

$$ RSS(\beta) = \sum_{i=1}^n \varepsilon_i^2 = (y-X\beta)^T(y-X\beta) $$

 

위 식을 \(\beta\)에 대해 미분하고 0을 만족하는 식을 만들면 정규방정식(normal equation)이 된다.

 

$$ X^TX\beta = X^TY $$

 

X가 full column-rank를 가질때, \(\hat{\beta}\)은 다음과 같다.

 

$$ \hat{\beta} = (X^TX)^{-1}X^Ty $$

 

위에서 X full column-rank 라는것은 X에서 모든 열들이 서로 선형독립임을 의미한다.

 

이 내용을 이용해서 Python 라이브러리로 \(\beta\)를 추정한 값과 직접 계산한 값을 비교해 보도록하자.

1. 패키지 불러오기

1
2
3
4
5
import numpy as np
import numpy.linalg as lin
import matplotlib.pyplot as plt
import pandas as pd  
import statsmodels.api as sm  
cs

2. 데이터 입력하기

 

이 데이터는 diamond의 무게와 가격을 이용하여 회귀선을 적합하고 다이아몬드 캐럿의 무게가 0.43g 일때 의 가격을 예측하는 단순회귀분석 문제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
= np.array([.17,.16,.17,.18,.25,.16,.15,.19,
              .21,.15,.18,.28,.16,.20,.23,.29,
              .12,.26,.25,.27,.18,.16,.17,.16,
              .17,.18,.17,.18,.17,.15,.17,.32,
              .32,.15,.16,.16,.23,.23,.17,.33,
              .25,.35,.18,.25,.25,.15,.26,.15])
 
= np.array([355,328,350,325,642,342,322,485,
              483,323,462,823,336,498,595,860,
              223,663,750,720,468,345,352,332,
              353,438,318,419,346,315,350,918,
              919,298,339,338,595,553,345,945,
              655,1086,443,678,675,287,693,316])
 
= X.reshape(48,1)
= Y.reshape(48,1)
cs

여기서 X에 무게를 입력하고 Y에 가격을 입력하고, 단순회귀적합을 하기위해 각각 array를 48 by 1 행렬의 형태로 바꿔준다.

3. 단순회귀적합

1
2
3
4
5
6
7
X1 = sm.add_constant(X, has_constant = "add") 
 
model = sm.OLS(Y, X1)
 
fitted_model = model.fit()
 
fitted_model.summary()
cs

\(b_0\)를 계산해야 하기 때문에 \(X\)에 1로 구성된 열을 추가해준다. 그리고 statsmodels.api 라이브러리를 이용하여 단순회귀적합을 진행한다.

결과 값을보면

 

$$ \hat{y} = -259.6259 + 3721.0249 x_1 +\varepsilon  $$

 

으로 적합되는 것을 볼 수 있다.

 

산점도 그리기

1
2
3
4
5
6
7
pred = fitted_model.predict(X1)
 
plt.scatter(X,Y,label="Ture")                                      
plt.plot(X,pred,label = "predict")         
                                                    
plt.legend()                                        
plt.show()
cs

 

 

적합된 회귀식과 직접 계산한 \(\hat{\beta} = (X^TX)^-1X^Ty\) 의 값을 비교한결과를 보면 같은것을 확인 할 수 있다..

 

 

 

코드 한눈에 보기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import numpy as np
import numpy.linalg as lin
import matplotlib.pyplot as plt
import pandas as pd  
import statsmodels.api as sm  
 
= np.array([.17,.16,.17,.18,.25,.16,.15,.19,
              .21,.15,.18,.28,.16,.20,.23,.29,
              .12,.26,.25,.27,.18,.16,.17,.16,
              .17,.18,.17,.18,.17,.15,.17,.32,
              .32,.15,.16,.16,.23,.23,.17,.33,
              .25,.35,.18,.25,.25,.15,.26,.15])
 
= np.array([355,328,350,325,642,342,322,485,
              483,323,462,823,336,498,595,860,
              223,663,750,720,468,345,352,332,
              353,438,318,419,346,315,350,918,
              919,298,339,338,595,553,345,945,
              655,1086,443,678,675,287,693,316])
 
= X.reshape(48,1)
= Y.reshape(48,1)
 
X1 = sm.add_constant(X, has_constant = "add"
 
model = sm.OLS(Y, X1)
 
fitted_model = model.fit()
 
fitted_model.summary()
 
fitted_model.params  
 
pred = fitted_model.predict(X1)
 
plt.scatter(X,Y,label="Ture")                                      
plt.plot(X,pred,label = "predict")         
                                                    
plt.legend()                                        
plt.show()
 
np.dot(np.dot(lin.inv(np.dot(X1.T,X1)),X1.T),Y)
cs

'Statistics > 회귀 분석' 카테고리의 다른 글

Chapter 3. 다중회귀의 기하학적 의미(with R)  (0) 2021.03.23
Chapter 2. OLS (with R)  (1) 2021.03.17
Chapter 1. 단순회귀분석  (0) 2021.03.09