inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

[개정판] 파이썬 머신러닝 완벽 가이드

피처 중요도 시각화 plot_importance() 질문입니다.

해결된 질문

6231

Idea

작성한 질문수 23

0

안녕하세요.

아래와 같이 피쳐 중요도를 시각화하면,  강사님 말씀대로 y축의 피처 명들이 출력되지 않습니다.

from xgboost import plot_importance

import matplotlib.pyplot as plt

%matplotlib inline

fig, ax = plt.subplots(figsize = (10, 12))

plot_importance(xgb_wrapper, ax = ax)

그래서 구글링을 해서 찾아보니 set_yticklabels라는게 있더군요. 코드를 다음과 같이 변경하니 피처 명들이 나오긴 하는데, 이게 맞는 방법인지 확신이 안서서 질문드립니다.

from xgboost import plot_importance

import matplotlib.pyplot as plt

%matplotlib inline

fig, ax = plt.subplots(figsize = (10, 12))

plot_importance(xgb_wrapper, ax = ax).set_yticklabels(dataset.feature_names)

python 머신러닝 배워볼래요? 통계

답변 6

1

권 철민

위 코드는 확인해보니 사이킷런 wrapper의 feature_importances_ 값과 xgboost의 피처별 f1 score를 뽑아내는 로직이 서로 달라서 안맞는 것이었군요.

그리고 set_yticklabels() 를 이용하는 방식을 저도 stackoverflow에서 찾았는데, 답변하신 분이 잘못 생각하신것 같습니다. set_ysticklabels()안에 f1 score 별로 feature 들을 정렬해서 입력해야 하는데, 단순하게 컬럼명만 입력해서는 안됩니다.

https://stackoverflow.com/questions/46943314/xgboost-plot-importance-doesnt-show-feature-names

 f1 score 별로 feature들을 정렬해 주려면, xgboost 모듈내에서 이를 지원하는 api가 있으면 좋을 텐데 저는 찾지 못했습니다.

결론적으로 말씀드리면 사이킷런 xgboost wrapper를 사용하실 때에는 앞에 말씀드린 DataFrame을 피처 데이터 세트로 이용하거나 python xgboost를 사용하실때는 아래와 같이 DMatrix를 만들때 feature names을 인자로 입력하는 방법중 하나를 선택하면 될 것 같습니다.

import xgboost as xgb
from xgboost import plot_importance

import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')

dataset = load_breast_cancer()
X_features= dataset.data
y_label = dataset.target

cancer_df = pd.DataFrame(data=X_features, columns=dataset.feature_names)
cancer_df['target']= y_label

X_train, X_test, y_train, y_test=train_test_split(X_features, y_label,
                                         test_size=0.2, random_state=156 )

# DMatrix 생성 시 인자로 feature_names를 입력
dtrain = xgb.DMatrix(data=X_train , label=y_train, feature_names=dataset.feature_names)
dtest = xgb.DMatrix(data=X_test , label=y_test, feature_names=dataset.feature_names)

params = { 'max_depth':3,
           'eta': 0.1,
           'objective':'binary:logistic',
           'eval_metric':'logloss',
           'early_stoppings':100
        }
num_rounds = 400

# train 데이터 셋은 ‘train’ , evaluation(test) 데이터 셋은 ‘eval’ 로 명기합니다.
wlist = [(dtrain,'train'),(dtest,'eval') ]
# 하이퍼 파라미터와 early stopping 파라미터를 train( ) 함수의 파라미터로 전달
xgb_model = xgb.train(params = params , dtrain=dtrain , num_boost_round=num_rounds , evals=wlist )

import matplotlib.pyplot as plt
%matplotlib inline

fig, ax = plt.subplots(figsize=(10, 12))
plot_importance(xgb_model, ax=ax)

1

권 철민

안녕하십니까,

plot_importance()를 사용할 때 컬럼명이 안나오는것은 feature 데이터 세트가 numpy 이기 때문입니다. feature 데이터 세트를 DataFrame으로 바꾸면 컬럼명이 나옵니다. 그런데 Xgboost의 경우는 feature 데이터 세트를 numpy로 하는게 더 좋습니다. DataFrame으로 하다보면, 이유를 알 수 없는 버그가 발생합니다. 특히 복잡한 데이터 가공을 xgboost와 함께 진행하다보면 이렇게 발생하는 버그 때문에 많은 시간을 소모할 수 있습니다. 아래는 plot_importance() 를 DataFrame으로 feature 데이터 세트를 만들었을 때의 코드 입니다. 

import xgboost as xgb
from xgboost import plot_importance
from xgboost import XGBClassifier

import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import warnings
import matplotlib.pyplot as plt
%matplotlib inline
warnings.filterwarnings('ignore')

dataset = load_breast_cancer()
X_features= dataset.data
y_label = dataset.target

cancer_df = pd.DataFrame(data=X_features, columns=dataset.feature_names)
cancer_df['target']= y_label

X_features = cancer_df.iloc[:, :-1]
y_label = cancer_df.iloc[:, -1]

# 전체 데이터 중 80%는 학습용 데이터, 20%는 테스트용 데이터 추출
X_train, X_test, y_train, y_test=train_test_split(X_features, y_label,
                                         test_size=0.2, random_state=156 )
print(X_train.shape , X_test.shape)

xgb_wrapper = XGBClassifier(n_estimators=400, learning_rate=0.1, max_depth=3)

evals = [(X_test, y_test)]
xgb_wrapper.fit(X_train, y_train, early_stopping_rounds=100, eval_metric="logloss",
                eval_set=evals, verbose=True)

ws100_preds = xgb_wrapper.predict(X_test)
ws100_pred_proba = xgb_wrapper.predict_proba(X_test)[:, 1]


fig, ax = plt.subplots(figsize=(10, 12))
# 사이킷런 래퍼 클래스를 입력해도 무방.
plot_importance(xgb_wrapper, ax=ax)

감사합니다.

0

Genie Lee

안녕하세요 강사님,

첫번째 답변에서, Xgboost는 feature 데이터 세트가 numpy로 하는 게 좋다고 하셨는데, 그럼  DataFrame으로 말고 numpy 형태로 놔두는 것이 좋은 건가요? 아니면 Datafraom으로 바꾸는 것이 좋은 건가요?

0

권 철민

안녕하십니까, 

옛날 버전 xgboost는 numpy로 하는게 더 좋은데, 지금은 버전업이 되어서 DataFrame으로 바꿔도 별 문제가 없군요. 

0

Genie Lee

아하! 그렇군요! 빠른 답변감사합니다! DataFrame으로 해보겠습니다~!

0

Idea

감사합니다!

저도 올려주신 stackoverflow를 참고해서 질문 드렸는데, 그 답변자 분께서 해주신 설명이 좀 이상해서 질문드렸던 겁니다.

앞으로는 알려주신 방법을 참고하겠습니다.

0

권 철민

방법이 있을거 같아서 아래와 같이 코드를 수행해 봤는데, 결과가 위 코드랑 다르군요. 참고 부탁드립니다.

import seaborn as sns

ftr_importances_values = xgb_wrapper.feature_importances_
ftr_importances = pd.Series(ftr_importances_values,index=X_train.columns  )
ftr_top20 = ftr_importances.sort_values(ascending=True)

fig, ax = plt.subplots(figsize = (10, 12))

plot_importance(xgb_wrapper, ax = ax).set_yticklabels(ftr_top20.index)

0

Idea

답변 감사드립니다.

추가적으로 제가 질문드린 set_yticklabels()를 이용해서 해결할 수 있는 방법은 혹시 없을까요?

안녕하세요 열심히 수강중인 학생입니다

0

63

2

정수 인덱싱

0

68

2

넘파이 오류

0

85

2

11강 numpy의 axis 축 질문 드립니다.

0

85

2

Kaggle 에서 Santander customer satisfaction data 를 다운로드 되지가 않습니다.

0

79

2

Feature importances 를 보여주는 barplot 이 그래프로 안보여져요.

0

70

2

타이타닉 csv 파일이 주피터 화면에 보이지 않습니다.

0

75

2

타이타닉 csv 파일이 주피터 화면에 보이지 않습니다.

0

64

2

5강 강의 오류가 있어요.

0

84

1

실무에서 LTV 관련 모델 선택 질문입니다!

0

72

2

14강 강의 듣는중에 궁금한게 있어서 질문합니다~

0

69

3

파이썬 다운그레이 후 사이킷런 재설치

0

117

2

좋은 강의 감사합니다.

0

72

2

scoring 함수 음수값

0

67

2

6번 강의에 사이킷런, 파이썬, 아나콘다 각각 버전 일치 안 시키고 진행해도 강의 따라가 지나요?

0

100

2

분류 평가 정확도 예측

0

77

2

안녕하세요. 강의 들으면서 업무에 적용하고 싶은 수강생입니다.

0

99

1

카카오톡 채널 있나요

0

107

1

혹시 강의에서 사용하시는 ppt 받을 수 있는건가요

0

190

2

pca 스케일링 관련하여 질문드립니다.

0

100

2

주피터 대신 구글 코랩

0

172

2

강의에서 사용하는 pdf or ppt자료는 따로 없는 건가요?

0

148

2

실루엣 스코어..

0

86

2

float64 null 값 처리 방법

0

103

2