데이터분석-머신러닝-AI/강의 정리

[혼자 공부하는 머신러닝+딥러닝] 13강. 트리의 앙상블 - 다양한 앙상블 알고리즘

bluebamus 2023. 11. 14.

https://www.youtube.com/watch?v=Moz8i-tKurk&list=PLJN246lAkhQjoU0C4v8FgtbjOIXxSs_4Q&index=14

 

 - 정형 데이터와 비정형 데이터

   - 정형 데이터는 머신러닝에 사용되는 데이터이고 비정형 데이터는 딥러닝에 사용되는 데이터로 나눈다.

 

 - 정형데이터를 다루는데 머신러닝 알고리즘을 사용한다. 그 중 가장 뛰어난 성능의 알고리즘은 트리의 앙상블이다.

 

 1. 랜덤 포레스트

   - 앙상블 학습의 대표주자로 랜덤한 결정트리의 숲이라 할 수 있다

      - 기본원리

         1) 훈련데이터를 같은 크기의 부트스트랩 샘플(중복을 허용한 추출 샘플)을 만들어 학습한다.

         2) 노드를 분할할 때 특성 개수를 루트로 계산하여 그 결과에 대한 특성만 사용하여 분할한다.

      - 위 두가지 방법을 개별 트리에 무작위성을 부여해 트리 성능이 너무 강력해지는 것을 막는다.

         - 트리가 커질수록 과대적합이 발생하는데 이러한 과대적합을 방지한다.

      - 이 결과로 개별 트리의 성능은 떨어지지만 여러개 묶어서 일반화 하면 높은 성능이 나오게 된다.

 

   - 트리의 성능을 억제하는 특징을 가지고 있다.

   - RandomForest는 classifier(분류)와 regressor(회귀)가 있다.

   - 분류일 경우 각 결정트리에서 클래스별 확률이 나온다.

      - 모든 확률을 더하고 트리 개수로 나눈다. 그러면 클래스마다의 평균 확률을 얻을 수 있다. 이 확률 중 제일 큰 값을 고른다.

   - 회귀일 경우 각 결정트리에서 예측값이 나온다.

      - 모든 예측값을 더하고 트리 개수로 나눈다. 그리고 얻은 평균 확률 중 가장 큰 값을 고른다.

 

 - 훈련 세트에 무작위성 주입 (부트슽트랩 샘플 생성)

   - 랜덤포레스트 속의 각 트리는 우리가 입력한 훈련데이터를 그대로 사용해 학습하지 않는다.

   - 훈련세트와 같은 크기의 여러개의 부트스트랩 샘플(동일한 갯수, 중복 추출 허용)을 만들어 각각 샘플마다 결정 트리 훈련을 한다.

      -  훈련세트가 매번 달라지고 중복 데이터로 인해 성능도 그렇게 좋지 않게 된다.

 

 -  특성 선택에 무작위성 주입

   - 원래 부모노드와 자식노드간 불순도 차이를 계산하여 최선의 노드 분할을 하는데 특성 집합들 중 일정 수만큼 랜던 선택을 하여 분할을 하게 한다.

      - 예를 들어 현재 특성 개수가 3개이면 루트 3을 한 값 만큼 랜덤 선택을 한다.

 

 - 훈련 세트의 무작위성 주입 + 특성 선택에 무작위성 주입의 방식으로 주어진 값만큼 결정트리를 훈련한다( 기본 100개) 

 - 각 트리의 클래스별 확률을 평균하여 가장 높은 확률의 클래스를 예측 클래스로 정한다.

   - 회귀의 경우 "확률" 대신 "예측값(임의의 수치)"를 평균하면 된다.

 

 - 랜덤 포레스트 훈련

   - 데이터 읽기 및 테스트 데이터 분리

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split

wine = pd.read_csv('https://bit.ly/wine_csv_data')

data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()

train_input, test_input, train_target, test_target = train_test_split(data, target, test_size=0.2, random_state=42)

 

 

   - 교차 검증

      - return_train_score 파라미터는 훈련세트의 점수도 반환하는지 여부를 설정한다. (과대적합 여부 파악)

      - 랜덤 포레스트도 feature_importances_ 변수를 통해 특성의 중요도 정보를 제공한다.

      - 특성을 랜덤하게 선택하다 보니 다른 특성도 강제로 테스트를 해보게 된다. 때문에 골고루 특성을 사용하게 되는 효과를 가지게 된다.

from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier

rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))
0.9973541965122431 0.8905151032797809


rf.fit(train_input, train_target)
print(rf.feature_importances_)
[0.23167441 0.50039841 0.26792718]


rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)

rf.fit(train_input, train_target)
print(rf.oob_score_)
0.8934000384837406

 

 - OOB(out of bag) 샘플 

   - 랜덤포레스트에서 부트스트랩 샘플을 만들 때, 복원추출 과정에서 선택되지 않고 남은 샘플이다.

      - 이 남은 샘플로 트리를 평가할 수 있다.(검증 세트와 같은 역할)

   - oob_score 옵션을 True로 하면 그걸로 평가한 점수가 obb_score_에 저장된다.

   - 이 방법을 사용하면 훈련세트에 더 많은 샘플을 사용할 수 있다.

 

 2. 엑스트라 트리

 - 랜덤 포레스트와 매우 비슷하다. 

 - 랜덤 포레스트에서 사용된 '특성 선택에 무작위성 주입'에 '노드 분할에 무작위성 주입'을 하는 방법이 추가된다.

 - 노드 분할에 무작위성 주입

   - 랜덤 포레스트의 '부트스트랩 샘플' 사용과는 달리 엑스트라 트리는 기본 훈련세트 전체를 그대로 사용한다.

   - 대신, 노드를 분할할 때 최선의 분할(부모 노드와 자식 노드간 불순도 차이가 가장 큰 분할)을 찾는 것이 아니라 "무작위 분할"을 수행한다. 

      - 랜덤하게 분할한 후보들 중 그나마 불순도 차이가 가장 큰 쪽으로...

      - 무작위 분할로 인해 랜덤 포레스트보다 무작위성이 더 크다. 때문에 랜덤포레스트보다 트리 개수를 더 많이 해야 좋은 성능을 낸다고 알려져 있다. 하지만 더 큰 무작위성으로 인해 계산속도는 상개적으로 다 빠르다는 장점을 가지고 있다.

 

 - 엑스트라 트리 훈련

from sklearn.ensemble import ExtraTreesClassifier

et = ExtraTreesClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(et, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))
0.9974503966084433 0.8887848893166506


et.fit(train_input, train_target)
print(et.feature_importances_)
[0.20183568 0.52242907 0.27573525]

 

 3. 그레이디언트 부스팅

 - 앙상블 알고리즘에서 가장 좋은 알고리즘 중 하나라 할 수 있다.

 - 깊이가 얕은 결정 트리를 사용하여 이전 트리의 오차를 보완하는 방식의 앙상블 학습 방법이다.

   - 기본 값은 3이다

   - 깊이가 얕기 때문에 과대적합을 방지할 수 있다.

 - 'Gradient'에서 유추할 수 있듯, 경사 하강법을 사용해 트리를 추가하는 것이다.

   - 분류 : 로지스틱 손실함수

   - 회귀 : 평균제곱오차 함수

   - 각 함수의 결과로 나오는 실수 값이 낮아지도록 트리를 추가하는 것이다.

   - 너무 빨리 학습을 하게 되면 최적점을 지나칠 수 있다. 때문에 학습속도를 제어할 수 있는 learning_rate 매개변수가 있다.

   - 얕은 깊이의 트리를 사용함으로 과대적합을 방지하지만 score 의 성능 결과가 그렇게 좋지 않은 것을 확인할 수 있다. 하지만 이전 트리의 손실을 보완하는 방향으로 트리를 추가하면서 조금씩 이동하도록 학습률을 조절해 나가게 되면 성능이 점차 높아지는 것을 확인할 수 있다. 

   - 결정트리 수를 늘려도 과대적합에 강하다는 장점이 있다.

 - 단점으로 트리를 하나씩 추가해야 하기 때문에 훈련속도가 느리다는 문제를 가지고 있다.

 - subsample 매개변수를 사용하여 훈련에 사용할 훈련세트의 비율을 정할 수 있다.

   - 기본값은 1.0으로 훈련세트 전체를 사용하게 된다. (배치 경사하강법)

   - 1보다 작은 값으로 정의하면 훈련세트의 일부만 사용한다. 이것은 확률적 경사하강법이나 미니배치 경사하강법처럼 동작하게 된다.

 

 - 그레이디언트 부스팅 학습

from sklearn.ensemble import GradientBoostingClassifier

gb = GradientBoostingClassifier(random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))
0.8881086892152563 0.8720430147331015

gb = GradientBoostingClassifier(n_estimators=500, learning_rate=0.2, random_state=42)
scores = cross_validate(gb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))
0.9464595437171814 0.8780082549788999

gb.fit(train_input, train_target)
print(gb.feature_importances_)
[0.15853457 0.68010884 0.1613566 ]

 

 4. 히스토그램 기반 그레이디언트 부스팅

 - 정형 데이터를 다루는 머신러닝 알고리즘 중 가장 인기가 높다.

 - 기본 매개변수에서도 안정적인 성능을 얻을 만큼 신뢰성 높은 모델이다.

 

 - 노드를 분할하기 전 훈련 데이터를 256 구간으로 나눈다.
   - 특성의 범위가 짧게 끊어져있어 최적의 분할을 매우 빨리 찾을 수 있다.

   - 나눠진 훈련 데이터를 히스토그램처럼 만듬으로 데이터의 특성을 빠르게 파악할 수 있다.

   - 256 구간은 실재 255 구간과 1개의 누락된 데이터를 위한 구간으로 할당된다. 때문에 누락이 있는 데이터라도 전처리를 할 필요 없이 바로 사용할 수 있다.

# 사이킷런 1.0 버전 아래에서는 다음 라인의 주석을 해제하고 실행하세요.
# from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier

hgb = HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))
0.9321723946453317 0.8801241948619236

from sklearn.inspection import permutation_importance

hgb.fit(train_input, train_target)
result = permutation_importance(hgb, train_input, train_target, n_repeats=10,
                                random_state=42, n_jobs=-1)
print(result.importances_mean)
[0.08876275 0.23438522 0.08027708] # 가운데 특성이 제일 변화가 크다

result = permutation_importance(hgb, test_input, test_target, n_repeats=10,
                                random_state=42, n_jobs=-1)
print(result.importances_mean)
[0.05969231 0.20238462 0.049     ]

hgb.score(test_input, test_target)
0.8723076923076923

 

 - 특성 중요도 확인, permutation_importance() 함수

   - 하나의 특성의 샘플 데이터를 무작위로 섞은 뒤 모델의 성능 변화를 관찰한다. 그리고 이러한 과정을 모든 특성에 적용한다. 이 성능의 변화(정확도의 손실)가 가장 클수록해당 특성이 중요하다는 결론을 내릴 수 있다.

      - n_repeats로 섞을 횟수를 지정할 수 있다. (특성마다 몇번 섞을 것인지 지정)

   - 함수를 사용하여 반환되는 결과에는 다음과 같은 정보들을 가지고 있다.

      -  importances (계산한 개별 특성중요도 모두)

      -  importances_mean(그걸 평균 낸 최종 특성중요도)

      -  importances_std(특성중요도들 간 표준편차)

   - 이 함수는 훈련세트뿐 아니라 테스트 세트에서도 특성 중요도를 계산할 수 있다.

      - 실전에 투입했을 때 어떤 특성에 중점을 둘 것인지, 민감한지를 미리 예상해 볼 수 있다.

 

 5. XGBoost

 - 다양한 부스팅 알고리즘을 지원하는 라이브러리이다.

   - 오픈소스이고 코랩에서도 동작된다.

   - 케글에서 많이 사용하면서 유명해진 라이브러리이다.

from xgboost import XGBClassifier

xgb = XGBClassifier(tree_method='hist', random_state=42)
scores = cross_validate(xgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))

 

 6. LightGBM

 - 마이크로소프트에서 만든, 그레이언트 부스팅 전용 라이브러리이다.

   - 오픈소스이고 코랩에서도 동작된다.

   - 히스토그램 기반 그레디언트 부스팅을 지원하면서 인기가 높아졌다.

from lightgbm import LGBMClassifier

lgb = LGBMClassifier(random_state=42)
scores = cross_validate(lgb, train_input, train_target, return_train_score=True, n_jobs=-1)

print(np.mean(scores['train_score']), np.mean(scores['test_score']))

 

 

 

- reference : 

https://velog.io/@simon919/%ED%98%BC%EA%B3%B5%EB%A8%B8%EC%8B%A0-5-3.-%ED%8A%B8%EB%A6%AC%EC%9D%98-%EC%95%99%EC%83%81%EB%B8%94-wdvkdf13

 

[혼공머신] 5-3. 트리의 앙상블

이사님🗣️ "베스트 머신러닝 알고리즘을 찾아보게나!"

velog.io

https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-15-Gradient-Boost

 

머신러닝 - 15. 그레디언트 부스트(Gradient Boost)

앙상블 방법론에는 부스팅과 배깅이 있습니다. (머신러닝 - 11. 앙상블 학습 (Ensemble Learning): 배깅(Bagging)과 부스팅(Boosting)) 배깅의 대표적인 모델은 랜덤 포레스트가 있고, 부스팅의 대표적인 모

bkshin.tistory.com

https://tensorflow.blog/hg-mldl/

 

혼자 공부하는 머신러닝+딥러닝

Yes24, 교보문고 평점 평균 10점 만점! 감사합니다! ★★★★★ 박해선님 도서는 항상 기대함. 그러나 항상 기대이상. 이번엔 심지어 재미있음. (a******t 님)★★★★★ 박해선님이 제대로 된 초보자

tensorflow.blog

https://velog.io/@sset2323/04-05.-GBMGradient-Boosting-Machine

 

04-05. GBM(Gradient Boosting Machine)

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.

velog.io

https://velog.io/@sset2323/04-02.-%EA%B2%B0%EC%A0%95-%ED%8A%B8%EB%A6%AC

 

04-02. 결정 트리

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.

velog.io

https://velog.io/@sset2323/04-03.-%EC%95%99%EC%83%81%EB%B8%94-%ED%95%99%EC%8A%B5

 

04-03. 앙상블 학습

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.

velog.io

https://velog.io/@sset2323/04-04.-%EB%9E%9C%EB%8D%A4-%ED%8F%AC%EB%A0%88%EC%8A%A4%ED%8A%B8

 

04-04. 랜덤 포레스트

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.

velog.io

https://velog.io/@sset2323/04-05.-GBMGradient-Boosting-Machine

 

04-05. GBM(Gradient Boosting Machine)

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.

velog.io

https://velog.io/@sset2323/04-06.-XGBoosteXtra-Gradient-Boost

 

04-06. XGBoost(eXtra Gradient Boost)

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.

velog.io

https://velog.io/@sset2323/04-07.-LightGBM

 

04-07. LightGBM

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.

velog.io

https://velog.io/@sset2323/04-10.-%EC%8A%A4%ED%83%9C%ED%82%B9-%EC%95%99%EC%83%81%EB%B8%94

 

04-10. 스태킹 앙상블

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.

velog.io

 

댓글