본문 바로가기

Machine Learning Models/Classic

Feature Selection - Recursive Feature Elimination

반응형

Recursive feature elimination (rfe)는 매우 직관적인 feature selection 방법으로 먼저 전체 feature에 대해 훈련 후 중요하지 않은 feature 들을 제거하면서 원하는 개수의 feature 수만 남기도록 하는 방법입니다. 따라서 원하는 수의 feature 만 사용하는 minimal optimal feature subset 을 구하는 간단한 방법이라 볼 수 있으며 중요하지 않은 feature 를 매 스텝마다 하나씩 줄이면서 모델을 새로 빌딩하는 과정을 반복합니다.

Example

파이썬에서는 scikit-learn 패키지의 RFE 함수로 구현할 수 있습니다. Scikit-learn의 메소드이니 만큼 1) 클래스 선언 2) fit 3) transform 의 과정으로 진행하며 feature_importance_ 속성을 지원하는 의사결정나무 기반의 다양한 모델에 wrapper로서 사용이 가능합니다. RFE의 파라미터로는 다음과 같고,

Parameter Description
estimator feature importance가 계산 가능한 모델
n_features_to_select 남겨질 중요한 feature의 수를 선언하며 지정되지 않을 경우 원래 feature의 절반이 선택됩니다.
step 매 스텝마다 제거될 feature 수를 의미합니다.

feature selection이 진행된 이후에 다음과 같은 속성을 지원합니다.

Attributes Description
estimator_ 선택된 feature들로만 훈련된 estimator
n_features_ 선택된 feature의 개수
ranking_ 각 feature의 순위이며 선택된 feature는 1이 됩니다.
support_ 선택된 feature를 가리키는 마스크를 리턴합니다.

 

실험 데이터로는 sklearn.datasets에서 인공 데이터를 생성하는 make_classification 함수를 사용합니다. (regression의 경우 make_regression 함수를 사용합니다.) 이 함수를 통해서 데이터/feature의 개수와 중요한/중요하지 않은 feature 개수를 지정할 수 있습니다.

import sklearn

from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_classification


X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5)

이후에 DecisionTreeClassifier를 이용해 데이터를 훈련시키고 sklearn.feature_selection의 RFE 함수를 호출해 wrapping합니다. support_ 와 ranking_ 속성으로 어떠한 feature가 선택되었는지 알 수 있습니다.

from sklearn.feature_selection import RFE
from sklearn.tree import DecisionTreeClassifier

# define RFE
rfe = RFE(estimator=DecisionTreeClassifier(), n_features_to_select=5)
# fit RFE
rfe.fit(X, y)
# summarize all features
for i in range(X.shape[1]):
    print('Column: %d, Selected %s, Rank: %.3f' % (i, rfe.support_[i], rfe.ranking_[i]))

 

RFE 에서는 선택할 feature 개수를 선택해야 하지만 cross-validation을 통해 자동으로 선택할 feature 개수를 선택할 수 있습니다. sklearn.feature_selection 모듈의 RFECV를 통해 이를 수행할 수 있습니다. RFE와 거의 비슷하지만 n_features_to_select 파라미터가 없어지고 cv 라는 파라미터가 생성되어 cross-validation 객체를 넣게 됩니다. (디폴트로는 5-fold cross-validation 이 사용됩니다.) 수행 결과 8개의 feture가 중요하다고 선택되었습니다. 

from sklearn.datasets import make_classification
from sklearn.model_selection import RepeatedStratifiedKFold
from sklearn.feature_selection import RFECV
from sklearn.tree import DecisionTreeClassifier

# define dataset
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5, n_redundant=5, random_state=1)
cv = RepeatedStratifiedKFold(n_splits=10, n_repeats=3, random_state=1)
rfe = RFECV(estimator=DecisionTreeClassifier(), cv=cv)
rfe.fit(X, y)

# summarize all features
for i in range(X.shape[1]):
    print('Column: %d, Selected %s, Rank: %.3f' % (i, rfe.support_[i], rfe.ranking_[i]))

마지막으로 scikit-learn의 메소드이니 만큼 transform() 을 이용하여 선택된 feature만 쉽게 filtering할 수 있습니다.

X_transformed = rfe.transform(X)
X_transformed.shape

정리하면 RFE는 중요하지 않은 feature 순으로 하나씩 제거함으로써 feature selection을 수행하는 방법으로 classification이나 regression에 적용 가능합니다. 특히 파이썬에서는 feature_importance_ 가 계산 가능한 다양한 모델에 wrapper로서 적용 가능하여 쉽게 사용할 수 있습니다.

 

참조

반응형