XGBoost : Dimension Reduction (feature selection)
1. Feature importance
2. BorutaShap
XGBoost 알고리즘으로 모델을 만들고
최대한 input variables을 줄여 경제적인 모델을 만들기 위해
두 가지 방법을 사용해 봄.
1. Feature importance
- XGBoost의 기본 내장된 feature_importance를 이용하는 방법.
- importance가 가장 작은 변수를 차례대로 제거 해주고 train에서 성능을 비교
- 본인의 기준에 맞게 제거할 변수를 선택
- 논리적이긴 하나 특별한 이론이 개입된 방법은 아니기 떄문에 신뢰성에 대한 이슈는 있음.
#1.1 XGBoost의 내장되어 있는 기능으로 importance를 순위로 확인함
# dimensionality reduction using feature importance
df_imp = pd.DataFrame({'imp':model.feature_importances_}, index = model.get_booster().feature_names)
df_imp = df_imp[df_imp.imp > 0].sort_values('imp').copy()
feat_num = df_imp.shape[0]
print("total number of features =", feat_num)
df_imp
#1.2 importance가 가장 작은 변수부터 제거하여 train에서 AUC를 확인.
auc_list = [mean(scores)]
for i in range(0,feat_num+1):
features = df_imp.index[i:(feat_num+1)].to_list()
mark_feature = X_train_features.columns[X_train_features.columns.isin(features)]
X_train_new = X_train_features[mark_feature].copy()
model_adj = XGBClassifier(colsample_bytree=0.8, gamma=0.6, learning_rate=0.01, max_depth=3,
min_child_weight=1, n_estimators=750, objective="binary:logistic",
reg_alpha=0.5, reg_lambda=8, scale_pos_weight=35, subsample=0.8,
nthread=6, random_state=SEED)
scores_adj = evaluate_model(X_train_new, y_train, model_adj)
print('%d, AUC = %.3f (%.3f)' % (i, mean(scores_adj), std(scores_adj)))
auc_list.append(mean(scores_adj))
# plot
plt.plot(auc_list)
6개 까지 제거하여도 성능이 크게 차이가 없다는 것을 확인함.
2. BorutaShap
install - pip
https://pypi.org/project/BorutaShap/
- 신뢰할 수 있음(패키지가 있으니).
- classification, regression 모두 이용 가능.
- 사용법이 간단함(링크 참고).
- 한눈에 보기 좋은 plot, 색으로 판단(기본 설정: 초록색=accepted, 빨간색=rejected)
# feature selection using BorutaShap
from BorutaShap import BorutaShap
from sklearn.base import clone
model_BS = clone(model)
Feature_Selector = BorutaShap(model=model_BS,
importance_measure='shap',
classification=True,
percentile=100,
pvalue=0.05)
Feature_Selector.fit(X=X_train_features,
y=y_train,
n_trials=100,
sample=False,
train_or_test = 'train',
normalize=True,
verbose=False,
random_state=SEED)
# boruta plot
Feature_Selector.plot(X_size=15,
which_features='all')