앙상블: 일련의 예측기로부터 예측을 수집하면 가장 좋은 모델 하나보다 더 좋은 예측을 얻을 수 있음
앙상블 방법
- 앙상블 학습 알고리즘
- 훈련 세트로부터 무작위로 각기 다른 서브넷을 만들어 일련의 결정 트리 분류기 훈련 가능
- 예측기가 가능한 서로 독립적일 때 최고의 성능을 발휘
랜덤 포레스트
- 앙상블 방법으로 만든 트리에 예측을 위해 모든 개별 트리의 예측을 구한 뒤 가장 많은 선택을 받은 클래스를 예측으로 삼음
- 간단한 방법임에도 오늘날 가장 강력한 머신러닝 알고리즘 중 하나
- 프로젝트의 마지막에 다다르면 흔히 앙상블 방법을 사용하여 이미 만든 여러 괜찮은 예측기를 연결하여 더 좋은 예측기를 만듦
1. 투표 기반 분류기
직접 투표 분류기
- 분류기 여러 개를 훈련시킨 뒤 더 좋은 분류기를 만들기 위해 각 분류기의 예측을 모아 가장 많이 선택된 클래스를 예측
- 다수결 투표로 정해지는 분류기
- 이 분류기가 앙상블에 포함된 개별 분류기 중 가장 뛰어난 것보다도 정확도가 높을 경우가 많음
# 여러 분류기를 조하하여 사이킷런의 투표 기반 분류기 만들기
from sklearn.ensemble import VotingClassifier
# ~~~
voting_clf = VotingClassifier (
estimators=[('lr', log_clf), ('rf', rnd_clf), ('svc', svm_clf)],
voting='hard')
voting_clf.fit(X_train, y_train)
간접 투표 분류기
- 모든 분류기가 클래스의 확률을 예측할 수 있으면 개별 분류기의 예측을 평균 내어 확률이 가장 높은 클래스 예측
- 확률이 높은 투표에 비중을 더 두기 때문에 직접 투표 방식보다 성능이 높음
- voting="hard"를 voting="soft"로 바꾸고 모든 분류기가 클래스의 확률을 추정할 수 있으면 됨
2. 배깅과 페이스팅
다양한 분류기를 만드는 방법
- 각기 다른 훈련 알고리즘을 사용하기
- 같은 알고리즘을 사용하고 훈련 세트의 서브셋을 무작위로 구성하여 분류기를 각기 다르게 학습
배깅: 훈련 세트에서 중복을 허용하여 샘플링하는 방식
페이스팅: 중복을 허용하지 않고 샘플링하는 방식
=> 배깅과 페이스팅은 훈련 세트에서 무작위로 샘플링하여 여러 개의 예측기를 훈련
- 분류의 경우 통계적 최빈값, 회귀의 경우 평균을 계산
- 일반적으로 앙상블 결과는 원본 데이터셋으로 하나의 예측기를 훈련시킬 때와 비교해 편향은 비슷하지만 분산은 줄어듦
1) 사이킷런의 배깅과 페이스팅
- 결정 트리 분류기 500개의 앙상블 훈련시키는 코드
- 각 분류기는 훈련 세트에서 중복을 허용하여 무작위로 선택된 100개의 샘플로 훈련
- 페이스팅을 사용하려면 bootstrap=False로 지정
- n_jobs: 사이킷런이 훈련과 예측에 사용할 CPU 코어 수 (-1로 지정하면 가용한 모든 코어 사용)
from sklearn.ensemble import BaggingClassifier
from sklearn.tree import DecisionTreeClassifier
bag_clf = BaggingClassifier (
DecisionTreeClassifier(), n_estimators=500,
max_samples=100, bootstrap=True, n_jobs=-1)
bag_clf.fit(X_train, y_train)
y_pred = bag_clf.predict(X_train)
- 부트스트래핑은 각 예측기가 학습하는 서브셋에 다양성을 증가시키므로 배깅이 페이스팅보다 편향이 조금 더 높음
- 다양성을 추가한다는 것은 예측기들의 상관관계를 줄이므로 앙상블의 분산을 감소시킴
- 전반적으로 배깅이 더 나은 모델을 만드므로 일반적으로 더 선호
2) oob 평가
- 배깅을 사용하면 어떤 샘플은 여러 번 샘플링되고 어떤 것은 전혀 선택되지 않을 수 있음
- BaggingClassifier는 기본값으로 중복을 허용하여 훈련 세트의 크기만큼인 m개 샘플을 선택
- 평균적으로 훈련 샘플 63%만 샘플링된다는 의미로 37%는 oob 샘플이라고 함
- 예측기마다 남겨진 37%는 모두 다름
- 예측기가 훈련하는 동안 oob 샘플은 사용하지 않으므로 별도의 검증 세트를 사용하지 않고 oob 샘플을 사용해 평가 가능
- 사이킷런에서 BaggingClassifier 만들 때 oob_score=True로 지정하면 훈련이 끝난 후 자동으로 oob 평가 수행
3. 랜덤 패치와 랜덤 서브스페이스
- BaggingClassifier는 특성 샘플링도 지원
- 샘플링은 max_features, bootstrap_features 두 매개변수로 조절
- 각 예측기는 무작위로 선택한 입력 특성의 일부분으로 훈련
- 이 기법은 매우 고차원의 데이터셋을 다룰 때 유용
- 특성 샘플링은 더 다양한 예측기를 만들며 편향을 늘리는 대신 분산을 낮춤
- 랜덤 패치 방식: 훈련 특성과 샘플을 모두 샘플링
- bootstrap_features=False, max_samples=1.0
- 랜덤 서브스페이스 방식: 훈련 샘플을 모두 사용하고 특성은 샘플링하는 것
- bootstrap_features=True, max_samples=1.0보다 작게 설정
4. 랜덤 포레스트
- 일반적으로 배깅 방법(또는 페이스팅)을 적용한 결정 트리의 앙상블
- max_samples를 훈련 세트의 크기로 지정
# 최대 16개의 리프 노드를 갖는 500개 트리로 이뤄진 랜덤 포레스트 분류기를 여러 CPU 코어에서 훈련
from sklearn.ensemble import RandomForestClassifier
rnd_clf = RandomForestClassifier(n_estimators=500, max_leaf_node=16, n_jobs=-1)
rnd_clf.fit(X_train, y_train)
y_pred_rf = rnd_clf.predict(X_test)
- 랜덤 포레스트 알고리즘은 무작위로 선택한 특성 후보 중에서 최적의 특성을 찾는 식으로 무작위성을 더 주입
- 트리를 더욱 다양하기 만듦
- 편향을 손해 보는 대신 분산을 낮추어 전체적으로 더 훌륭한 모델을 만들어냄
1) 엑스트라 트리
익스트림 랜덤 트리(엑스트라 트리)
- 트리를 더욱 무작위로 만들기 위해 최적의 임계값을 찾는 대신 후보 특성을 사용해 무작위로 분할한 다음 그중에서 최상의 분할 선택
- 극단적으로 무작위 한 트리의 랜덤 포레스트
- 모든 노드에서 특성마다 가장 최적의 임계값을 찾는 것이 트리 알고리즘에서 가장 시간이 많이 소요되므로 일반적인 랜덤 포레스트보다 엑스트라 트리가 더 빠름
- 사이킷런의 ExtraTreesClassifier 사용
2) 특성 중요도
- 랜덤 포레스트의 또 다른 장점은 특성의 상대적 중요도 측정하기 쉽다는 것
- 사이킷런은 어떤 특성을 사용한 노드가 평균적으로 불순도를 얼마나 감소시켰는지 확인하여 특성의 중요도 측정
- feature_importances_ 변수에 저장됨
5. 부스팅
부스팅
- 약한 학습기를 여러 개 연결하여 강한 학습기를 만드는 앙상블 방법
- 이 방법의 아이디어는 앞의 모델을 보완해나가면서 일련의 예측기를 학습
- 가장 인기 있는 부스팅 방법은 에이다부스트와 그레이디언트 부스팅
1) 에이다부스트
에이다부스트에서 사용하는 방식
- 이전 예측기를 보완하는 새로운 예측기를 만들기 위해서는 이전 모델이 과소적합했던 훈련 샘플의 가중치를 더 높임 -> 새로운 예측기는 학습하기 어려운 샘플에 점점 더 맞춰지게 됨
- 경사 하강법은 비용 함수를 최소화하기 위해 한 예측기의 모델 파라미터를 조정해가는 한편 에이다부스트는 점차 더 좋아지도록 앙상블에 예측기를 추가
- 연속된 학습 기법은 이전 예측기의 훈련 및 평가 이후에 학습 가능하므로 병렬화 불가능
- 배깅이나 페이스팅만큼 확장성이 높지 않음
from sklearn.ensemble import AdaBoostClassifier
ada_clf = AmdaBoostClassifier(
DecisionTreeClassifier(max_depth=1), n_estimators=200,
algorithm="SAME.R", learning_rate=0.5)
ada_clf.fit(X_train, y_train)
- 사이킷런의 AdaBoostClassifier를 사용하여 200개의 얕은 결정 트리를 기반으로 하는 에이다부스트 분류기
- 사이킷런은 SAMME라는 에이다부스트의 다중 클래스 버전 사용
2) 그레이디언트 부스팅
그레이디언트 부스팅
- 에이다부스트처럼 앙상블에 이전까지의 오차를 보정하도록 예측기를 순차적으로 추가
- 에이다부스트처럼 반복마다 샘플의 가중치를 수정하는 대신 이전 예측기가 만든 잔여 오차에 새로운 예측기를 학습시킴
그레이디언트 트리 부스팅 (그레이디언트 부스티드 회귀 트리)
1. DecisionTreeRegressor를 훈련 세트에 학습시키기
from sklearn.tree import DecisionTreeRegressor
tree_reg1 = DecisionTreeRegressor(max_depth=2)
tree_reg1.fit(X, y)
2. 첫 번째 예측기에서 생긴 오차에 두 번째 DecisionTreeRegressor 훈련시키기
y2 = y- tree-reg1.predict(X)
tree_reg2 = DecisionTreeRegressor(max_depth=2)
tree_reg2.fit(X, y2)
3. 두 번째 예측기가 만든 잔여 오차에 세 번째 회귀 모델 훈련시키기
y3 = y2- tree-reg1.predict(X)
tree_reg3 = DecisionTreeRegressor(max_depth=2)
tree_reg3.fit(X, y3)
4. 모든 트리의 예측을 더하기
y_pred = sum(tree.predict(X_new) for tree in (tree_reg1, tree_reg2, tree_reg3))
- 사이킷런의 GradientBoostingRegressor 이용하기
- learning rate가 각 트리의 기여도를 조절
- 최적의 트리 수를 찾기 위해 조기 종료 기법 사용 가능
- staged_predict() 메서드 사용
from sklearn.ensemble import GradientBoostingRegressor
gbrt = GradientBoostingRegressor(max_depth=2, n_estimator=3, learning_rate=1.0)
gbrt.fit(X, y)
확률적 그레이디언트 부스팅
- subsample 매개변수를 이용해 각 트리가 훈련할 때 사용할 훈련 샘플의 비율 지정 가능
- 편향이 높아지는 대신 분산이 낮아지게 되며 훈련 속도를 상당히 높음
import xgboost
xgb_reg = xgboost.SGBRegressor()
sgb_reg.fit(X_train, y_train)
```
# 조기 종료 버전
sgb_reg.fit(X_train, y_train,
eval=set=[(X_val, y_val)], early_stopping_rounds=2)
```
y_pred = xgb_reg.predict(X_val)
6. 스태킹
- 앙상블에 속한 모든 예측기의 예측을 취합하는 간단한 함수를 사용하는 대신 취합하는 모델을 사용하자는 아이디어에서 출발
- 각기 다른 값을 예측 후 마지막 예측기 (블렌더 또는 메타학습기)가 이 예측을 입력으로 받아 최종 예측을 만듦
- 블렌더는 일반적으로 홀드 아웃 세트를 사용하여 학습
- 훈련 세트를 서브셋으로 나누고 각 레이어의 예측을 위해 서브셋은 사용됨
- 각 레이어를 예측기를 사용해 레이어 개수만큼의 예측을 만들고 예측한 값을 특성으로 사용하는 새로운 훈련 세트를 만듦
- 사이킷런이 스태킹을 직접 지원하지는 않음
'인공지능(AI) > 머신러닝' 카테고리의 다른 글
[핸즈온 머신러닝] 9장 비지도 학습 (0) | 2022.02.07 |
---|---|
[핸즈온 머신러닝] 8장 차원 축소 (0) | 2022.01.24 |
[핸즈온 머신러닝] 6장 결정 트리 (0) | 2022.01.18 |
[핸즈온 머신러닝] 5장 서포트 벡터 머신 (1) | 2022.01.18 |
[핸즈온 머신러닝] 4장 모델 훈련 (0) | 2022.01.17 |
댓글