본문 바로가기

실습 note

앙상블 실습(랜덤포레스트,GBM,XGBoost,LightBoost)

반응형

Voting classifier

import pandas as pd
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import seaborn as sns
import matplotlib.pyplot as plt

#데이터 불러오기
cancer = load_breast_cancer()

data_df= pd.DataFrame(cancer.data, columns=cancer.feature_names)
data_df.head()

* voting의 인자는 estimators, voting 
* estimators : 개별 분류기를 튜플로 담아 넣는다 
* voting : hard or soft  (defalt hard)

# 개별 분류기 객체 생성
lr_clf= LogisticRegression()
knn_clf=KNeighborsClassifier(n_neighbors=8)

#개별 모델을 앙상블 모델로 구현
#soft : 각 분류기에서 출력된 레이블의 확률을 평균 낸것들 가장 높은걸 최종결과값으로 선정
vo_clf =VotingClassifier(estimators=[("LR",lr_clf), ('KNN', knn_clf)], voting='soft')

x_train,x_test,y_train,y_test = train_test_split(cancer.data, cancer.target, test_size=0.2, random_state=156)

#votinclassifier 학습/예측/평가
vo_clf.fit(x_train, y_train)
pred=vo_clf.predict(x_test)
print('voting 분류기 정확도: {0:.4f}'.format(accuracy_score(y_test,pred)))

#개별 모델의 학습/예측/평가
classifiers= [lr_clf, knn_clf]
for classifier in classifiers:
  classifier.fit(x_train,y_train)
  pred=classifier.predict(x_test)
  class_name= classifier.__class__.__name__
  print('{0} 정확도: {1:.4f}'.format(class_name, accuracy_score(y_test,pred)))


랜덤포레스트

* 중첩되는 데이터 세트를 생성 (부트스트래핑)
* 부트스트랩: 통계학에서는 데이터 세트를 임의로 만들어서 개별 평균의 분포도를 측정하는 목적을 위한 샘플링 방식을 지칭
from sklearn.ensemble import RandomForestClassifier 

#데이터 분리
x_train,x_test,y_train,y_test = train_test_split(cancer.data, cancer.target, test_size=0.2, random_state=156)

#랜덤 포레스트 학습 및 별도의 테스트 세트로 예측 성능 평가
rf_clf=RandomForestClassifier(random_state=0)
rf_clf.fit(x_train,y_train)
pred=rf_clf.predict(x_test)
accuracy = accuracy_score(y_test,pred)
print('랜덤 포레스트 정확도:{0:.4f}'.format(accuracy))

랜덤포레스트(하이퍼 파라미터 및 튜닝)

from sklearn.model_selection import GridSearchCV

params={
    'n_estimators': [100],
    'max_depth':[6,8,10,12],
    'min_samples_leaf':[8,12,18],
    'min_samples_split':[8,16,20]
}
rf_clf = RandomForestClassifier(random_state=0, n_jobs=-1)
grid_cv= GridSearchCV(rf_clf, param_grid=params, cv=2, n_jobs=-1)
grid_cv.fit(x_train,y_train)

print('최적 하이퍼 파라미터: \n', grid_cv.best_params_)
print('최고 예측 정확도: {0:.4f}'.format(grid_cv.best_score_))


최적 하이퍼 파라미터: 
 {'max_depth': 6, 'min_samples_leaf': 8, 'min_samples_split': 8, 'n_estimators': 100}
최고 예측 정확도: 0.9451
new_rf_clf= RandomForestClassifier(random_state=0 , n_estimators=300, max_depth=6, min_samples_split=8, min_samples_leaf=8)
new_rf_clf.fit(x_train,y_train)
pred=new_rf_clf.predict(x_test)
accuracy=accuracy_score(y_test, pred)
print("램던 포레트스 정확도:{0:.4f}".format(accuracy))

램던 포레트스 정확도:0.9474

feature importance

ttr_importances_values= new_rf_clf.feature_importances_
feature_importances = pd.Series(ttr_importances_values, index= cancer.feature_names)
tfr_top20=feature_importances.sort_values(ascending=False)[:20]

plt.figure(figsize=(16,10))
plt.title('Feature importtances Top 20')
sns.barplot(x=tfr_top20, y=tfr_top20.index)
plt.show()


GBM(Gradiant boosting machine)

* 여러 개의 약한 학습기를 순차적으로 학습-예측 후 잘못 예측한 데이터에 가중치를 부여함으로써 오류개선
* 가중치 업데이트 방식은 경사 하강법이며 오류 값은 true-pred 값
* 오류값을 최소화하는 방향으로 도달
* 과적합에도 뛰어난 예측 성능 발휘, 수행시간의 증가

from sklearn.ensemble import GradientBoostingClassifier
import time

#데이터 불러오기
x_train,x_test,y_train,y_test = train_test_split(cancer.data, cancer.target, test_size=0.2, random_state=156)

#GBM 수행시간 측정을 위한 시작 시간 설정
start_time =time.time()

gb_clf=GradientBoostingClassifier(random_state=0)
gb_clf.fit(x_train,y_train)
pred=gb_clf.predict(x_test)
accuracy = accuracy_score(y_test, pred)

print('GBM 정확도: {0:.4f}'.format(accuracy))
print('GBM 수행시간: {0:.1f}초'.format(time.time()-start_time))


GBM 정확도: 0.9561
GBM 수행시간: 0.4초

GBM 하이퍼 파라미터 및 튜닝

params={
    'n_estimators':[100,200,300,400,500],
    'learning_rate':[0.05,0.1]
}
grid_cv= GridSearchCV(gb_clf, param_grid=params, cv=2, verbose=1)
grid_cv.fit(x_train,y_train)
pred=grid_cv.predict(x_test)

print('최적의 하이퍼 파라미터:\n', grid_cv.best_params_)
print('최고 예측 정확도:{0:.4f}'.format(grid_cv.best_score_))


최적의 하이퍼 파라미터:
 {'learning_rate': 0.1, 'n_estimators': 100}
최고 예측 정확도:0.9385
#GridSearchCV를 이용해 최적으로 학습된 estimator
gb_pred=grid_cv.best_estimator_.predict(x_test)
gb_accuracy = accuracy_score(y_test,gb_pred)
print("GBM 정확도:{0:.4f}".format(gb_accuracy))

GBM 정확도:0.9561

XGBoost

from xgboost import XGBClassifier

xgb_wrapper= XGBClassifier(n_estimators=400, learning_rate=0.1, max_depth=3)
                                  #early_stopping_rounds: 조기종료까지 최소반복횟수  
evals =[(x_test, y_test)]
xgb_wrapper.fit(x_train, y_train, early_stopping_rounds=100, eval_metric='logloss', eval_set=evals, verbose=True)
w_pred=xgb_wrapper.predict(x_test)
w_pred_proba= xgb_wrapper.predict_proba(x_test)[:,1]
def get_clf_eval(y_test,pred):
  from sklearn.metrics import f1_score, accuracy_score,precision_score,recall_score,confusion_matrix
  confusion = confusion_matrix(y_test, pred)
  accuracy= accuracy_score(y_test, pred)
  precision=precision_score(y_test, pred)
  recall= recall_score(y_test, pred)
  #F1스코어 추가
  f1 =f1_score(y_test,pred)
  print('오차 행렬')
  print(confusion)
  #f1 score print 추가
  print('정확도 {0:.4f}, 정밀도 {1:.4f}, 재현율 {2:.4f}, F1:{3:.4f}'.format(accuracy,precision,recall,f1))
 
get_clf_eval(y_test,pred)

오차 행렬
[[35  2]
 [ 3 74]]
정확도 0.9561, 정밀도 0.9737, 재현율 0.9610, F1:0.9673

feature importance

from xgboost import plot_importance
fig,ax = plt.subplots(figsize=(10,12))
plot_importance(xgb_wrapper, ax=ax)


LightGBM

* 균형트리를 추구하지 않고 최대 손실값을 가지는 리프 노드를 계속 분할하는 방식

from lightgbm import LGBMClassifier

lgbm_wrapper = LGBMClassifier(n_estimators=400)

#w조기 중단 설정
evals=[(x_test,y_test)]
lgbm_wrapper.fit(x_train,y_train,early_stopping_rounds=100, eval_metric='logloss', eval_set=evals, verbose=True)
preds= lgbm_wrapper.predict(x_test)
pred_proba= lgbm_wrapper.predict(x_test)

get_clf_eval(y_test,preds)

오차 행렬
[[33  4]
 [ 2 75]]
정확도 0.9474, 정밀도 0.9494, 재현율 0.9740, F1:0.9615

feature importance

#중요도 시각화
from lightgbm import plot_importance
# %matplotlib inline

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

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형