본문 바로가기
공부/통계학

Backward Feature Selection (후진제거법) python

by signature95 2022. 1. 13.
728x90
반응형

이전 Wrapper method를 다룬 Forward Feature Selection (전진선택법, python)에 이어서 작성하는 포스트입니다.

 

2022.01.12 - [공부/모델링] - Forward feature selection (전진선택법) python

 

Forward feature selection (전진선택법) python

이전 filter method를 다룬 VIF (분산확장요인, python)에 이어서 작성하는 포스트입니다. 2022.01.11 - [공부/모델링] - VIF (분산확장요인, python) VIF (분산확장요인, python) Feature selection 방법은 크게..

signature95.tistory.com

 

 

Feature selection 방법은 크게 3가지로 나뉜다.

  1. Filter Method (Feature간 상관성 기반)
  2. Wrapper Method (Feature를 조정하며 모형을 형성하고 예측 성능을 참고하여 Feature 선택)
  3. Embedded Method (예측 모형 최적화, 회귀계수 추정 과정에서 각 Feature가 선택되는 방식)

이번에는 Wrapper Method 중 후진제거법에 대해 다루게 된다.

 

먼저 데이터를 불러오자.

사용할 데이터는 도요타 자동차 가격 데이터로 kaggle에서도 다운받을 수 있다.

 

https://www.kaggle.com/klkwak/toyotacorollacsv

 

ToyotaCorolla.csv

 

www.kaggle.com

 

초기에 모든 컬럼 데이터를 넣은 부분은 이전 포스트와 동일하다.

따라서 이번에는 추가로 Feature selection 없이 OLS를 진행한 것에 대해 RMSE(Root Mean Squared Error)를 출력해보도록 한다.

# feature selection 없이 진행한 OLS
import statsmodels.api as sm
from sklearn.metrics import mean_squared_error
from math import sqrt


X_train = sm.add_constant(X_train)
model = sm.OLS(y_train, X_train).fit()
y_pred = model.predict(X_test)

rmse = sqrt(mean_squared_error(y_test, y_pred))
print(rmse)

>>>
1133.2238385552757

 

 

그렇다면 이번에는 후진제거법을 실시해볼 것이다.

def backward_regression(X, y,
                           initial_list=[], 
                           threshold_out = 0.05, # P-value 임계값 (제거 기준)
                           feature_list = X_train.columns.tolist()
                           ):
    
    
    sv_per_step = [] ## 각 스텝별로 선택된 변수들
    adj_r_squared_list = [] ## 각 스텝별 수정된 결정계수
    steps = [] ## 스텝
    step = 0
    included = feature_list
    while True:
        changed=False
        model = sm.OLS(y, sm.add_constant(pd.DataFrame(X[feature_list]))).fit(disp=0)
        # use all coefs except intercept
        pvalues = model.pvalues.iloc[1:] # 각 feature의 P값을 의미함
        worst_pval = pvalues.max()	# P 값이 가장 높은 것 선정
        if worst_pval > threshold_out:
            changed=True
            worst_feature = pvalues.idxmax()
            included.remove(worst_feature)
        
        step += 1
        steps.append(step)        
        adj_r_squared = sm.OLS(y, sm.add_constant(pd.DataFrame(X[feature_list]))).fit(disp=0).rsquared_adj
        adj_r_squared_list.append(adj_r_squared)
        sv_per_step.append(included.copy())
        
        if not changed:
            break
      
    return included,step,steps,adj_r_squared_list,sv_per_step

backward_valriables_function,step,steps,adj_r_squared_list,sv_per_step = backward_regression(X_train, y_train)

다음 표를 확인하면 adjusted R squared 값이 step 별로 어떻게 변화하는지 알 수 있다.

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(10,10))
fig.set_facecolor('white')
 
font_size = 15
plt.xticks(steps,[f'step {s}\n'+'\n'.join(sv_per_step[i]) for i,s in enumerate(steps)], fontsize=1)
plt.plot(steps, adj_r_squared_list, marker='o')
    
plt.ylabel('adj_r_squared',fontsize=font_size)
plt.grid(True)
plt.show()

 

후진제거법 적용 후 모델의 summary는 다음과 같다.

model = sm.OLS(y_train, sm.add_constant(pd.DataFrame(X_train[backward_valriables_function]))).fit(disp=0)
print(model.summary())

>>>
                            OLS Regression Results                            
==============================================================================
Dep. Variable:                  Price   R-squared:                       0.906
Model:                            OLS   Adj. R-squared:                  0.904
Method:                 Least Squares   F-statistic:                     470.2
Date:                Thu, 13 Jan 2022   Prob (F-statistic):               0.00
Time:                        23:26:57   Log-Likelihood:                -9663.6
No. Observations:                1148   AIC:                         1.938e+04
Df Residuals:                    1124   BIC:                         1.950e+04
Df Model:                          23                                         
Covariance Type:            nonrobust                                         
====================================================================================
                       coef    std err          t      P>|t|      [0.025      0.975]
------------------------------------------------------------------------------------
Age_08_04         -121.8330      3.736    -32.612      0.000    -129.163    -114.503
Mfg_Month          -99.4782      9.950     -9.998      0.000    -119.001     -79.955
Mfg_Year             2.4462      0.667      3.670      0.000       1.138       3.754
KM                  -0.0162      0.001    -12.893      0.000      -0.019      -0.014
HP                  23.3496      3.249      7.187      0.000      16.975      29.724
Automatic          395.4738    146.668      2.696      0.007     107.700     683.248
Doors               80.0415     38.681      2.069      0.039       4.146     155.937
Cylinders           -0.0319      0.002    -16.216      0.000      -0.036      -0.028
Quarterly_Tax       13.0804      1.719      7.609      0.000       9.707      16.453
Weight               8.3921      1.198      7.005      0.000       6.041      10.743
Mfr_Guarantee      207.1914     72.093      2.874      0.004      65.739     348.644
BOVAG_Guarantee    447.1854    121.293      3.687      0.000     209.198     685.173
Guarantee_Period    65.0485     13.921      4.673      0.000      37.735      92.362
ABS               -346.3486     98.151     -3.529      0.000    -538.928    -153.769
Airco              203.1230     84.356      2.408      0.016      37.610     368.636
Automatic_airco   2294.4187    178.972     12.820      0.000    1943.263    2645.575
Boardcomputer     -314.2060    113.963     -2.757      0.006    -537.809     -90.602
CD_Player          254.8536     94.546      2.696      0.007      69.346     440.361
Powered_Windows    368.2483     82.493      4.464      0.000     206.391     530.106
Sport_Model        388.0867     82.999      4.676      0.000     225.236     550.937
Backseat_Divider  -230.7848    115.695     -1.995      0.046    -457.787      -3.782
Metallic_Rim       201.2032     88.447      2.275      0.023      27.664     374.743
Tow_Bar           -232.3991     76.233     -3.049      0.002    -381.975     -82.824
Fuel_Type_CNG    -1148.0595    338.728     -3.389      0.001   -1812.671    -483.448
Fuel_Type_Petrol   799.8869    280.208      2.855      0.004     250.098    1349.676
==============================================================================
Omnibus:                       94.295   Durbin-Watson:                   2.069
Prob(Omnibus):                  0.000   Jarque-Bera (JB):              487.180
Skew:                           0.133   Prob(JB):                    1.62e-106
Kurtosis:                       6.180   Cond. No.                     4.67e+19
==============================================================================

Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The smallest eigenvalue is 3.25e-27. This might indicate that there are
strong multicollinearity problems or that the design matrix is singular.

 

그렇다면 기존 모델과 후진제거법 적용 후 모델의 RMSE를 구해보자.

 

from sklearn.metrics import mean_squared_error
from math import sqrt

y_pred = model.predict(X_test[backward_valriables_function])

rmse = sqrt(mean_squared_error(y_test, y_pred))
print(rmse)

>>>

1126.5289337601785

 

처음의 RMSE는 1133이었다. 미약하게나마 RMSE가 줄어든 것을 확인할 수 있다.

 

다음 글에서 이어집니다.

2022.01.14 - [공부/모델링] - Stepwise Feature Selection (단계선택법) python

 

Stepwise Feature Selection (단계선택법) python

이전 Wrapper method를 다룬 Backward Feature Selection (후진제거법, python)에 이어서 작성하는 포스트입니다. 2022.01.13 - [공부/모델링] - Backward Feature Selection (후진제거법) python Backward Featur..

signature95.tistory.com

 

728x90

댓글