변수선택법(stepwise) - Logistic regression in python

이경주 Junior data analyst·2023년 11월 6일
1

Python

목록 보기
1/8

0. 개요

  • 그지같은 파이썬이 step 함수를 제공하지 않는거랑, 또 제공되어도 죄다 OLS 함수를 쓴 회귀분석에 관련된 글만 주구장창 나온다. 따라서 이 글은 stepwise를 통해 Logistic 회귀의 변수선택을 진행하려 한다. 그것도 AIC 기준으로

  • Python 라이브러리 함수를 이용해서 Logitregression을 구하는 방법이 두가지가 있는데, 이 글에선 statsmodels을 이용할 것이다. sklearn도 원리는 비슷해서 구상하는 방식은 똑같을 것 같다.

1. 방법

Step 1. 라이브러리 불러오기

#%% 라이브러리 불러오기
import pandas as pd 
import numpy as np

from datetime import datetime
from nltk import ngrams
from collections import Counter
import itertools

import statsmodels.api as sm
import time
import warnings
warnings.filterwarnings("ignore")

Step 2. X랑 Y에 독립변수(feature), 설명변수(target)을 지정한다.

data_x = ...(independent Variable)
data_y = ...(explanatory Variable)

data_x['범주변수'] = X['범주변수'].astype('category')

Step 3. 범주형(카테고리) 변수 dummy로 만들기

def g_d(df):
    for i in df.columns:
        if df[i].dtype.name == 'category':
            df = pd.get_dummies(df, columns = [i], drop_first = True)
        else:
            df = df
    return df
  • R에선 category로 변수의 형태로 입력 시 자동으로 dummy 변수로 만들어주지만.. python은 직접 입력해야한다. 그지같다.

step 4. Stepwise

import time
#%%
# 초기화
startpoint = time.time()
selected_features = []
best_aic = float("inf")  # 초기 AIC를 무한대로 설정
loopCount = 0

while True:
    added = None
    removed = None
    # Forward Selection
    for feature in data_x.columns:
        if feature not in selected_features:
            temp_features = selected_features + [feature]
            
            model = sm.Logit(data_y, sm.add_constant(g_d(data_x[temp_features]))).fit(method = 'bfgs')
            aic = model.aic
            if aic < best_aic:
                best_aic = aic
                added = feature
                
                
    # Backward Elimination
    if len(selected_features) > 0:
        for feature in selected_features:
            temp_features = [f for f in selected_features if f != feature]
            model = sm.Logit(data_y, sm.add_constant(g_d(data_x[temp_features]))).fit(method = 'bfgs')
            aic = model.aic
            if aic < best_aic:
                best_aic = aic
                removed = feature
    if added is not None:
        selected_features.append(added)
    elif removed is not None:
        selected_features.remove(removed)
    else:
        break
    time.sleep(1)
    loopCount += 1

finishPoint = time.time()
print('\n',"변수선택 걸린시간: ",finishPoint - startPoint, "초.")  
print("Best selected features:", selected_features)
print("Best AIC:", best_aic)
  • 코드가 길어서 무서워 하지 말고 천천히 읽어보면 별거 없다.

  • fit 부분에서 method = "bfgs"는 변수 중 singular matrix가 존재해도 결과를 도출해주는 최적화 방법이라 생각하면 된다.

  • 중간에 add.constant는 상수항 1을 추가해주는 방법으로, 통계를 수강했던 기억을 자세히 생각하면 X행렬 앞에 1을 [:,0] 추가했던 기억이 날 것이다.

  • Stepwise 검색하다가 이 글을 읽는다면, 아마 Stepwise의 작동 방법은 알고 왔을 것이다. 그럼에도 아주 간단하게 코드와 같이 설명하면.

    1. 첫 aic를 inf(무한)으로 정한다.
    2. Forward 방식으로 변수를 추가하여 AIC를 계산한 뒤 이전 변수들의 AIC랑 비교하여 추가 할지 말지 고민한다.
    3. Backward 방식으로 선택 된 변수에서 변수를 제거할 때 AIC의 증,감소량을 보며 변수를 뺄지 말지 고민한다.
  • 다른 블로그에 올라와 있는 방법보다 위 방법이 변수 선택에 있어 시간을 훨씬 단축시켜 줄 것이다. 내가 해봤기 때문이다. 자료구조를 전문적으로 배우지 않아서 구체적으로 설명할 순 없다. 힝..

  • 추가로 sm.logit에서 error가 뜬다면 method = 'bfgs'부분을 아예 없애면 해결 될 수 있다.
profile
Good afternoon, Good evening and Good night

0개의 댓글