let us not love with words or tongue but actions and truth.

IT/파이썬

Permutation Feature Importance(변수중요도)를 통한 feature selection

sarah0518 2020. 12. 24. 18:09
728x90

오늘은 permutation feature importance에 대해서 알아보려고 해요.

 

파이썬 코드에 대한 설명에 앞서서, 기본 변수중요도를 파악하는 방법과의 차이를 간단히 설명 드릴게요.

 

stepwise, backward, forward 방식은 변수중요도를 파악하는 가장 간단한 방법이죠. 

 

 

SAS에서 주로 활용하긴 하는데,

Forward는 변수를 하나씩 추가하면서 설명력이 높이지는 가장 best feature들을 찾는 것이고,

 

 

https://quantifyinghealth.com/stepwise-selection/

 

 

 

반대로 Backward는 전체 변수를 다 넣고 시작해서, 하나씩 변수를 제거하는 방식으로 진행합니다.

 

 

 

https://quantifyinghealth.com/stepwise-selection/

 

stepwise는 단계별로 변수를 넣었다 제거하는 방식이구요.

 

파이썬에서 기본적인 feature importance를 구하는 방식도 stepwise와 유사하다고 보시면 됩니다.

특정 변수의 상대적 영향도를 측정하여 분류 모델의 불순도를 더 많이 낮춰주는 변수들을 찾는 것이지요.

 

 

 

Feature Importance의 한계점

하지만 단순 feature importance(a.k.a variable importance)는 한계점이 존재하는데요.

간단히 설명 드리면, feature importance의 결과는 bias될 가능성이 큽니다.

 

 

 

예를 들어,

분류모델에서 1/0을 가진 A변수와 1/2/3/4/5의 5개 분류를 가진 B변수를 분류모델에 넣는다면

어느것이 활용 도가 높을까요?

 

 

당연, B변수이겠죠.

분류할 수 있는 분기점들이 많으니까,

더 다양한 조합으로 분류를 해볼수 있는 기회가 많은 샘이죠.

 

 

 

permutation feature importance은 각 변수들의 순서를 무작위로 섞은 뒤,

중요도를 판단하려고 하는 그 feature를 noise로 만듭니다.

 

따라서, 모델이 해당 변수에 대한 의존도가 높을 수록 설명력은 감소하겠죠.

 

이런식으로 각 변수의 중요도를 판단하여 importace를 뽑아주는 것인데,

그렇다고 하더라도 위의 feature importance의 한계점은 상쇄시킬수는 없다고 판단 됩니다.

 

 

>>soohee410.github.io/iml_permutation_importance

permutation importance에 대한 더 많은 설명을 위해 읽어보세요.

 

 

 

파이썬 소스코드

그래도 단순 feature importance보다는 더 변동성을 줄여줄테니,

이 방법에 대해 파이썬으로 구현해보려고합니다.

 

 

아래는 함수로 여러 모형에 대한 permuation importance를 구할 수 있도록 구현한 방법입니다.

random forest, gradient boosting 그리고 xg boosting에 대해서

permutation importance를 구하고,

 

"iloc[:45]" 이 부분에서 보다시피 표로 45개의 변수까지의 importance값을 return값으로 받습니다.

 

 

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
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import GradientBoostingClassifier
import xgboost
from xgboost import XGBClassifier
from sklearn.inspection import permutation_importance
 
def clf(x, y, col_list):
# random forest
    rfc = RandomForestClassifier(max_depth=12, random_state=99, criterion = "entropy",n_estimators = 3, max_features='auto')
    rfc.fit(x, y)
    result_rfc = permutation_importance(rfc, x,y , n_repeats=10, random_state=333, n_jobs=2)
    sorted_idx_rfc = result_rfc.importances_mean.argsort()
    importances_rf = pd.DataFrame(result_rfc.importances_mean[sorted_idx_rfc], index=x.columns[sorted_idx_rfc]).sort_values(0, ascending=False).iloc[:45]
   
# gradient boosting
    gb = GradientBoostingClassifier(criterion='friedman_mse',loss='deviance', max_depth=5, n_estimators=30, random_state=99, max_features='auto')
    gb.fit(x, y)
    result_gb = permutation_importance(gb, x,y , n_repeats=10, random_state=333, n_jobs=2)
    sorted_idx_gb = result_gb.importances_mean.argsort()
    importances_gb = pd.DataFrame(result_gb.importances_mean[sorted_idx_gb], index=x.columns[sorted_idx_gb]).sort_values(0, ascending=False).iloc[:45]
   
# xg boosting
    xg = XGBClassifier(booster='gbtree', max_depth=7,  gamma=0.5, learning_rate=0.01, n_estimators=3, random_state=99)
    xg.fit(x, y)
    result_xg = permutation_importance(xg, x,y , n_repeats=10, random_state=333, n_jobs=2)
    sorted_idx_xg = result_xg.importances_mean.argsort()
    importances_xg = pd.DataFrame(result_xg.importances_mean[sorted_idx_xg], index=x.columns[sorted_idx_xg]).sort_values(0, ascending=False).iloc[:45]
 
    return importances_rf, importances_gb,importances_xg
   cs

 

 

[output]

1
rfc_list, gb_list, xg_list=clf(x,y,col_list)
cs

 

permutation importance 그래프 그리기

 

위에처럼 숫자가 아닌 box-plot으로 중요도를 그래프로 나타내는 방법입니다.

특히 한글같은 경우에는 출력이 안되는 경우가 많은데,

font 다운받으셔서(전 나눔고딕으로 했습니다)

python환경에 업로드하시고 사용하시면 됩니다.

 

 

NanumGothicCoding.ttf
2.65MB

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from sklearn.inspection import permutation_importance
import matplotlib.pyplot as plt
import seaborn as sns
sns.set(font="NanumGothic",
        rc={"axes.unicode_minus":False},
        style='whitegrid')
result = permutation_importance(rfc, x, y, n_repeats=10,
                                random_state=99, n_jobs=2)
sorted_idx = result.importances_mean.argsort()
 
fig, ax = plt.subplots()
ax.boxplot(result.importances[sorted_idx].T,
           vert=False, labels=x.columns[sorted_idx])
ax.set_title("Permutation Importances (test set)")
fig.tight_layout()
plt.show()
cs

 

 

[output]

728x90

'IT > 파이썬' 카테고리의 다른 글

one-hot encoding(원-핫 인코딩)  (0) 2021.01.04
kkma를 활용한 word cloud 그리기  (0) 2021.01.03
Dummy Classifier  (0) 2020.12.23
Lasso regression(라쏘 회귀분석)  (0) 2020.12.22
GridSearchCV 그리드서치 1탄  (0) 2020.12.21