본문 바로가기

STUDY

파이썬 스터디 4주차(머신러닝)(2)

https://book.naver.com/bookdb/book_detail.nhn?bid=16238302

 

파이썬 머신러닝 완벽 가이드

자세한 이론 설명과 파이썬 실습을 통해 머신러닝을 완벽하게 배울 수 있습니다!《파이썬 머신러닝 완벽 가이드》는 이론 위주의 머신러닝 책에서 탈피해 다양한 실전 예제를 직접 구현해 보면

book.naver.com

 

 

4. 분류

 

05. GBM(Gradient Boosting Machine)

부스팅 : 여러 개의 약한 학습기(weak learner)로 데이터에 가중치를 부여해 오류를 개선하며 학습하는 방식. AdaBoost(Adaptive boosting)와 GradientBoost가 있음.

- 에이다부스트 : 오류 데이터에 가중치를 부여한 결정기준을 모두 결합해 예측 수행

(왼쪽 그림은 에이다 부스트에 대한 설명)

- GBM(Gradient Boosting Machine) : 에이다부스트와 유사하나 가중치 업데이트에 경사 하강법(Gradient Descent)을 이용. 분류와 회귀 둘 다 가능.

*경사하강법은 오류(=실제값-예측값)식을 최소화하기 위해 반복적으로 가중치 값을 업데이트하는 기법.

- 일반적으로 GBM이 랜덤포레스트보다 성능이 뛰어나나 그만큼의 수행시간과 (하이퍼 파라미터)튜닝 노력을 요구함.

 

  • GBM 하이퍼 파라미터 및 튜닝

- loss(경사하강법에서 활용할 비용 함수), learning_rate(GBM의 학습률. 약한 학습기가 오류 보정에 적용할 계수. n_estimators와 상호 보완해 사용), n_estimators(약한 학습기 개수), subsample(학습에 사용할 데이터 샘플링 비율)

- GBM은 과적합에도 뛰어난 예측 성능을 보이나 수행 시간이 오래 걸림.

- 이후 GBM기반의 ML패키지인 XGBoost, LightGBM이 생겨남!

(실행 결과랑 코드를 첨부하고 싶었지만 너무 오래 걸려 포기했다..)

 

 

06. XGBoost(eXtra Gradient Boost)

XGBoost : 트리 기반 앙상블 학습에서 가장 각광받는 알고리즘. GBM기반.

- 장점 : 뛰어난 예측 성능, 느린 수행시간 문제 해결, 과적합 규제 부재 문제 해결, 교차 검증 기능 자체 내장, 병렬 cpu환경에서 병렬 학습 가능, 결손값 자체 처리, 긍정 이득 없는 분할 수 줄이기(Tree pruning)

- 핵심 라이브러리는 C/C++로 작성됨. XGBoost전용 파이썬 패키지와 사이킷런 래퍼 XGBoost가 둘 다 존재.

- 파이썬 래퍼 XGBoost와 사이킷런 래퍼 XGBoost의 일부 하이퍼 파라미터는 약간 다름(정리x)

- XGBoost는 자체적으로 시각화(plotting) 기능과 성능 향상 기능을 가짐. 대표 기능은 Early Stopping(조기 중단)으로, 반복 횟수에 도달하지 않아도 오류가 더이상 개선되지 않으면 반복 중지. 

- 파이썬 래퍼 XGBoost는 학습용/테스트용 데이터 세트를 위해 DMatrix라는 별도의 객체 생성. 이는 XGBoost만의 전용 데이터 세트.

#각종 임포트 생략

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

X_train, X_test, y_train, y_test = train_test_split(X_features, y_label, test_size=0.2, random_state=156)

dtrain = xgb.DMatrix(data=X_train, label=y_train)
dtest = xgb.DMatrix(data=X_test, label=y_test)
#넘파이 형태의 데이터세트를 DMaatrix로 변환
#data 파라미터는 피처 데이터 세트, label 파라미터는 (분류)레이블/(회귀)종속값 데이터 세트
params = {
    'max_depth': 3,
    'eta': 0.1,
    'objective': 'binary:logistic',
    'eval_metric': 'logloss',
    'early_stoppings': 100
    }
num_rounds = 400

wlist = [(dtrain, 'train'), (dtest, 'eval')] #test데이터세트를 eval로 표현
xgb_model = xgb.train(params=params, dtrain=dtrain, num_boost_round=num_rounds, early_stopping_rounds=100, evals=wlist)
#파이썬 래퍼 XGBoost는 하이퍼 파라미터를 xgboost train()함수에 파라미터로 전달함
#train()함수에 early_stopping_rounds파라미터 설정. 이를 위해 eval_set과 eval_metric도 설정

 

- eval_set은 평가용 데이터세트(성능평가 수행 대상), eval_metric은 평가용 데이터세트에 적용할 (성능 평가) 방법을 말함

- 파이썬 래퍼 XGBoost는 train()을 호출해 학습된 모델 객체를 반환함. 이 모델 객체는 predict()메서드 이용. 사이킷런의 predict()는 예측 결과 클래스 값을 반환하나 xgboost의 predict()는 예측 결과 확률 값을 반환함.

 

pred_probs = xgb_model.predict(dtest)
print("predict() 수행 결과값 10개만 표시(예측 확률값으로 표시)")
print(np.round(pred_probs[:10], 3))

#예측 확률이 0.5보다 크면 1, 그렇지 않으면 0으로 결정해 리스트에 저장
preds = [1 if x>0.5 else 0 for x in pred_probs]
print("예측값 10개 표시:", preds[:10])

 

- 리스트 값이 0.5를 넘는 것만 1, 그렇지 않은 경우 0으로 바뀌어 있음을 확인

- xgboost의 plot_importance()는 피처 중요도를 막대그래프 형식으로 나타냄. 파라미터로 학습 완료된 모델 객체, matplotlib의 ax객체 입력 (fig, ax = plt.subplots(figsize=(10, 12)) \n plot_importance(xgb_model, ax=ax))

 

- 피처 순서별로 f뒤에 숫자를 붙여 X축에 나열

- xgboost의 to_graphviz()로 규칙 트리 구조를 만들 수도 있음.

- 파이썬 래퍼 XGBoost는 사이킷런 GridSearchCV같은 데이터 세트 교차 검증 수행 후 최적 파라미터를 구하는 것을 cv()로 제공함. cv() API 파라미터는 다음과 같음

- params(dict), dtrain(DMatrix), num_boost_round(int), nfold(int), stratified(bool), metrics(string or list of strings), early_stopping_round(int). 설명은 생략

- XGBoost를 위한 사이킷런 래퍼는 사이킷런과 호환돼 편리함

 

 

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

- 기존 사이킷런의 하이퍼 파라미터와 호환성을 유지하기 위해 xgboost모듈의 네이티브 하이퍼 파라미터 몇 개를 변경    (eta -> learning_rate,    sub_sample -> subsample,    lambda -> reg_lambda,    alpha -> reg_alpha)

- 조기중단 관련 파라미터: early_stopping_rounds(반복횟수 정의), eval_metric(평가지표), eval_set(성능평가 수행 데이터세트). 여기서 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]

 

- n_estimators가 400, early_stopping_rounds가 100이나 311에서 멈춤. 211번 logloss가 0.085593이었으나 100번 더 반복한 311이 0.085948로 별다른 차이가 없어 반복이 멈춘 것

- 조기 중단값(early_stopping_rounds)을 급격히 줄이면 예측 성능이 저하될 수 있음

 

 

07. LightGBM

LightGBM : XGBoost와 함께 부스팅 계열 알고리즘에서 가장 각광받음. 

- XGBoost보다 학습에 걸리는 시간과 메모리 사용량이 적음. 그러나 예측 성능 면에서는 별 차이가 없으며, 적은 데이터 세트에 적용했을 때 과적합이 발생하기 쉬움

- 일반 GBM계열의 트리 분할 방법이 아니라 리픝 중심 트리 분할(Leaf Wise)방식 사용. 이 방법은 최대 손실값(max delta loss)을 가지는 리프 노드를 분할하며 비대칭적인 규칙 트리를 생성함. 결과적으로 균형 트리 분할방식 보다 예측 오류 손실을 최소화 할 수 있음.

- 대용량 데이터에 대한 예측 성능이 뛰어나며 병렬 컴퓨팅 기능, GPU 제공

- 파이썬 래퍼용 LightGBM, 사이킷런 래퍼 LightGBM이 있음.

 

  • LightGBM 하이퍼 파라미터

- 리프노드가 계속 분할되며 트리가 깊어지므로 이에 맞는 하이퍼 파라미터 설정 필요

- num_iterations, learning_rate, max_depth, min_data_in_leaf, num_leaves, boosting(gbdt/rf), bagging_fraction, labmda_l2, labmda_l1, objective, num_leavesmin_data_in_leafmax_depth가 있음. 설명은 생략

- XGBoost처럼 LightGBM도 사이킷런 래퍼 LightGBM의 하이퍼 파라미터를 사이킷런 XGBoost에 맞춰 변경. 이에 사이킷런 래퍼 LightGBM클래스와 사이킷런 래퍼 XGBoost클래스는 대부분의 하이퍼 파라미터가 같음(추가설명 생략)

- LightGBMClassifier의 fit()에 조기중단(early stopping)관련 파라미터를 설정하면 조기중단 가능

from lightgbm import LGBMClassifier

import pandas as pd; import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

dataset = load_breast_cancer()
ftr = dataset.data
target = dataset.target

X_train, X_test, y_train, y_test = train_test_split(ftr, target, test_size=0.2, random_state=156)

lgbm_wrapper = LGBMClassifier(n_estimators=400)
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]

 

- 47번째에서 147번까지 큰 성능차이가 보이지 않아 조기중단됨

- xgboost와 마찬가지로 lightgbm도 피처 중요도를 시각화하는 내장 api 제공

 


너무 어려워요.. 필사의 느낌을 지울 수가 없음... 이해가 안되는걸요 뭐..ㅋㅎㅋㅋㅋ 나열과 나열과 나열밖에 없는데 깊게 이해하고 자시고 할 게 없음.. 후... 글 하나 더 써야 분류를 겨우 끝낼 것 같네요. 힘들당..