XGBoost 모델에서의 변수선택


/* 2017.9.3 by 3months */


원본글

https://machinelearningmastery.com/feature-importance-and-feature-selection-with-xgboost-in-python/



Gradient Boosting에서의 변수 중요도 (Feature Importance)


gradient boosting의 장점은 boosted tree가 완성된 후, feature의 중요도 스코어를 내는 것이 상대적으로 쉽다는 것이다.  어떠한 변수가 decision tree에서 "중요한 결정" 을 내리는데 사용된다면 그 변수의 중요도는 높을 것이다. 중요도는 변수별로 계산되며, 각각의 변수는 중요도 랭킹에 따라 정렬될 수 있다. 어떠한 변수의 중요도는 하나의 decision tree에서 그 변수로 인해 performance measure를 증가하는 양으로 계산된다. 이 때 performance measure는 purity(Gini index)가 사용된다. 최종적인 변수의 중요도는 모든 decision tree의 중요도의 평균값이 된다. boosted decision tree에서 변수의 중요도를 구하는 기술적인 방법은 https://www.amazon.com/dp/0387848576?tag=inspiredalgor-20 이 책의 page 367 에서 볼 수 있다고 한다. 또한 https://stats.stackexchange.com/questions/162162/relative-variable-importance-for-boosting 이 링크도 참고할만 하다.



Python XGBoost에서 변수의 중요도 구하기


get_xgb_imp 함수를 이용해 XGBoost의 변수 중요도를 구할 수 있다. 해당 함수의 파라미터로 트레이닝된 XGBoost의 모델과 feature의 이름을 리스트 데이터 타입으로 넣어주면 된다.


출처 - https://stackoverflow.com/questions/38212649/feature-importance-with-xgbclassifier

def get_xgb_imp(xgb, feat_names):
    from numpy import array
    imp_vals = xgb.booster().get_fscore()
    imp_dict = {feat_names[i]:float(imp_vals.get('f'+str(i),0.)) for i in range(len(feat_names))}
    total = array(imp_dict.values()).sum()
    return {k:v/total for k,v in imp_dict.items()}


예)

from xgboost import XGBClassifier model = XGBClassifier()
# train_x와 train_y는 학습하고자 하는 트레이닝 셋의 설명변수와 종속변수의 ndarray 타입이다. model.fit(train_x, train_y) feat_names = [i for i in range(0,100)] # 변수가 100개인 경우 가정 feature_importance = get_xgb_imp(model,feat_names)

{0: 0.021963824289405683, 1: 0.020671834625323, 2: 0.041343669250646, 3: 0.023255813953488372, 4: 0.05297157622739018,
5: 0.03488372093023256, 6: 0.025839793281653745, 7: 0.021963824289405683, 8: 0.04780361757105943, 9: 0.04392764857881137,
10: 0.06847545219638243, 11: 0.023255813953488372, 12: 0.006459948320413436, 13: 0.012919896640826873,
14: 0.012919896640826873, 15: 0.015503875968992248, 16: 0.0012919896640826874, 17: 0.003875968992248062,
18: 0.006459948320413436, 19: 0.003875968992248062, 20: 0.002583979328165375, 21: 0.00904392764857881,
22: 0.0012919896640826874, 23: 0.0012919896640826874, 24: 0.00516795865633075, 25: 0.0, 26: 0.0,
27: 0.014211886304909561, 28: 0.002583979328165375, 29: 0.0012919896640826874, 30: 0.00516795865633075,
31: 0.002583979328165375, 32: 0.007751937984496124, 33: 0.003875968992248062, 34: 0.00904392764857881,
35: 0.0012919896640826874, 36: 0.012919896640826873, 37: 0.0103359173126615, 38: 0.015503875968992248,
39: 0.003875968992248062, 40: 0.006459948320413436, 41: 0.006459948320413436, 42: 0.012919896640826873,
43: 0.006459948320413436, 44: 0.0103359173126615, 45: 0.02454780361757106, 46: 0.025839793281653745,
47: 0.021963824289405683, 48: 0.006459948320413436, 49: 0.0103359173126615, 50: 0.01808785529715762,
51: 0.020671834625323 .....

* 결과는 위와 같이 dict 타입으로 반환된다.



변수 중요도 그래프 그리기


아래와 같이 matplotlib를 통해 변수 중요도의 barchart를 그릴 수 있다.

from matplotlib import pyplot
pyplot.bar(range(len(feature_importance)), feature_importance.values())
pyplot.show()