[혼자 공부하는 머신러닝+딥러닝] 13강. 트리의 앙상블 - 다양한 앙상블 알고리즘
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://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-15-Gradient-Boost
https://tensorflow.blog/hg-mldl/
https://velog.io/@sset2323/04-05.-GBMGradient-Boosting-Machine
https://velog.io/@sset2323/04-02.-%EA%B2%B0%EC%A0%95-%ED%8A%B8%EB%A6%AC
https://velog.io/@sset2323/04-03.-%EC%95%99%EC%83%81%EB%B8%94-%ED%95%99%EC%8A%B5
https://velog.io/@sset2323/04-04.-%EB%9E%9C%EB%8D%A4-%ED%8F%AC%EB%A0%88%EC%8A%A4%ED%8A%B8
https://velog.io/@sset2323/04-05.-GBMGradient-Boosting-Machine
https://velog.io/@sset2323/04-06.-XGBoosteXtra-Gradient-Boost
https://velog.io/@sset2323/04-07.-LightGBM
https://velog.io/@sset2323/04-10.-%EC%8A%A4%ED%83%9C%ED%82%B9-%EC%95%99%EC%83%81%EB%B8%94
'데이터분석-머신러닝-AI > 강의 정리' 카테고리의 다른 글
[혼자 공부하는 머신러닝+딥러닝] 15강. k-평균 알고리즘 작동 방식을 이해하고 비지도 학습 모델 만들기 - 이미지 평균의 자동화 (1) | 2023.11.16 |
---|---|
[혼자 공부하는 머신러닝+딥러닝] 14강. 흑백 이미지 분류 방법과 비지도 학습, 군집 알고리즘 이해하기 - 지도 학습 샘플로 군집 알고리즘 학습 (1) | 2023.11.15 |
[혼자 공부하는 머신러닝+딥러닝] 12강. 교차 검증과 그리드 서치 - (1) | 2023.11.13 |
[혼자 공부하는 머신러닝+딥러닝] 11강. 로지스틱 회귀로 와인 분류하기 & 결정 트리 - 와인 분류하기 (1) | 2023.11.12 |
[혼자 공부하는 머신러닝+딥러닝] 10강. 확률적 경사 하강법 알아보기 - 점진적 학습, 온라인 학습 (0) | 2023.11.11 |
댓글