LITTLE BY LITTLE

[8] 파이썬 머신러닝 완벽 가이드 - 4. 분류(랜덤 포레스트, GBM, XGBOOST, LIGHT GBM) 본문

데이터 분석/파이썬 머신러닝 완벽가이드

[8] 파이썬 머신러닝 완벽 가이드 - 4. 분류(랜덤 포레스트, GBM, XGBOOST, LIGHT GBM)

위나 2022. 8. 17. 14:56

4. 분류

  1. 분류의 개요
  2. 결정 트리
  3. 앙상블 학습
  4. 랜덤 포레스트
  5. GBM(Gradient Boosting Machine)
  6. XGBoost(eXtra Gradient Boost)
  7. LightGBM
  8. 분류 실습 - 캐글 산탄데르 고객 만족 예측
  9. 분류 실습 - 캐글 신용카드 사기 검출
  10. 스태킹 앙상블
  11. 정리
더보기
  • 회귀
    1. 회귀 소개
    2. 단순 선형 회귀를 통한 회귀 이해
    3. 비용 최소화하기 - 경사 하강법 (Gradient Descent) 소개
    4. 사이킷런 Linear Regression을 이용한 보스턴 주택 가격 예측
    5. 다항 회귀와 과(대)적합/과소적합 이해
    6. 규제 선형 모델 - 릿지, 라쏘, 엘라스틱 넷
    7. 로지스틱 회귀
    8. 회귀 트리
    9. 회귀 실습 - 자전거 대여 수요 예측
    10. 회귀 실습 - 캐글 주택 가격 : 고급 회귀 기법
    11. 정리
  • 차원 축소 
    1. 차원 축소의 개요
    2. PCA (Principal Component Anlysis)
    3. LDA (Linear Discriminant Anlysis)
    4. SVD (Singular Value Decomposition)
    5. NMF (Non-Negative Matrix Factorization)
    6. 정리
  • 군집화
    1. K-평균 알고리즘 이해
    2. 군집 평가
    3. 평균 이동 (Mean shift)
    4. GMM(Gaussian Mixture Model)
    5. DBSCAN
    6. 군집화 실습 - 고객 세그먼테이션
    7. 정리
  • 텍스트 분석
    1. 텍스트 분석 이해
    2. 텍스트 사전 준비 작업(텍스트 전처리) - 텍스트 정규화
    3. Bag of Words - BOW
    4. 텍스트 분류 실습 - 20 뉴스그룹 분류
    5. 감성 분석
    6. 토픽 모델링 - 20 뉴스그룹
    7. 문서 군집화 소개와 실습 (Opinion Review 데이터셋)
    8. 문서 유사도
    9. 한글 텍스트 처리 - 네이버 영화 평점 감성 분석
    10. 텍스트 분석 실습 - 캐글 mercari Price Suggestion Challenge
    11. 정리
  • 추천 시스템
    1. 추천 시스템의 개요와 배경
    2. 콘텐츠 기반 필터링 추천 시스템
    3. 최근접 이웃 협업 필터링
    4. 잠재요인 협업 필터링
    5. 콘텐츠 기반 필터링 실습 - TMDV 5000 영화 데이터셋
    6. 아이템 기반 최근접 이웃 협업 필터링 실습
    7. 행렬 분해를 이용한 잠재요인 협업 필터링 실습
    8. 파이썬 추천 시스템 패키지 - Surprise
    9. 정리

4-4. 랜덤 포레스트(Random Forest)

  1. 배깅은 앞서 소개한 보팅과 다르게 같은 알고리즘으로 여러개의 분류기를 만들어 보팅으로 최종 결정하는 알고리즘이었다. 
  2. 배깅의 대표적인 알고리즘 랜덤포레스트이다. 
    1. 앙상블 알고리즘 중 비교적 빠른 속도
    2. 높은 예측 성능
    3. 기반 알고리즘은 결정 트리로서, 결정트리의 쉽고 직관적인 장점을 그대로 갖고 있다.
    4. 여러개의 결정 트리분류가 전체 데이터에서 배깅 방식으로 각자의 데이터의 샘플링을 통해 개별적 학습 수행 후 최정적으로 모든 분류기가 보팅을 통해 예측 결정을 하게됨
  1. 랜덤 포레스트의 개별적 분류기들의 기반 알고리즘은 결정트리이지만,
  2. 개별 트리가 학습하는 데이터셋은 전체 데이터가 일부 중첩되게 샘플링된 데이터 (Boostrapping 분할 방식)
  3. 그래서 배깅(bagging)은 부트 스트래핑(bootstrapping)의 줄임말
  4. *원래 bootstrap의 의미는 작은 데이터셋을 임의로 만들어, 개별 평균의 분포도를 측정하는 등의 목적을 위한 샘플링 방식을 지칭함
부트스트래핑 샘플링 방식(중첩되게 샘플링)
  1. 이렇게 데이터가 중첩된 개별 데이터셋에 결정트리 분류기를 각각 적용하는 것이 랜덤포레스트
  2. RandomForestClassifier 클래스 지원

get_human_dataset()을 이용해 학습/테스트용 dataframe을 가져오자.
https://noelee.tistory.com/74?category=1294038

[7] 파이썬 머신러닝 완벽 가이드 - 분류(결정 트리-제약을 통한 과적합 해결, 앙상블-보팅-소프트

4. 분류 분류의 개요 결정 트리 앙상블 학습 랜덤 포레스트 GBM(Gradient Boosting Machine) XGBoost(eXtra Gradient Boost) LightGBM 분류 실습 - 캐글 산탄데르 고객 만족 예측 분류 실습 - 캐글 신용카드 사기..

noelee.tistory.com

이 함수로 데이터 불러오기
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
import pandas as pd
import warnings
warnings.filterwarnings('ignore')
# 결정 트리에서 사용한 get_human_dataset()을 이용해 학습/테스트용 dataframe 반환
X_train, X_test, y_train, y_test = get_human_dataset()

# 랜덤 포레스트 학습 및 별도의 데이터셋으로 예측 성능 평가
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))

[Out]

랜덤 포레스트 정확도: 0.9253


- 랜덤포레스트는 사용자 행동 인식 데이터셋에 대해 92.53%의 정확도를 보여준다.

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

  1. 트리 기반 앙상블 알고리즘의 단점은 하이퍼 파라미터가 너무 많고, 그로인해 튜닝에 너무 많은 시간이 소요된다는 점
  2. 그리고 튜닝 후 예측 성능이 크게 향상되는 경우가 많지 않다.
  3. 트리 기반 하이퍼 파라미터가 원래 많은데, 배깅/부스팅/학습/정규화 등을 위한 하이퍼 파라미터까지 추가되므로, 일반적으로 다른 ML 알고리즘에 비해 많을 수 밖에 없다. 
  4. 그나마 랜덤 포레스트는 대부분 결정 트리에서와 같은 하이퍼 파라미터를 사용하기 때문에 적은편에 속함
  5. n_estimators : 랜덤 포레스트에서 결정 트리의 개수 지정 / 디폴트는 10개 / 많을수록 좋은 성능 기대(절대적X)/ 늘릴수록 학습 수행시간이 길어지는 것 감안
  6. max_features : 결정 트리에 사용된 max_features 파라미터와 같다.
    1. 하지만 RandomForestClassifier의 기본 max_features는 'None'이 아니라, 'auto'로, 'sqrt'와 같다.
    2. 따라서 랜덤 포레스트의 트릴르 분할하는 피처를 참조할 때, 전체 피처가 아니라 sqrt(전체 피처개수)만큼 참조 
    3. ex. 전체 피처가 16개라면 4개 참조
  7. max_depthmin_samples_leaf와 같이 결정트리에서 과적합 개선을 위해 사용하는 파라미터랜덤 포레스트에도 똑같이 적용될 수 있다.

이번에는 GridSearchCV를 이용해 랜덤 포레스트의 하이퍼 파라미터를 튜닝해보자.
- 튜닝 시간을 절약하기 위해 n_estimators는 100으로, CV를 2로만 설정해 최적 하이퍼 파라미터를 구해보자.
- 다른 하이퍼 파라미터를 최적화한 뒤에, n_estimators는 나중에 300으로 증가시켜서 예측 성능을 평가하자.
- (멀티 코어환경에서는 다음 예제에서 RandomRorestClassifier 생성자와 GridSearchCV 생성시 n_jobs=-1 파라미터를 추가하면 모든 CPU 코어를 이용해 학습할 수 있다.)

# GridSearhCV를 이용해 랜덤 포레스트의 하이퍼 파라미터를 튜닝해보자.
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]
}
# RandomForest Classifier 객체 생성 후 , GridSearchCV 수행
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_))

[Out]

최적 하이퍼 파라미터:
 {'max_depth': 10, 'min_samples_leaf': 8, 'min_samples_split': 8, 'n_estimators': 100}
최고 예측 정확도: 0.9180

- 'n_estimator': 100, 'max_depth' : 10, 'min_samples_leaf' : 8, 'min_samples_split' : 8일 때 약 91.68%의 평균 정확도가 측정되었다.

n_estimators를 100에서 300으로 증가시키고, 최적 하이퍼 파라미터로 다시 RandomForestClassifier를 학습시킨 뒤, 이번에는 별도의 테스트 데이터셋에서 예측 성능을 측정해보자.

rf_clf1 = RandomForestClassifier(n_estimators=300, max_depth=10, min_samples_leaf=8, \
                                 min_samples_split=8, random_state=0)
rf_clf1.fit(X_train, y_train)
pred = rf_clf1.predict(X_test)
print('예측 정확도 : {0:.4f}'.format(accuracy_score(y_test, pred)))

[Out]

예측 정확도: 0.9165

RandomForestClassifier의 feature_importances_속성을 이용해 알고리즘이 선택한 피처의 중요도를 막대그래프로 시각화해보자.

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

ftr_importances_values = rf_clf1.feature_importances_
ftr_importances = pd.Series(ftr_importances_values, index=X_train.columns)
ftr_top20 = ftr_importances.sort_values(ascending=False)[:20]

plt.figure(figsize=(8,6))
plt.title('Feature importances Top 20')
sns.barplot(x=ftr_top20, y=ftr_top20.index)
plt.show()
피처 중요도 순위 막대그래프

- tGravityAcc-min()-X / tGravityAcc-mean()-X / tGravityAcc-min()-Y 등이 높은 피처 중요도를 가지고 있다.


4-5. GBM(Gradient Boosting Machine)

  1. 보팅-배깅에 이어 부스팅 알고리즘에 대해 알아보자.
  2. 부스팅 알고리즘은 여러개의 '약한 학습기'를 순차적으로 학습-예측하면서 잘못 예측한 데이터에 가중치를 부여해 오류를 개선해나가는 학습 방식이다.
  3. 부스팅의 대표적인 구현은 AdaBoost(Adaptive Boosting)와 그래디언트 부스트가 있다.

Adaboost

AdaBoost는 오류 데이터에 가중치를 부여하며 부스팅을 수행하는 대표적 알고리즘

Adaboost
1번째 학습기에 가중치 0.3, 2번째 학습기에 0.5, 3번째 학습기에 0.8을 부여한 후 모두 결합해 예측을 수행
  1. Step 1 - 첫 번째 약한 학습기가 분류기준 +와 1로 분류한 것 (동그라미로 표시된 + 데이터는 + 데이터가 잘못 분류된 오류데이터)
  2. Step 2 - 이 오류 데이터에 대해서 가중치 값을 부여한다. 가중치가 부여된 오류 + 데이터(동그라미)는 다음 약한 학습기가 더 잘 분류할 수 있게 +의 크기가 커짐
  3. Step 3 - 두 번째 약한 학습기가 분류 기준 2로 +와 -를 분류하였다. 마찬가지로 동그라미 표시된 - 데이터는 오류 데이터
  4. Step 4 - 잘못분류된 오류데이터 - 에 대해서 다음 약한 학습기가 잘 분류할 수 있도록 더 큰 가중치를 부여, 더 잘 분류할 수 있게 -의 크기가 커짐
  5. Step 5 - 세 번째 약한 학습기가 분류 기준 3으로 +와 -를 분류하고, 오류 데이터를 찾는다. Adaboost는 이렇게 약한 학습기가 순차적으로 오류값에 대해 가중치를 부여한 예측 결정 기준을 모두 결합해 예측 수행
  6. 마지막으로 맨 아래 그림은 1,2,3번째 약한 학습기를 모두 결합한 결과 예측, 개별 약한 학습기보다 훨씬 정확도↑

GBM

  1. GBM(Gradient Boost Machine)도 Adaboost와 유사하나, 가중치 업데이트를 경사 하강법(Gradient Descent)을 이용하는 것이 큰 차이이다.
  2. 오류식 h(x) = y - F(x) 를 최소화하는 방향성을 가지고 반복적으로 가중치 값을 업데이트하는 것이 경사 하강법
  3. 다음장에서 회귀에 대해 다룰 때 더 알아보고, 여기서는 경사 하강법을 '반복 수행을 통해 오류를 최소화할 수 있도록 가중치 업데이트값을 도출하는 기법'으로 이해
  4. GBM은 CART 기반의 다른 알고리즘과 마찬가지로 분류는 물론, 회귀도 가능하다.
  5. GradientBoostingClassifier 클래스 제공

사이킷런의 GBM을 이용해 사용자 행동 데이터셋을 예측 분류해보자. (수행시간도 같이 측정해보자.)
또 get_human_dataset()함수로 데이터셋 가져오기

from sklearn.ensemble import GradientBoostingClassifier
import time
import warnings
warnings.filterwarnings('ignore')

X_train, X_test, y_train, y_test = get_human_dataset()

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

gb_clf = GradientBoostingClassifier(random_state=0)
gb_clf.fit(X_train, y_train)
gb_pred = gb_clf.predict(X_test)
gb_accuracy = accuracy_score(y_test, gb_pred)

print('GBM 정확도: {0:.4f}'.format(gb_accuracy))
print("GBM 수행 시간:{0:.4f}.".format(time.time() - start_time))
GBM 정확도: 0.9386 #랜덤 포레스트보다는 예측 성능이 뛰어난 경우가 많다.
GBM 수행 시간:827.1422.(초) # 대신에 오래 걸린다.

GBM 하이퍼 파라미터 및 튜닝

  1. n_estimators, max_depth, max_features와 같은 트리 기반 파라미터는 결정 트리, 랜덤포레스트에서와 같다.
  2. loss : 경사 하강법에서 사용할 비욤함수 지정 (특별한 이유 없을 시 기본 값 deviance 그대로 적용)
  3. learning_rate : GBM이 학습을 진행할 때마다 적용하는 학습률, weak learner가 순차적으로 오류 값을 보정해 나가는데 적용하는 계수
    1. 0~1값을 지정할 수 있으며 기본 값은 0.1이다.
    2. 너무 작은 값을 적용하면 업데이트 되는 값이 작아져서 최소 오류값을 찾아 예측 성능이 높아질 가능성이 있지만 모든 weak learner의 반복이 완료되어도 최소 오류 값을 찾지 못할 수도 있다. (그리고 오래 걸린다.)
    3. 반대로 큰 값을 적용하면 최소 오류값을 찾지 못하고 그냥 지나쳐버려 예측 성능이 떨어질 가능성 (대신 빠르다.)
    4. 이러한 특성 때문에 learning_rate는 n_estimators와 상호보완적으로 조합해 사용한다. learning_rate를 작게 하고 n_estimators를 크게하면 더 이상 성능이 좋아지지 않는 한계점까지는 예측성능이 좋아질 수 있음. 그래도 오래걸리는 단점이 있으며, 예측성능이 눈에띄게 좋아지지도 않는다.
  4. n_estimators : weak learner의 개수이다. 많을수록 예측성능이 좋아질 수 있응나, 수행시간이 오래 걸린다. 기본값은 100이다.
  5. subsample : weak learner가 학습에 사용하는 데이터의 샘플링 비율이다. 기본 값은 1이며, 1일시 전체 학습 데이터를 기반으로 학습한다는 의미, 0.5일시 학습 데이터의 50%. 과적합이 염려될 경우 1보다 작은 값으로 설정

GridSearchCV를 이용해 하이퍼 파라미터를 최적화해보자. n_estimators=100,500으로, learning_rate=0.05,0.1로 제약하고, 교차 검증세트는 2개로만 설정해서 GridSearchCV를 적용해보자.


4-6. XGBoost (eXtra Gradient Boost)

  1. XGBoost는 트리 기반의 앙상블 학습에서 많이 쓰이는 알고리즘 중 하나이다.
  2. GBM에 기반하고 있지만, GBM의 단점인 느린 수행 시간 및 과적합 규제(Regularization) 부재 등의 문제를 해결
  3. 병렬 CPU환경에서 병렬 학습이 가능해 GBM보다 빠르게 학습을 완료할 수 있다. (GBM하고 비교하자면 빠른 것)
  4. Tree pruning(나무 가지치기) : 일반적으로 GBM은 분할 시 부정 손실이 발생하면 분할을 더 이상 수행하지 않지만, 이런 방식이어도 지나치게 많은 분할을 발생할 수 있다. GBM처럼 max_depth 파라미터로 분할 깊이를 조정하기도 하지만, tree pruing으로 더 이상 긍정 이득이 없는 분할을 가지치기 해서 분할 수를 더 줄일 수 있는 장점을 갖고 있다.
  5. 자체 내장된 교차 검증 : 지정된 반복횟수가 아니라, 교차검증을 통해 평가 데이터셋의 평가 값이 최적화되면 반복을 중간에 멈출 수 있는 조기 중단 기능도 있다.
  6. 결손값 자체 처리 기능도 있다.
  7. XGBoost 전용의 파이썬 패키지 xgboost 패키지도 있고, 머신러닝 사용자들이 사이킷런과 연동할 수 있도록 래퍼 클래스(Wrapper class)로 XGBClassifier, XGBRegressor 모듈도 제공한다.
  8. 하이퍼 파라미터 유형
    1. 일반 파라미터 : 실행시 스레드 개수나 silent모드 등의 선택을 위한 파라미터, 바꾸는 경우는 거의 없음
      1. boostergbtree(tree based model) 또는 gblinear( linear model) 선택. 디폴트는 gbtree입니다.
      2. silent:디폴트는 0이며, 출력 메시지를 나타내고 싶지 않을 경우 1로 설정
      3. nthreadCPU의 실행 스레드 개수를 조정하며, 디폴트는 CPU의 전체 스레드를 다 사용하는 것. (멀티 코어/스레드 CPU 시스템에서 전체 CPU를 사용하지 않고 일부 CPU만 사용해 ML 애플리케이션을 구동하는 경우에 변경)
    2. 부스터 파라미터 : 트리 최적화, 부스팅, regularization 관련 파라미터 지칭
      1. eta [default=0.3, alias:learning_rate]:GBM의 학습률(learning rate)과 같은 파라미터.
        1. 0에서 1 사이의 값을 지정하며 부스팅 스텝을 반복적으로 수행할 때 업데이트되는 학습률 값.
        2. 파이썬 래퍼 기반의 xgboost를 이용할 경우 디 폴트는 0.3.
        3. 사이킷런 래퍼 클래스를 이용할 경우 eta는 learning_rate 파라미터로 대체되며, 디폴트는 0.1이고, 보통은 0.01 - 0.2 사이의 값을 선호한다.
      2. num_boost_rounds : GBM의 n_estimators와 같은 파라미터
      3. min_child_weight[default=1] : 트리에서 추가적으로 가지를 나눌지를 결정하기 위해 필요한 데이터들의 weight 총합이다. 클수록 분할을 자제함으로써 과적합을 조절하기 위해 사용된다.
      4. gamma [default=0, alias:min_split_loss] : 트리의 리프 노드를 추가적으로 나눌지를 결정할 최소 손실 감소 값, 해당 값보다 큰 손실이 감소된 경우, 리프 노드를 분리하며, 값이 클수록 과적합 감소효과가 있다.
      5. max_depth[default=6] : 트리 기반 알고리즘의 max_depth와 같다. 0을 지정하면 깊이 제한이 없고, depth가 높으면 특정 피처 조건에 특화되어 룰 조건이 만들어져 과적합 가능성이 높아짐 (보통3-10 사이 값 적용)
      6. sub_sample[default=1] : GBM의 subsample과 동일하다. 트리가 커져서 과적합되는 것을 제어하기 위해 데이터를 샘플링하는 비율 지정 (0.5지정시, 전체 데이터의 절반을 트리 생성에 사용, 보통 0.5-1 사이 값 적용)
      7. colsample_bytree[default=1] : GBM의 max_features와 유사하다. 트리 생성에 필요한 피처(칼럼)를 임의로 샘플링하는데 사용, 매우 많은 피처가 있는 경우 과적합 조정에 적용
      8. lambda [default=1, alias: reg_lambda] : L2 Regularization 적용 값이다. 피처 개수가 많을 경우 적용을 검토하며, 값이 클수록 과적합 감소효과가 있다.
      9. alpha [default=0, alias: reg_alpha] : L1 Regularization 적용 값이다. 피처 개수가 많을 경우 적용을 검토하며, 값이 클수록 과적합 감소 효과가 있다.
      10. scale_pos_weight [default=1] : 특정 값으로 치우친 비대칭한 클래스로 구성된 데이터셋의 균형을 유지하기 위한 파라미터이다.
    3. 학습 테스크 파라미터: 학습 수행 시의 객체 함수, 평가를 위한 지표 등을 설정하는 파라미터
      1. objective : 최솟값을 가져야할 손실 함수를 정의한다. 이진분류인지 다중분류인지에 따라 달라짐
      2. binary:logistic : 이진 분류일 때 적용
      3. multi: softamax : 다중 분류일 때 적용, 손실함수가 multi:softmax일 경우에는 레이블 클래스의 개수인 num_class 파라미터를 지정해야 한다.
      4. multi: softprob : multi:softamax와 유사하나, 개별 레이블 클래스의 해당되는 예측 확률을 반환한다.
      5. eval_metric : 검증에 사용되는 함수를 정의한다. 기본 값은 회귀인 경우는 rmse, 분류일 경우에는 error이다. 
        • rmse, mae, logloss (negative log-likelihood), error (binary classification error rate, 0.5 threshold), merror (multi classification error rate), mlogloss (multiclass logloss), auc
    4. 뛰어난 알고리즘일수록 파라미터를 튜닝할 필요가 적으며, 파라미터 튜닝에 들이는 공수 대비 성능 향상 효과가 높지 않은 경우가 대부분이다. 파라미터를 튜닝하는 경우의 수는 여러가지 상황에 따라 달라진다. (피처의 수가 매우 많거나, 피처 간 상관되는 정도가 많거나 .. )
과적합 문제가 심각하다면 다음과 같이 적용할 것을 고려할 수 있다.

- eta 값 낮추기 (0.01~0.1), eta 값을 낮출 경우, num_round(또는 n_estimators)는 반대로 높여주어야 한다.
- max_depth 값 낮추기
- min_child_weight 값 높이기
- gamma 값 높이기
- subsample과 colsample_bytree를 조정하는 것도 트리가 너무 복잡하게 생성되는 것을 막아 과적합 문제에 도움
  1. XGBoost 자체적으로 교차검증, 성능평가, 피처 중요도 등의 시각화 기능을 가지고 있다. 또한, 다른 GBM에서 부족한 여러가지 성능 향상 기능이 있다.
  2. 조기 중단 기능(Early Stopping) : 예를들어 n_estimators=200, 조기중단 파라미터값을 50으로 설정하면, 1부터 200회까지 부스팅을 반복하다가 50회를 반복하는 동안 학습 오류가 감소하지 않으면 더이상 부스팅을 진행하지 않고 종료 / 혹은 학습 오류값이 0.8인데, 101-150회 반복하는 동안 예측 오류가 0.8보다 작은 값이 하나도 없으면 부스팅을 종료.

파이썬 래퍼(Wrapper) XGBoost 적용 - 위스콘신 유방암 예측

  1. 위스콘신 유방암 데이터셋은 종양의 크기, 모양 등의 다양한 속성값을 기반으로 악성 종양(malignant)인지 양성 종양(benign)인지 분류한 데이터셋
  2. load_breast_cancer() 호출로 위스콘신 유방암 데이터셋을 불러오자.
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
cancer_df.head(3)

[Out]

 

종양의 크기과 모양에 관련된 많은 속성이 숫자형 값으로 되어있고, 타깃 레이블 값의 종류는 악성인 'malignant'가 0, 양성인 'benign'이 1으로 되어있다.
레이블 값의 분포를 확인해보자.

print(dataset.target_names)
print(cancer_df['target'].value_counts())
['malignant' 'benign']
1    357
0    212
Name: target, dtype: int64

양성 357개, 음성 212개로 구성되어있다. 학습용/테스트용 데이터셋으로 나누자

# 전체 데이터 중 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)
  1. 파이썬 래퍼 XGBoost는 사이킷런과 차이가 여러 가지 있지만. 먼저 눈에 띄는 차이는 학습용과 테 스트용 데이터 세트를 위해 별도의 객체인 DMatrix를 생성한다는 점이다.
  2. DMatrix의 주요 입력 파라미터는 data와 label이다. data는 피처 데이터 세트이며, label은 분류의 경우에는 레이블 데이터 세트,회귀의 경우는숫자형인 종속값 데이터 세트
  3. DMatrix는 넘파이 외에 libsvm txt 포맷 파일, xgboost 이진 버퍼 파일을 파라미터로 입력받아 변환가능
  4. 판다스의 DataFrame으로 데이터 인터페이스를 하기 위해서는 DataFrame.values를 이용해 넘파이로 일차 변환한 뒤에 이를 이용해 DMatrix 변환을 적용

다음은 넘파이 형태의 학습 데이터 세트와 테스트 데이터 세트를 DMatrix로 변환하는 예제

dtrain = xgb.DMatrix(data=X_train, label=y_train)
dtest = xgb.DMatrix(data=X_test, label=y_test)
  1. 파이썬 래퍼 XGBoost 모듈인 xgboost를 이용해 학습을 수행하기 전에, 먼저 XGBoost의 하이퍼 파라미터를 설정한다.
  2. XGBoost의 하이퍼 파라미터는 주로 딕셔너리 형태로 입력한다.
  3. 다음과 같은 하이퍼 파라미터 설정을 딕셔너리 형태로 만들어보자.
    1. max_depth=3
    2. eta=0.1
    3. objective='binary:logistic'
    4. eval_metric : logloss
    5. num_rounds(부스팅 반복횟수)=400
params = {'max_depth':3,
          'eta' : 0.1,
          'objective' : 'binary:logistic',
          'eval_metric' : 'logloss',
          'early_stopping' : 100
          }
num_rounds = 400
  1. 조기 중단은 xgboost의 train() 함수에 early_stopping_rounds 파라미터를 입력하여 설정한다. 100으로 설정하자.
  2. early_stopping_rounds 파라미터를 설정해 조기 중단을 수행하기 위해서는 반드시 eval_set과 eval_metric이 함께 설정되어야 한다.
  3. XGBoost는 반복마다 eval_set으로 지정된 데이터셋에서 eval_metric의 지정된 평가 지표로 예측 오류 측정
    1. eval_set은 성능평가를 수행할 평가용 데이터셋 설정
      • eval_set 평가할 데이터셋 dtrain과 dtest를 각각 train, eval로 하여 리스트 wlist를 만들어, train()의 파라미터 evals=wlist 입력
    2. eval_metric은 평가 세트에 적용할 성능 평가 방법, 분류일 경우 주로 error(분류 오류), logloss를 적용
      1. eval_metric은 위에서 params 딕셔너리에 하이퍼 파라미터로 넣어놓았다. (eval_metric='logloss')
# 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, \
                      early_stopping_rounds=100, evals=wlist)

[Out]

[0]	train-logloss:0.609688	eval-logloss:0.61352
Multiple eval metrics have been passed: 'eval-logloss' will be used for early stopping.

Will train until eval-logloss hasn't improved in 100 rounds.
[1]	train-logloss:0.540803	eval-logloss:0.547843
[2]	train-logloss:0.483753	eval-logloss:0.494248
[3]	train-logloss:0.434457	eval-logloss:0.447986
[4]	train-logloss:0.39055	eval-logloss:0.409109
[5]	train-logloss:0.354146	eval-logloss:0.374977
.
.
.
[310]	train-logloss:0.005457	eval-logloss:0.085923
[311]	train-logloss:0.00545	eval-logloss:0.085948
Stopping. Best iteration:
[211]	train-logloss:0.006413	eval-logloss:0.085593
  1. train()으로 학습 수행하면 반복시 train_error과 eval_logloss가 지속적으로 감소한다.
  2. xgboost를 이용해 모델의 학습이 완료됐으면 이를 이용해 테스트 데이터셋에 예측을 수행해보자.
  3. 파이썬 래퍼 XGBoost는 train()함수를 호출해 학습이 완료된 모델 객체를 반환하게 되는데, 이 모델 객체는 예측을 위해 predict() 메소드를 이용한다.
  4. 유의할 점은 사이킷런의 predict()메소드는 결과로 클래스값 (0,1)을 반환하는 반면, xgboost의 predict()는 예측 결괏값이 아닌, 예측 결과를 추정할 수 있는 확률 값을 반환한다는 것이다. 즉, 본 예제에서는 암이 악성인지 양성인지 판단하는 이진 분류이므로, 예측 확률이 0.5보다 크면 1, 그렇지 않으면 0으로 예측값을 결정하는 로직을 추가하면 된다.
# 3장 평가에서 생성한 get_clf_eval() 함수로 예측 성능을 평가해보자.
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix

# 호출한 지표들을 한꺼번에 계산하는 함수 정의
def get_clf_eval(y_test, pred,pred_probs):
    confusion = confusion_matrix(y_test, pred)
    accuracy = accuracy_score(y_test, pred)
    precision = precision_score(y_test, pred)
    recall = recall_score(y_test, pred)
    print('오차행렬')
    print(confusion)
    print('정확도 : {:.4f}\n정밀도 : {:.4f}\n재현율 : {:.4f}'.format(accuracy, precision, recall))
get_clf_eval(y_test, preds, pred_probs)

[Out]

오차행렬
[[35  2]
 [ 1 76]]
정확도 : 0.9737
정밀도 : 0.9744
재현율 : 0.9870

이번에는 xgboost 패키지 내에 내장된 시각화 기능을 수행해보자.

  1. xgboost의 plot_importance()는 피처의 중요도를 막대그래프로 나타낸다.
  2. 기본 평가 지표로 f1 스코어를 기반으로 하여 각 피처의 중요도를 나타냄
  3. 사이킷런은 Estimator 객체의 feautre_importances_ 속성으로 시각화코드를 작성했었음
  4. 사용시 주의할 점은 xgboost 넘파이 기반의 피처 데이터로, 학습시에 피처명을 제대로 알 수 없어 f0, f1과 같이 피처 순서별로 f자 뒤에 순서를 붙여서 X축에 피처들로 나열한다.
from xgboost import plot_importance
import matplotlib.pyplot as plt
%matplotlib inline

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

- 결정 트리에서 보여준 트리 기반 규칙 구조도 xgboost에서 시각화할 수 있다. xgboost 모듈의 to_graphviz() 를 이용하면 된다. (Graphviz 프로그램과 패키지가 설치되어있어야 한다, 이전에 실습 생략했었음)

- 파이썬 래퍼 XGBoost는 사이킷런의 GridSearchCV와 유사하게 데이터셋에 대한 교차 검증 수행 후 최적 파라미터를 구할 수 있는 방법을 cv()로 제공한다.

XGBoost의 cv()
XGBoost의 cv()의 파라미터에 대한 설명

- xgb.cv의 반환값을 dataframe 형태이다.
이제 사이킷런 래퍼 XGBoost에 대해 알아보자.

사이킷런 래퍼 XGBoost의 개요 및 적용

  1. 사이킷런의 기본 estimator을 그대로 상속해 만들었기 때문에, 다른 estimator과 동일하게 fit()과 predict()만으로 학습과 예측이 가능하고, GridSearchCV, Pipeline 등 사이킷런의 다른 유틸리티를 그대로 사용할 수 있기 때문에, 기존의 다른 머신러닝 알고리즘으로 만들엉놓은 프로그램이 있더라도, 알고리즘 클래스만 XGBoost 래퍼 클래스로 바꾸면 그대로 사용 가능
  2. 기존의 파이썬 래퍼 XGBoost와의 하이퍼 파라미터가 어떻게 다른지 알아두자.
파이썬 래퍼 XGBoost → 사이킷런 래퍼 XGBoost

3. 또한 xgboost와 n_estimators와 num_boost_round 하이퍼 파라미터는 서로 동일한 파라미터이다. 만일 2개가 동시에 사용된다면, 파이썬 래퍼 xgboost에서는 n_estimators를 무시하고, num_boost_round 파라미터를 적용하고, 사이킷런 래퍼 xgboost에서는 n_esetimators를 적용
4. 위스콘신 대학병원의 유방암 데이터셋 분류를 위한 래퍼 클래스인 XGBClassifier을 이용하여 예측해보자. (앞의 예제)
5. 모델의 하이퍼 파라미터는 동일하게 n_estimators(num_rounds 대응)는 400, learning_rate(eta 대응)는 0.1, max_depth=3으로 설정
6. XGBClassifier 클래스의 fit(), predict(), predict_proba()를 이용해 학습-예측을 수행하자.

# 사이킷런 래퍼 XGBoost 클래스인 XGBClassifier 임포트
from xgboost import XGBClassifier

xgb_wrapper = XGBClassifier(n_estimators=400, learning_rate=0.1, max_depth=3)
xgb_wrapper.fit(X_train, y_train)
w_preds = xgb_wrapper.predict(X_test)
w_pred_proba = xgb_wrapper.predict_proba(X_test)[:, 1]

# 똑같이 get_clf_eval() 함수로 모델의 예측 성능 평가
get_clf_eval(y_test, w_preds, w_pred_proba)
오차행렬
[[35  2]
 [ 1 76]]
정확도 : 0.9737
정밀도 : 0.9744
재현율 : 0.9870

- 앞의 파이썬 래퍼 XGBoost와 동일한 평가결과가 나왔다. 여기에서도 조기 중단으르 수행할 수 있다.
- early_stopping_rounds, 평가지표 eval_metric, 성능평가를 수행할 데이터셋 eval_set 지정
- 성능 평가를 수행할 데이터셋은 학습 데이터가 아니라, 별도의 데이터셋이어야 한다.
- early_stopping_rounds를 100, eval_metric은 logloss, eval_set은 테스트 데이터셋으로 설정해보자.
- 여기서 평가를 위한 데이터셋으로 테스트 데이터셋을 사용하였는데, 바람직한 방법은 아니다. 테스트 데이터셋은 학습 시에는 완전히 알려지지 않은 데이터셋을 사용해야한다.(과적합 방지) 단, 이 예제에서는 데이터셋의 크기가 작아서 테스트 데이터를 평가용으로 사용하였다.

from xgboost import XGBClassifier

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]

[Out]

[0]	validation_0-logloss:0.61352
Will train until validation_0-logloss hasn't improved in 100 rounds.
[1]	validation_0-logloss:0.547842
[2]	validation_0-logloss:0.494247
[3]	validation_0-logloss:0.447986
[4]	validation_0-logloss:0.409109
.
.
.
[305]	validation_0-logloss:0.086059
[306]	validation_0-logloss:0.085971
[307]	validation_0-logloss:0.085998
[308]	validation_0-logloss:0.085999
[309]	validation_0-logloss:0.085877
[310]	validation_0-logloss:0.085923
[311]	validation_0-logloss:0.085948
Stopping. Best iteration:
[211]	validation_0-logloss:0.085593

- n_estimators를 400으로 설정해도, 400번 반복을 수행하지 않고, 311번 반복한 후 학습을 완료하였다.
- 311번 반복 후 멈춘 이유는 211번 반복시 logloss가 0.08559이고, 311번 반복시 logloss가 0.08594인데, 211번에서 311번까지 early_stopping_rounds=100으로 지정된 100번의 반복 동안 성능 평가 지수가 향상되지 않았기 때문에 더이상 반복되지 않고 멈춘 것
조기 중단으로 학습된 XGBClassifier의 예측 성능을 살펴보자.

get_clf_eval(y_test, ws100_preds, ws100_pred_proba)

[Out]

오차행렬
[[34  3]
 [ 1 76]]
정확도 : 0.9649
정밀도 : 0.9620
재현율 : 0.9870

- 조기 중단이 적용되지 않은 결과보다 약간 저조한 성능을 나타냈지만, 큰 차이는 아니다.
- 조기 중단 값을 너무 급격하게 줄이면 예측 성능이 저하될 우려가 크다. 만일 early_stopping_rounds를 10으로 하면, 아직 성능이 향상될 여지가 있음에도 불구하고 10번 반복하는 동안 성능 평가 지표가 향상되지 않으면, 반복이 멈춰버려서 충분한 학습이 되지 않아 예측 성능이 나빠질 수 있다.
early_stopping_rounds를 10으로 설정하고 예측 성능을 재측정해보자.

# early_stopping_rounds를 10으로 설정하고 재학습
xgb_wrapper.fit(X_train, y_train, early_stopping_rounds=10,
                eval_metric="logloss", eval_set=evals, verbose=True)
ws10_preds = xgb_wrapper.predict(X_test)
ws10_pred_proba = xgb_wrapper.predict_proba(X_test)[:,1]
get_clf_eval(y_test, ws10_preds, ws10_pred_proba)

[Out]

[0]	validation_0-logloss:0.61352
Will train until validation_0-logloss hasn't improved in 10 rounds.
[1]	validation_0-logloss:0.547842
[2]	validation_0-logloss:0.494247
[3]	validation_0-logloss:0.447986
[4]	validation_0-logloss:0.409109
.
.
.
[60]	validation_0-logloss:0.091939
[61]	validation_0-logloss:0.091461
[62]	validation_0-logloss:0.090311
Stopping. Best iteration:
[52]	validation_0-logloss:0.089577

오차행렬
[[34  3]
 [ 2 75]]
정확도 : 0.9561
정밀도 : 0.9615
재현율 : 0.9740

- 62번 반복까지만 수행된 후 학습이 종료되었다. 62번 반복의 logloss가 0.0903, 52번 반복의 logloss가 0.0895로서 10번의 반복 동안 성능 평가 지수가 향상되지 못해서 더 이상의 반복을 수행하지 않고 학습이 종료된 것
- 이렇게 학습된 모델로 예측한 결과 정확도는 약 0.9561로 early_stopping_rounds=100일 때 0.9649였던 것과 비교하여 더 낮다.
- 앞에서와 같이 plot_importance로 시각화 결과를 도출하여 피처 중요도를 막대그래프로 확인할 수 있다.


4-7. LightGBM

  1. LightGBM은 XGBoost보다 학습 시간이 짧고, 메모리 사용량도 상대적으로 적다. 예측성능은 별 차이 없으나, 기능상의 다양성은 LightGBM이 더 많다.
  2. 단점은 적은 데이터셋에 적용할 경우 과적합이 발생하기 쉽다. (일반적으로 10,000건 이하의 데이터셋)
  3. 일반 GBM 계열의 트리 분할 방법과 다르게, 리프 중심 트리 분할(Leaf Wise)방식을 사용한다.
    1. 기존의 대부분 트리 기반 알고리즘은 트리의 깊이를 효과적으로 줄이기 위한 균형 트리 분할 방식(Level Wise)을 사용한다. 과적합에 더 강한 구조를 가질 수 있다고 알려져있기 때문
    2. 하지만 균형을 맞추기위한 시간이 필요하다는 단점이 있다.
    3. 반면에 LightGBM의 리프 중심 트리 분할 방식은 트리의 균형을 맞추지 않고, 최대 손실 값(max delta loss)을 가지는 리프 노드를 지속적으로 분할하면서 트리의 깊이가 깊어지고, 비대칭적 규칙 트리가 생성됨
    4. 이렇게 최대 손실값을 가지는 리프노드를 지속적으로 분할해 생성된 규칙 트리는 학습을 반복할수록 균형 중심 트리 분할 방식보다 예측 오류 손실을 최소화할 수 있다는 것이 LightGBM의 구현 사상
기존의 대부분 트리 기반 알고리즘 vs LightGBM
  1. Light GBM의 XGBoost 대비 장점은 1)더 빠른 학습/예측 수행 시간, 2)더 작은 메모리 사용량, 3)카테고리형 피처의 자동 변환과 최적 분할(원-핫 인코딩 사용없이도 카테고리형 피처를 최적으로 변환, 이에 따른 노드 분할 수행)
  2. XGBoost와 마찬가지로, 파이썬 패키지 lightgbm과 사이킷런 래퍼 Light GBM - LGBMClassifier, LGBMRegressor 두 가지가 있다.

이제부터는 사이킷런 래퍼 클래스만 설명 (사이킷런에 익숙하면 별도의 파이썬 래퍼 클래스를 사용하지 않아도 되기 때문)

LightGBM과 하이퍼 파라미터

  1. XGBoost와 많이 유사하다. 주의해야할 점은 LightGBM은 XGBoost와 다르게 리프 노드가 계속 분할되면서 트리의 깊이가 깊어지므로 이러한 트리 특성에 맞는 하이퍼 파라미터 설정이 필요하다 (ex. 매우 큰 max_depth 값을 가짐)
  2. 주요 파라미터 
    1. num_iterations [ default = 100 ] : 반복 수행하려는 트리의 개수 지정
      • 크게 지정할수록 예측 성능이 높아질 수 있지만, 너무 높으면 과적합으로 성능 저하될 가능성
      • 사이킷런 GBM과 XGBoost의 사이킷런 호환 클래스의 n_estimators와 같은 파라미터
    2. learning_rate [ default = 0.1] : 0과 1사이의 값을 지정하며 부스팅 스텝을 반복적으로 수행할 때 업데이트되는 학습률 값
      • 일반적으로 n_estimators를 크게하고, learning_rate를 작게 해서 예측 성능을 향상시킬 수 있으나, 마찬가지로 과적합 이슈와 학습 시간이 길어지는 부정적인 영향도 고려해야한다. 
      • GBM, XGBoost의 learning rate와 같음
    3. max_depth [ default = -1 ] : 트리 기반 알고리즘의 max_depth와 같다. 
      • 0보다 작은 값을 지정하면 깊이에 제한이 없다.
      • 이전에 나온 Depth wise 방식의 트리와 다르게 LightGBM은 Leaf wise 기반이므로 깊이가 상대적으로 더 깊다.
    4. num_leaves [ default = 20 ] : 결정 트리의 min_samples_leaf와 같은 파라미터이다. 
      • 사이킷런 래퍼 LightGBM 클래스인 LightGBMClassifier에서는 min_child_samples 파라미터로 사용
      • 최종 결정 클래스인 리프 노드가 되기 위해서 최소한으로 필요한 레코드 수이며, 과적합 제어를 위한 파라미터이다.
    5. num_leaves [ default = 31 ] : 하나의 트리가 가질 수 있는 최대 리프 개수
    6. boosting [ default = gbdt ] : 부스팅의 트리를 생성하는 알고리즘을 기술
      • gbdt : 일반적인 그래디언트 부스팅 결정트리
      • rf : 랜덤 포레스트
    7. bagging_fraction [ default = 1.0 ] : 트리가 커져서 과적합이 되는 것을 제어하기 위해 데이터를 샘플링하는 비율을 지정한다.
      • 사이킷런의 GBM과 XGBClassifier의 subsample 파라미터와 동일하기에 사이킷런 래퍼 LightGBM인 LightGBMClassifier에서는 subsample로 동일하게 파라미터 이름이 변경된다.
    8. feature_fraction [ default = 1.0] : 개별 트리를 학습할 때마다 무작위로 선택하는 피처의 비율, 과적합을 막기 위해 사용
      • GBM의 max_features와 유사하며, XGBClassifier의 colsample_bytree와 똑같으므로 LightGBM Classifier에서는 동일하게 colsample_bytree로 변경된다.
    9. lambda_l2 [ default = 0.0 ] : L2 regulation 제어를 위한 값으로, 피처개수가 많을 경우 적용을 검토하며 값이 클수록 과적합 감소 효과
      • XGBClassifier의 reg_lambda와 동일하므로 LightGBMClassifier에서는 reg_lambda로 변경
    10. lambda_l1 [ default = 0.0] : L1 regulation 제어를 위한 값으로, L2와 마찬가지로 과적합 제어를 위한 것
      • XGBClassifier의 reg_alpha와 동일하므로 LightGBMClassifier에서는 reg_alpha로 변경된다,

Learning Task 파라미터

  1. objective : 최솟값을 가져야 할 손실함수를 정의, xgboost에서와 동일

하이퍼 파라미터 튜닝 방안

  1. num_leaves의 개수를 중심으로 min_child_samples(min_data_in_leaf), max_depth를 함께 조정하면서 모델의 복잡도를 줄이는 것이 기본 튜닝 방안이다.
    1. num_leaves는 개별 트리가 가질 수 있는 최대 리프 개수, LightGBM 모델의 복잡도를 제어함 - num_leaves를 높일 시 정확도가 높아지는 반면, 반대로 트리의 깊이가 깊어지고, 과적합 영향도 커진다.
    2. min_data_in_leaf : 사이킷런 래퍼클래스에서 min_child_samples로 이름이 바뀐다 - 보통 큰 값으로 설정시 트리가 깊어지는것을 방지
    3. max_depth : 명시적으로 깊이의 크기를 제한한다. 위 2개와 함께 과적합 개선에 사용
같은 파라미터에 대한 이름 비교

LIGHT GBM 적용 - 위스콘신 유방암 예측

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

# 앞서 XGBoost와 동일하게 n_estimators는 400으로 설정
import lightgbm as lgb
from lightgbm import LGBMClassifier
lgbm_wrapper = LGBMClassifier(n_estimators=400)
 
# LightGBM도 XGBoost와 동일하게 조기 중단 수행 가능
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_proba(X_test)[:, 1]

[Out]

[1]	valid_0's binary_logloss: 0.565079	valid_0's binary_logloss: 0.565079
Training until validation scores don't improve for 100 rounds.
[2]	valid_0's binary_logloss: 0.507451	valid_0's binary_logloss: 0.507451
[3]	valid_0's binary_logloss: 0.458489	valid_0's binary_logloss: 0.458489
[4]	valid_0's binary_logloss: 0.417481	valid_0's binary_logloss: 0.417481
[5]	valid_0's binary_logloss: 0.385507	valid_0's binary_logloss: 0.385507
.
.
.
[143]	valid_0's binary_logloss: 0.186084	valid_0's binary_logloss: 0.186084
[144]	valid_0's binary_logloss: 0.185302	valid_0's binary_logloss: 0.185302
[145]	valid_0's binary_logloss: 0.187856	valid_0's binary_logloss: 0.187856
[146]	valid_0's binary_logloss: 0.190334	valid_0's binary_logloss: 0.190334
[147]	valid_0's binary_logloss: 0.192769	valid_0's binary_logloss: 0.192769
Early stopping, best iteration is:
[47]	valid_0's binary_logloss: 0.126108	valid_0's binary_logloss: 0.126108

- 조기 중단으로 147번 반복까지만 수행하고, 학습을 종료하였다.
학습된 LightGBM 모델을 기반으로 예측 성능을 평가해보자.
[Out]

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

- 정확도는 94.7%로 XGBoost보다 조금 작지만, 학습 데이터셋과 테스트 데이터셋의 크기가 작아서, 알고리즘 간 성능 비교는 큰 의미가 없다.
피처 중요도 시각화도 해보자.

from lightgbm import plot_importance
import matplotlib.pyplot as plt
%matplotlib inline

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

- light gbm에 내장된 plot_importance() 역시 넘파이로 피처 데이터를 학습할 경우, 피처명을 알 수 없기에 column_ 뒤에 피처 순서대로 숫자를 붙여 X축에 나열 랜덤 포레스트 예제에서는 train,test셋을 불러와 dataframe으로 변환하는 작업을 했었고, 여기서는 train, test 셋을 직접 나누었고, train_test_split은 ndarray를 반환하기 때문에 .columns를 사용할 수 없어 다른 방법으로 column 번호 대신 피처명을 적어야한다.


Comments