Python 데이터 분석

Python 데이터분석 기초 46 - 회귀분석(선형회귀분석) 방법[make_regression, LinearRegression, ols]

코딩탕탕 2022. 11. 10. 17:16

 

회귀분석(선형회귀분석)

각각의 데이터에 대한 잔차(예측값 - 실제값)제곱합이 최소가 되는 추세선(표준회귀선)을 만들고, 이를 통해 독립변수(x, feature)가 종속변수(y, label)에 얼마나 영향을 주는지 인과관계를 분석

 

독립변수 : 연속형, 종속변수 : 연속형. 두 변수는 상관관계가 있어야 하고, 나아가서는 인과관계가 있어야 한다.

정량적 모델을 생성

 

# 회귀분석(선형회귀분석)
# 각각의 데이터에 대한 잔차(예측값 - 실제값)제곱합이 최소가 되는 추세선(표준회귀선)을 만들고, 이를 통해
# 독립변수(x, feature)가 종속변수(y, label)에 얼마나 영향을 주는지 인과관계를 분석
# 독립변수 : 연속형, 종속변수 : 연속형. 두 변수는 상관관계가 있어야 하고, 나아가서는 인과관계가 있어야 한다.
# 정량적 모델을 생성

import statsmodels.api as sm
from sklearn.datasets import make_regression
import numpy as np


np.random.seed(12)

# 모델 맛보기

# 방법1 : make_regression을 사용. model x
x, y, coef = make_regression(n_samples = 50, n_features = 1, bias = 100, coef = True) # 표본 수, 독립변수 수, 절편값, 기울기 있음
print(x)
print(y)
print(coef) # y절편 구하기

# 회귀식 : (y = a + bx) == (y = b + wx) == (y = wx + b)
y_pred = 94.42251360530422 * 0.75314283 + 100
print('y_pred :', y_pred)

# 새로운 x값에 대한 y값 예측 결과
y_pred_new = 94.42251360530422 * 33 + 100
print('y_pred :', y_pred_new)


xx = x
yy = y

print()
# 방법2 : LinearRegression을 사용. model O
from sklearn.linear_model import LinearRegression # matrix 로 넣어진다.

model = LinearRegression()
fit_model = model.fit(xx, yy) # 이미 수집된 학습 데이터로 모형 추정 : 절편, 기울기 얻음(내부적으로 최소 제곱법)
print('기울기(slope, w) :', fit_model.coef_) # 기울기
print('절편(bias, w) :', fit_model.intercept_) # 절편(bias)
# 예측값 확인 함수로 미지의 feature(독립변수)에 대한 label(종속변수)을 예측
print(xx[0]) # [[-1.70073563]]
y_new = fit_model.predict(xx[[0]]) # matrix로 넣어주어야 된다. 대괄호 감싸기
print('y_new(예측값) :', y_new)
print('실제값 :', yy[0])

y_new2 = fit_model.predict([[55]]) # matrix로 넣어주어야 된다. 대괄호 감싸기
print('y_new(예측값) :', y_new2)

print()
# 방법3 : ols을 사용. model O   - 잔차제곱합(RSS)을 최소화하는 가중치 벡터를 행렬미분으로 구하는 방법
import statsmodels.formula.api as smf
import pandas as pd

print(xx.shape) # (50, 1)
x1 = xx.flatten() # 차원축소 함수
print(x1.shape) # (50, )
y1 = yy

data = np.array([x1, y1])
df = pd.DataFrame(data.T) # .T = 행렬 바꾸기
df.columns = ['x1', 'y1']
print(df.head(3))

model2 = smf.ols(formula = 'y1 ~ x1', data = df).fit() # label ~ feature
print(model2.summary()) # Intercept = 기울기 x1.coef = 절편값

# 예측값 확인 함수
print(x1[:2])
new_df = pd.DataFrame({'x1':[-1.70073563, -0.67794537]}) # 기존 자료를 사용하였다.
new_pred = model2.predict(new_df)
print('new_pred :\n', new_pred)
print('실제값 :\n', df.y1[:2])

#  전혀 새로운 x값에 대한 예측
new_df2 = pd.DataFrame({'x1':[33.0, -1.234]})
new_pred2 = model2.predict(new_df2)
print('new_pred2 :\n', new_pred2)


<console>
[[-1.70073563]
 [-0.67794537]
 [ 0.31866529]
 [ 0.13884618]
 [ 0.53513589]
 [-0.03920917]
 [ 0.03541635]
 [-0.71385629]
 [-0.11491994]
 [ 1.01251548]
 [ 2.24181779]
 [ 0.00512708]
 [-1.02953021]
 [-0.64743078]
 [ 0.47298583]
 [-1.2151688 ]
 [-0.25390408]
 [-0.3843588 ]
 [ 0.52733267]
 [ 0.47245699]
 [-0.91386915]
 [ 0.5018723 ]
 [-0.68142588]
 [-2.21333348]
 [-0.12214979]
 [-0.57188106]
 [ 1.34235637]
 [-1.15436024]
 [-0.58526828]
 [-3.14741652]
 [ 0.21497595]
 [-1.68175651]
 [-0.80698188]
 [ 1.20979645]
 [ 1.09595612]
 [-0.59782292]
 [-0.99720384]
 [-0.52840432]
 [-0.12022767]
 [ 0.07325207]
 [-0.10586232]
 [ 0.75314283]
 [ 0.2424395 ]
 [-2.21853495]
 [-1.78809425]
 [ 2.87181939]
 [ 1.33583134]
 [-1.53472134]
 [ 0.64076111]
 [-0.33759525]]
[ -52.17214291   39.34130801  128.51235594  112.42316554  147.88091341
   96.49178624  103.16885304   36.12820309   89.71761789  190.59412103
  300.58509445  100.45874176    7.88349776   42.07157936  142.32007968
   -8.72638684   77.28210847   65.60976235  147.18272498  142.27276227
   18.23219105  144.90467678   39.0298914   -98.0364801    89.07073235
   48.8313381   220.10640661   -3.28558253   47.63352619 -181.61291334
  119.23482409  -50.47399897   27.79585534  208.24569942  198.05991459
   46.51020834   10.77587732   52.72138937   89.24271248  106.55417864
   90.52804266  167.38693344  121.69210605  -98.50187763  -59.98849467
  356.95405132  219.52258382  -37.31812896  157.33165682   69.79389882]
89.47430739278907
y_pred : 171.11363911241233
y_pred : 3215.942948975039

기울기(slope, w) : [89.47430739]
절편(bias, w) : 100.0
[-1.70073563]
y_new(예측값) : [-52.17214291]
실제값 : -52.17214291381569
y_new(예측값) : [5021.0869066]

(50, 1)
(50,)
         x1          y1
0 -1.700736  -52.172143
1 -0.677945   39.341308
2  0.318665  128.512356
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                     y1   R-squared:                       1.000
Model:                            OLS   Adj. R-squared:                  1.000
Method:                 Least Squares   F-statistic:                 1.905e+32
Date:                Thu, 10 Nov 2022   Prob (F-statistic):               0.00
Time:                        17:15:06   Log-Likelihood:                 1460.6
No. Observations:                  50   AIC:                            -2917.
Df Residuals:                      48   BIC:                            -2913.
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept    100.0000   7.33e-15   1.36e+16      0.000     100.000     100.000
x1            89.4743   6.48e-15   1.38e+16      0.000      89.474      89.474
==============================================================================
Omnibus:                        7.616   Durbin-Watson:                   1.798
Prob(Omnibus):                  0.022   Jarque-Bera (JB):                8.746
Skew:                           0.516   Prob(JB):                       0.0126
Kurtosis:                       4.770   Cond. No.                         1.26
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[-1.70073563 -0.67794537]
new_pred :
 0   -52.172143
1    39.341308
dtype: float64
실제값 :
 0   -52.172143
1    39.341308
Name: y1, dtype: float64
new_pred2 :
 0    3052.652144
1     -10.411295
dtype: float64