[ML] XGBoost, LightGBM, Stacking

hyunyoungjin·2020년 9월 19일
4

저번 글에서는 대표적인 앙상블 알고리즘인 Random Forest와 Gradient Boosting에 대해 정리했었다. 이번 글에서는 기존의 Gradient Boosting을 뛰어넘는 새로운 알고리즘인 XGBoost, LightGBM, Stacking을 알아볼 것이다.

06. XGBoost (eXtra Gradient Boost)

1. XGBoost 개요

트리 기반의 앙상블 학습.

2. 파이썬 래퍼 XGBoost 하이퍼 파라미터

파라미터의 유형

  1. 일반 파라미터 : 일반적으로 실행 시 스레드의 개수나 냐ㅣ둣 모드 등의 선택을위한 파라미터로서 디폴트 파라미터 값을 바꾸는 경우는 거의 없다.

  2. 부스터 파라미터 : 트리 최적화, 부스팅, regularization 등의 관련 파라미터들을 지칭.

  3. 학습 태스크 파라미터 : 학습 수행 시의 객체 함수, 평가를 위한 지표등을 설정하는 파라미터.

주요 일반 파라미터
1. booster : gbtree(나무 기반 모델) or gblinear (회귀 기반 모델)선택, 디폴트는 gbtree

  1. silent : 출력 메시지를 나타내고 싶지 않을 경우 1로 설정 , 디폴트 = 0

  2. nthread : cpu의 실행 스레드 개수를 조정, 디폴트는 cpu의 전체 스레드를 다 사용하는 것.

주요 부스터 파라미터

regularization(정규화) : 과적합 모델을 일반화 해주는 기법

  • L1 Regularization (lasso): 기존 함수에 계수의 절댓값에 가중치를 곱한 것을 더해주는 것

  • L2 Regularization (ridge) : 기존함수에 계수의 제곱의 가중치를 곱한 것을 더해주는 것

🔗regularization 개념 설명 페이지

학습 태스크 파라미터

  • log loss : 로그 우도에 -1을 곱한 값

우도, 가능도(liklelihood) : 어떤 값이 관측 되었을때, 이것이 어던 확률 분포에서 온건지에대한 확률

🔗확률(probability)과 가능도(likelihood) 그리고 최대우도추정(likelihood maximazation)

  • ROC: 분류모델의 성능을 보여주는 그래프
  • AUC: ROC 곡선의 아래 면적 (1일때 가장 좋음)

🔗auc와 roc에 관련 설명 페이지

3. 과적합 제어

과적합을 제어하는 방법

  • eta 값을 낮춘다. (0.01 ~ 0.1) → eta 값을 낮추면 num_round(n_estimator)를 반대로 높여주어야 한다.
  • max_depth 값을 낮춘다.
  • min_child_weight 값을 높인다.
  • gamma 값을 높인다.
  • subsample과 colsample_bytree를 낮춘다.

XGBoost는 자체적으로 교차 검증, 성능평가, 피처 중요도 등의 시각화 기능을 가지고 있다. 또한 다른 여러가지 성능을 향상시키는 기능을 가지고 있다.

Ex) Early Stopping 조기 중단 기능

GBM의 경우 n_estimators에 지정된 횟수만큼 학습을 끝까지 수행하지만, XGB의 경우 오류가 더 이상 개선되지 않으면 수행을 중지

Ex) n_estimators 를 200으로 설정하고, 조기 중단 파라미터 값을 50으로 설정하면, 1부터 200회까지 부스팅을 반복하다가 50회를 반복하는 동안 학습오류가 감소하지 않으면 더 이상 부스팅을 진행하지 않고 종료합니다.

07. LightGBM

1. LightGBM 개요

XGBoost는 GBM보다는 빠르지만 여전히 학습시간이 오래 걸리고, 대용량 데이터로 학습 성능을 기대하려면 높은 병렬도로 학습을 진행해야 한다.

LightGBM의 장점

  • XGBoost보다 학습에 걸리는 시간이 훨씬 적다.

  • 메모리 사용량도 상대적으로 적다.

  • 기능상의 다양상도 XGBoost보다 약간 더 많다.

    ex. 카테고리형 피처의 자동 변환(원ㅡ핫 인코딩 사용하지않는)과 이에 따른 최적 분할이다.

  • XGBoost와 마찬가지로 대용량 데이터에 대한 뛰어난 성능 및 병렬컴퓨팅 기능을 제공하고 최근에는 추가로GPU까지 지원한다.

XGBoost의 장점은 계승하고 단점은 보완하는 방식으로 개발되었다.

LightGBM의 단점

  • 적은(10,000건 이하)의 데이터 셋에 적용할 경우 과적합 발생 쉽다.

기존 GBM과의 차이점

  • 기존의 트리 기반 알고리즘 : 균형트리 분할(Level Wise) 방식 사용

→ 오버피팅에 더 강하지만 균형을 맞추기 위한 시간이 필요하다.

  • LightGBM : 리프 중심 트리 분할(Leaf Wise) 방식 사용

→ 트리의 균형을 맞추지 않고 최대 손실값(max delta loss)를 가지는 리프 노드를 지속적으로 분할하며 트리 깊이 확장하면서 트리의 깊이가 깊어지고 비대칭적 규칙 트리 생성한다.

→ 학습을 반복할 수록 균형트리분할방식보다 예측 오류 손실을 최소화할 수 있다.

패키지 설명

  1. 패키지명 : 'lightgbm'
  2. 초기에 lightgbm은 독자적인 모듈로 설계되었으나 편의를 위해 scikit-learn wrapper로 호환이 가능하게 추가로 설계되었다. 패키지 내에 파이썬 래퍼, 사이킷런 래퍼 모두 내장하고있다. 사이킷런 래퍼 LightGBM클래스는 분류를 위한 LGBMClassifier클래스와 회귀를 위한 LGBMRegressor클래스이다.
  3. fit( ), predict( ) 기반의 학습 및 예측과 사이킷런이 제공하는 다양한 기능 활용이 가능하다.

사이킷런에 익숙하다면 별도의 파이썬 래퍼 클래스를 사용하지 않아도 된다.

Light GBM은 leaf-wise 방식을 취하고 있기 때문에 수렴이 굉장히 빠르지만, 파라미터 조정에 실패할 경우 과적합을 초래할 수 있다.

2. LightGBM 설치

아나콘다로 쉽게 설치 가능하다. 단, 윈도우에 설치할 경우에는 Visual Studio Build tool 2015 이상이 먼저 설치돼 있어야한다. 그 후에 OS 터미널에서 conda명령어를 수행한다.

(윈도우10에서는 아나콘다 프롬프트→관리자 권한으로 실행→ conda명령어 수행)

conda install -c conda-forge lightgbm

도중에 나오는 Proceed([y]/n)에서 y를 입력하고 엔터를 누른다.

3. LightGBM 하이퍼 파라미터

XGBoost와 많은 부분이 유사하다. 주의할 점은 위의 트리분할 방식차이에 따라 이러한 트리 특성에 맞는 하이퍼 파라미터 설정이 필요하다는 점이다.(예를들어 max_depth가 매우 크게 가진다는 것)

주요파라미터

Learning Task 파라미터

objective : 최솟값을 가져야 할 손실함수 정의. 회귀, 다중클래스분류, 이진 분류인지에따라 지정

튜닝방안

  1. num_leaves(트리의 최대 리프 개수)를 중심으로 min_data_in_leaf와 max_depth를 함께 조정하면서 복잡도를 줄이는 것이 기본 튜닝 방안

과적합을 방지하기 위해 num_leaves는 2^(max_depth)보다 작아야 한다. 예를 들어 max_depth가 7이기 때문에, 2^(max_depth)=128이 되는데, 이 때 num_leaves를 이보다 작은 70~80 정도로 설정하는 것이 낫다.

  1. learning_rate는 DOWN, n_estimators는 UP (물론 너무 키우면 과적합)

learning_rate는 후반부에 건드리는 것이 좋은데, 초반부터 너무 작은 학습률을 지정하면 효율이 크게 떨어질 수 있기 때문이다.

  1. reg_lambda, reg_alpha와 같은 regularization적용

  2. 학습데이터에 사용할 피처개수나 데이터 샘플링 레코드 개수 줄이기 위해 colsample_bytree, subsample 적용

4. 파이썬 래퍼 LightGBM vs 사이킷런 래퍼 XGBoost vs 사이킷런 래퍼 LightGBM하이퍼 파라미터 비교

개요

  1. XGBoost가 사이킷런 규칙에 따라 자신의 하이퍼 파라미터 변경함
  2. LightGBM은 XGBoost와 기능이 많이 유사해서 사이킷런 래퍼의 파라미터를 XGBoost에 맞춰서 변경함

5. LightGBM적용 - 위스콘신 유방암 예측

앞서 XGBoost에서 사용한 유방암 데이터 셋을 이용해서 LightGBM으로 예측해 볼 것이다. LightGBM의 파이썬 패키지인 lightgbm에서 LGBMClassifier를 임포트 하여 사용한다.

조기중단을 원한다면 LGBMClassifier의 fit( )에 관련 파라미터를 설정해주면 된다.

조기중단으로 147번 반복까지만 수행 후 학습 종료한다. 이제 get_clf_eval( ) 함수를 이용하여 예측 성능을 평가한다.

LightGBM 파이썬 패키지와 사이킷런 래퍼 클래스 모두 xgboost와 같이 피처 중요도를 시각화 할 수 있다. 이름도 동일하게 plot_importance( )이다.

피처명 확인을 위해 Colum_뒤에 피처 순서대로 숫자를 붙여서 보여준다.

08. 스태킹 앙상블

  • 스태킹(Stacking): 개별적인 여러 알고리즘을 서로 결합해 예측 결과를 도출 ⇒ 배깅(Bagging) 및 부스팅(Boosting)과 공통점 지님

    ⇒ 하지만 큰 차이점은 개별 알고리즘으로 예측한 데이터를 기반으로 다시 예측을 수행한다는 것!

    ⇒ 즉, 개별 알고리즘의 예측 결과 데이터 세트를 최종적인 메타 데이터 세트로 만들어 별도의 ML 알고리즘으로 최종 학습을 수행하고, 다시 테스트 데이터를 기반으로 다시 최종 예측

    • 메타 모델: 개별 모델의 예측된 데이터 세트를 다시 기반으로 학습하고 예측하는 방식
  • 스태킹 모델은 두 종류의 모델이 필요

    1. 개별적인 기반 모델
    2. 이 개별 기반 모델의 예측 데이터를 학습 데이터로 만들어서 학습하는 최종 메타 모델
  • 스태킹 모델의 핵심은 여러 개별 모델의 예측 데이터를 각각 스태킹 형태로 결합해 최종 메타 모델의 학습용 피처 데이터 세트와 테스트용 피처 데이터 세트를 만드는 것

  • 주로 캐글과 같은 대회에서 높은 순위를 차지하기 위해 조금이라도 성능 수치를 높여야 할 경우 자주 사용됨!

  • 2~3개의 개별 모델만을 결합해서 쉽게 예측 성능을 향상시킬 수 없음

  • 스태킹을 적용한다고 해서 반드시 성능 향상 된다는 보장 없음

여러 개의 모델에 대한 예측값을 합한 후, 즉 스태킹 형태로 쌓은 뒤 이에 대한 예측을 다시 수행하는 것

  • 스텝별로 어떻게 데이터가 만들어지고 실행되는지 알아보자

  • M개의 로우, N개의 칼럼을 가진 데이터 세트에 스태킹 앙상블 적용한다고 가정
  • 학습에 사용할 ML 알고리즘 모델은 모두 3개

[스태킹 앙상블 순서]

  1. 모델별로 각각 학습 시킨 뒤 예측을 수행하면 각각 M개의 로우를 가진 1개의 레이블 값을 도출할 것임
  2. 모델별로 도출된 예측 레이블 값을 다시 합해서(스태킹) 새로운 데이터 세트를 만듦
  3. 스태킹 된 데이터 세트에 대해 최종 모델을 적용해 최종 예측

1. 기본 스태킹 모델

[코드 구현]

  • 스태킹에 사용될 머신러닝 알고리즘 클래스 생성
    • 개별 모델: KNN, 랜덤 포레스트, 결정 트리, 에이다부스트, 로지스틱 회귀(이들 모델의 예측 결과를 합한 데이터 세트로 학습/예측하는 최종 모델)

개별 모델을 학습하자

개별 모델의 예측 데이터 세트를 반환하고, 각 모델의 예측 정확도를 살펴보자

  • 개별 알고리즘으로부터 학습된 예측값을 칼럼 레벨로 옆으로 붙여서 피처 값으로 만들어, 최종 메타 모델인 로지스틱 회귀에서 학습데이터로 다시 사용
  • 반환된 예측 데이터 세트는 1차원 형태의 ndarray이므로 먼저 반환된 예측 결과를 행 형태로 붙인 뒤, 넘파이의 transpose()를 이용해 행과 열 위치를 바꾼 ndarray로 변환

  • 예측 데이터로 생성된 데이터 세트를 기반으로 최종 메타 모델인 로지스틱 회귀를 학습하고 예측 정확도를 측정
  • 개별 모델의 예측 데이터를 스태킹으로 재구성해 최종 메타 모델에서 학습하고 예측한 결과, 정확도가 97.37%로 개별 모델 정확도보다 향상
  • 이번엔 과적합을 개선하기 위한 CV 세트 기반의 스태킹 모델을 살펴보자

2. CV 세트 기반의 스태킹

과적합을 개선하기 위해 최종 메타 모델을 위한 데이터 세트를 만들 때 교차 검증 기반으로 예측된 결과 데이터 세트를 이용

  • 앞 예제에서 최종 학습할 때 레이블 데이터 세트로 학습 데이터가 아닌 테스트용 레이블 데이터 세트를 기반으로 학습했기에 과적합 문제 발생할 수 있음

⇒ 개선을 위해 개별 모델들이 각각 교차 검증으로 메타 모델을 위한 학습용 스태킹 데이터 생성과 테스트용 스태킹 데이터를 생성한 뒤 이를 기반으로 메타 모델이 학습과 예측 수행

  • 2단계의 스탭으로 구분

    • 스텝 1: 각 모델별로 원본 학습/테스트 데이터(X_train, X_test)를 예측한 결과 값을 기반으로 메타 모델을 위한 학습용/테스트용 데이터(meta_train/meta_test)를 생성

    • 스텝 2: 스텝1에서 개별 모델들이 생성한 학습용 데이터(meta_train)를 모두 스태킹 형태로 합쳐서 메타 모델이 학습할 최종 학습용 데이터 세트(final_train)를 생성 (최종 테스트용 데이터 세트도 마찬가지(meta_test를 모두 스태킹 → final_test))

      메타 모델은 최종 학습용 데이터 세트(final_train)와 원본 학습 데이터의 레이블 데이터(y_train)를 기반으로 학습한 뒤, 최종 테스트용 데이터 세트(final_test)를 예측하고, 원본 테스트 데이터의 레이블 데이터(y_test)를 기반으로 평가

각 스텝별로 수행하는 로직을 살펴보자
1. 스텝 1

⇒ 3개의 폴드만큼 반복을 수행하면서 스태킹 데이터를 생성하는 첫 번째 반복을 설명한 것

핵심은 개별 모델에서 메타 모델인 2차 모델에서 사용될 학습 데이터와 테스트용 데이터를 교차 검증을 통해서 생성하는 것

  • 스텝 1은 개별 모델 레벨(#1)에서 수행하는 것이며, 이러한 로직을 여러 개의 개별 모델(#1 ~ #4)에서 동일하게 수행
  • 먼저 학습용 데이터를 N개의 폴드(Fold)로 나눔(여기선 N=3)
  • 3개의 폴드세트이므로 3번의 유사한 반복 작업을 수행, 마지막 3번째 반복에서 개별 모델의 예측 값으로 학습 데이터와 테스트 데이터를 생성

주요 프로세서

⇒ 스태킹 데이터를 생성하는 두 번째 반복을 설명한 것

⇒ 스태킹 데이터를 생성하는 세 번째 반복을 설명한 것

  • 세 번째 반복을 완료하면 첫 번재, 두 번째, 세 번째 반복을 수행하면서 만들어진 폴드별 예측 데이터를 합하여 메타 모델에서 사용될 학습 데이터(meta_train)를 만들게 됨
  • 첫 번재, 두 번째, 세 번째 반복을 수행하면서 학습 폴드 데이터로 학습된 개별 모델들이 원본 테스트 세트로 예측한 결괏값을 최종 평균하여 메타 모델에서 사용될 테스트 데이터(meta_test)를 만들게 됨.
  1. 스텝 2

  • 각 모델들이 스텝 1로 생성한 학습/테스트 데이터(meta_train, meta_test)를 모두 합쳐서 최종적으로 메타 모델이 사용할 학습/테스트 데이터(final_train, final_test)를 생성하기만 하면 됨
  • 메타 모델이 사용할 최종 학습 데이터(final_train)와 원본 학습 데이터의 레이블 데이터(y_train)를 합쳐서 메타 모델을 학습
  • 최종 테스트 데이터(final_test)로 예측을 수행한 뒤, 최종 예측 결과를 원본 테스트 데이터의 레이블 데이터(y_test)와 비교해 평가

[코드 구현]

  • get_stacking_base_datasets() 함수 생성: 개별 모델의 Classifier 객체, 원본인 학습용 피처 데이터, 원본인 학습용 레이블 데이터, 원본인 테스트 피처 데이터 그리고 K 폴드를 몇 개로 할지를 파라미터로 입력
  • 함수 내에서는 폴드의 개수만큼 반복 수행 → 폴드된 학습용 데이터로 학습한 뒤 예측 결과값을 기반으로 메타 모델을 위한 학습/테스트용 데이터 새롭게 생성

  • 앞의 기본 스태킹 모델에서 생성한 개별 모델별로 get_stacking_base_datasets() 함수를 호출해 각각 메타 모델이 추후에 사용할 학습/테스트용 데이터 세트 반환

  • 넘파이의 concatenate()를 이용해 앞 함수로부터 반환된 각 모델별 학습/테스트 데이터를 합침

    • concatenate()는 여러 개의 넘파이 배열을 칼럼 또는 로우 레벨로 합쳐주는 기능 제공
  • 스태킹 학습 피처 데이터는 원본 학습 피처 데이터와 로우 크기는 같으며, 4개의 개별 모델 예측값을 합친 것이므로 칼럼 크기는 4

  • 최종 메타 모델인 로지스틱 회귀를 스태킹된 학습용 피처 데이터 세트와 원본 학습 레이블 데이터로 학습한 후에 스태킹된 테스트 데이터 세트로 예측
  • 예측 결과를 원본 테스트 레이블 데이터와 비교해 정확도 측정

⇒ 최종 메타 모델의 예측 정확도는 약 97.37%로 추정. 지금까지의 예제에서는 개별 모델의 알고리즘에서 파라미터 튜닝을 최적으로 하지 않았지만, 스태킹을 이루는 모델은 최적으로 파라미터를 튜닝한 상태에서 스태킹 모델을 만드는 것이 일반적임

(스태킹은 분류뿐만 아니라 회귀에도 적용 가능)

profile
Cloud, Machine Learning, DeepLearning Study⏳

2개의 댓글

comment-user-thumbnail
2020년 10월 25일

감사합니다

답글 달기
comment-user-thumbnail
2022년 3월 28일

IO Games : 일반적으로 실행 시 스레드의 개수나 냐ㅣ둣 모드 등의 선택을위한 파라미터로서 디폴트 파라미터 값을 바꾸는 경우는 거의 없다.

답글 달기