Q . Permutation Importances( 순열중요도 )란?
A . 검증데이터에서 각 특성을 제거하지 않고 특성값에 무작위로 노이즈를 주어 기존 정보를 제거하여 특성이 기존에 하던 역할을 하지 못하게 하고 성능을 측정한다.
- 이때 노이즈를 주는 가장 간단한 방법이 그 특성값들을 샘플들 내에서 섞는 것( shuffle, permutation )이다.
import eli5
from eli5.sklearn import PermutationImportance
# permuter 정의
permuter = PermutationImportance(
pipe.named_steps['rf'], # model
scoring='accuracy', # metric
n_iter=5, # 다른 random seed를 사용하여 5번 반복
random_state=2
)
# permuter 계산은 preprocessing 된 X_val을 사용합니다.
X_val_transformed = pipe.named_steps['preprocessing'].transform(X_val)
# 실제로 fit 의미보다는 스코어를 다시 계산하는 작업입니다
permuter.fit(X_val_transformed, y_val);
feature_names = X_val.columns.tolist()
pd.Series(permuter.feature_importances_, feature_names).sort_values()
# 특성별 score 확인
eli5.show_weights(
permuter,
top=None, # top n 지정 가능, None 일 경우 모든 특성
feature_names=feature_names # list 형식으로 넣어야 합니다
)
Q . Feature Importance란?
A . 각각 특성을 모든 트리에 대해 평균불순도감소(mean decrease impurity)를 계산한 값이다.
- sklearn 트리 기반 분류기에서 디폴트로 사용되는 특성 중요도는 속도는 빠르지만 결과를 주의해서 봐야 한다.
- High cardinalty 특성이 특성 중요도가 높게 나올 수 있다.
- Class가 많으면 feature가 중요하지 않아도 불순도가 낮아지기 때문에 특성 중요도가 높게 나온다.
불순도 감소(impurity decrease)는 다음과 같이 계산한다.
sample_weight
가 주어진다면, , , , 는 가중합을 합니다.# 특성 중요도
rf = pipe.named_steps['randomforestclassifier']
importances = pd.Series(rf.feature_importances_, X_train.columns)
%matplotlib inline
import matplotlib.pyplot as plt
n = 20
plt.figure(figsize=(10,n/2))
plt.title(f'Top {n} features')
importances.sort_values()[-n:].plot.barh();
Q . Drop-Column Importance란?
A . 매 특성을 drop한 후 fit을 다시한다.
- 단점 : 매우 느리다
- 칼럼 하나씩 제거 -> fit -> score
- 특성이 n개 존재할 때 n+1번 학습이 필요하다.
column = 'opinion_seas_risk'
# opinion_h1n1_risk 없이 fit
pipe = make_pipeline(
OrdinalEncoder(),
SimpleImputer(),
RandomForestClassifier(n_estimators=100, random_state=2, n_jobs=-1)
)
pipe.fit(X_train.drop(columns=column), y_train)
score_without = pipe.score(X_val.drop(columns=column), y_val)
print(f'검증 정확도 ({column} 제외): {score_without}')
# opinion_h1n1_risk 포함 후 다시 학습
pipe = make_pipeline(
OrdinalEncoder(),
SimpleImputer(),
RandomForestClassifier(n_estimators=100, random_state=2, n_jobs=-1)
)
pipe.fit(X_train, y_train)
score_with = pipe.score(X_val, y_val)
print(f'검증 정확도 ({column} 포함): {score_with}')
# opinion_h1n1_risk 포함 전 후 정확도 차이를 계산한다.
print(f'{column}의 Drop-Column 중요도: {score_with - score_without}')
Q . 부스팅과 배깅의 차이점은?
A . 트리를 만드는 방법에 차이가 있다. 배깅의 경우 각 트리를 독립적으로 만들지만 부스팅은 만들어지는 트리가 이전에 만들어진 트리에 영향을 받는다.
분류문제를 풀기 위해서는 트리 앙상블 모델을 많이 사용합니다.
Q . AdaBoost란?
A . 각 트리( 약한 학습기들, weak learners )가 만들어질 때 잘못 분류되는 관측치에 가중치를 준다. 그리고 다음 트리가 만들어질 때 이전에 잘못 분류된 관측치가 더 많이 샘플링되게 하여 그 관측치를 분류하는데 더 초점을 맞춘다.
최종 학습기 H(x) 는 약한 학습기들()의 가중()합으로 만들어진다.
여기서 가 크면 가 작다는 것으로 분류기 성능이 좋다는 것이고
여기서 가 작으면 가 크다는 것으로 분류기 성능이 안좋다는 뜻이다.
Q . Gradient Boosting이란?
A . 그래디언트 부스팅은 샘플의 가중치를 조정하는 대신 잔차(residual)을 학습하도록 한다. 이것은 잔차가 더 큰 데이터를 더 학습하도록 만드는 효과가 있다.
- 그래디언트 부스팅은 AdaBoost와 유사하지만 비용함수( Loss function )을 최적화하는 방법에 있어서 차이가 있다.
from xgboost import XGBClassifier
pipe = make_pipeline(
OrdinalEncoder(),
SimpleImputer(strategy='median'),
XGBClassifier(n_estimators=200
, random_state=2
, n_jobs=-1
, max_depth=7
, learning_rate=0.2
)
)
pipe.fit(X_train, y_train);
from sklearn.metrics import accuracy_score
y_pred = pipe.predict(X_val)
print('검증 정확도: ', accuracy_score(y_val, y_pred))
print(classification_report(y_pred, y_val))
Early Stopping을 사용하여 과적합을 피한다.
Q .왜n_estimators
최적화를 위해 GridSearchCV나 반복문 대신 early stopping을 사용할까?
A .n_iterations
가 반복수라 할때, early stopping을 사용하면 우리는n_iterations
만큼의 트리를 학습하면 된다.
하지만 GridSearchCV나 반복문을 사용하면 무려sum(range(1,n_rounds+1))
트리를 학습해야 한다!
거기에max_depth
,learning_rate
등등 파라미터 값에 따라 더 돌려야 한다.
따라서, early stopping을 잘 활용하는게 훨씬 효과적이다.
타겟 비율이 균형이 안맞을 때는 클래스에 weight를 주기 위해 ratio를 계산한다