[Day 50] Ensemble

임종우·2022년 11월 22일
0

ai_school_TIL

목록 보기
31/34

11.22. 오전
어제에 이어 KMOOC 강의 수강!
오전에는 Ensemble에 대해서 공부하고, 오후에는 Support Vector Machine에 대해 공부해보려 한다.

시작!


Ensemble

일련의 분류나 회귀모델로부터 예측을 수집하면 가장 좋은 모델 하나보다 더 좋은 예측 성능을 얻을 수 있고, 이걸 앙상블 학습이라고 한다.
-> 여러 모델의 결과들을 다 종합하여 최선의 결과를 내보자! 라는 컨셉 (집단지성) 결국, 투표 기반 분류기라고 할 수 있다.(회귀도 가능하다)

  • 일반적으로 다양한 머신러닝 기법들을 앙상블 시켜주면 성능이 향상되는 효과를 얻을 수 있다.
  • 캐글에서 1등한 사람들을 보면 대부분 앙상블 기법을 사용했다.
  • tree기반이 많은데, tree가 수직 분할만 가능하고 일반화도 쉽게 되지 않는 반면, 여러 모델들의 조합, 투표로 만들어진 ensemble 모델은 비선형적인 분할도 가능하다.
  • 다만, 해석력이 Tree 모델보다 떨어질 수 밖에 없다는 단점이 존재한다.

Ensemble learning 이론

  • Weak Learner and Strong Learner
    다수결 투표 분류기(앙상블)는 앙상블에 포함된 개별 분류기 중 가장 뛰어난 것 보다도 정확도가 높은 경우가 많다
    그 개별 분류기들을 Weak learner(랜덤 추측보다 조금 더 높은 성능을 내는 분류기), 앙상블 모델을 Strong learner라고 부른다.
    결국, 앙상블은 Weak Learner들을 조합하여 Strong Learner를 만드는 것이다.

  • 수학적인 원리
    동전 하나가 앞면이 나올 확률이 51%, 뒷면이 49%일 때, 한번 던졌을 때 앞면이 다수일 확률은 51%이지만, 천 번 던졌을 때 앞면이 다수일 확률은 75%에 육박한다. 많이 던질수록 확률은 1로 수렴해 갈 것이다.
    저 동전을 분류기라고 생각했을 때, 이론적으로 100% 정확도를 갖는 분류기를 만들 수도 있다.
    물론 이 설명은 이론적인 것일 뿐, 앙상블의 핵심 원리를 설명해주는 것이다.
    모든 분류기가 완벽하게 독립적이고 오차에 상관관계가 없다는 가정 하의 이야기이다.

  • 앙상블로 효과를 보려면 다양한 분류기를 만드는 것이 중요하다.
    다양한 분류기를 만드는 첫번째 방법은 각기 다른 훈련 알고리즘들을 사용하여 앙상블을 진행하는 것이고,
    두번째는 training data의 subset을 무작위로 구성하여 분류기를 각기 다르게 학습시키는 방법이다.

  • 각각의 Tree들이 예측한 결과물을 다수결을 한다던지, 가중치를 줘서 가중합을 한다던지하는 방법으로 종합하여 최종 결과물을 낸다.

앙상블 기법의 종류

Bagging

Bootstrap + aggregating
Bootstrap이란, 랜덤 복원 추출을 의미한다.

즉, 랜덤 추출을 통해 원래 데이터의 사이즈와 같은 샘플들을 여러 개 추출하는데, 추출의 과정이 복원 추출로 이루어진다.
이렇게 만들어낸 여러 개의 샘플에 대해 각각 모델을 학습시켜, 해당 모델들의 결과를 이용해 최종 모델을 만들어내는 것이 바로 Bagging이다.

  • Bagging의 경우, 여러 모델들의 학습이 동시에, 병렬적으로 진행된다.

  • 오버피팅 문제에 사용하기 적합하다.

  • bootstrap(복원 추출)을 이용하기 때문에, 편향은 유지하며 예측 모형의 분산을 최소화하여 예측력을 향상한다고 한다.
    -> 수업시간에 예시로 들어주신 것처럼, 랜덤포레스트를 생각해보자.
    한 개의 결정 트리는 데이터에 있는 노이즈에 대해 매우 민감하겠지만, 랜덤포레스트에서 트리들 사이에 상관관계가 존재하지 않는다면, 여러 트리들의 평균은 그런 노이즈에 대해 강인할 것이다. 이게 편향은 유지하며 분산은 최소화한다는 것이다.
    따라서 오버피팅을 줄일 수도 있다.

  • OOB
    부트스트랩 과정 중 한 번도 샘플링 되지 않은 데이터들이 존재할텐데, 이것들을 OOB(Out-of-Bag)이라고 한다.
    해당 데이터들을 마치 validation set 처럼 이용할 수 있다.

  • Pasting
    Bagging과 유사하나, 복원추출이 아닌 비복원추출을 통해 샘플링을 진행한다.

Boosting

여러 weak learner들을 순차적으로 연결해, 이전 학습기의 잔차를 보완해나가면서 학습해나갈 수 있도록 한 알고리즘이다.
즉, 앞선 학습기에서 제대로 해내지 못한 부분에 대해 가중치를 두어 boosting한다.

이 개념까지는 이해가 되는데. 그걸 어떻게 한다는건지 대체 모르겠다.. 아무리 찾아봐도 모르겠다. 공부하다보면 언젠가 알게 되겠지...?

이 블로그에서 gradient boosting에 대해 좀 설명해주신 것 같은데.. 어렵다...! 대단하셔라...
모델에 실제값과 예측값을 줄여주는 함수 h(x)와 학습률 l을 곱한 값을 더해가며 다음 모델을 만든다고 생각하면 될 것 같다. (이 h 자체도 머신러닝 모델인 것 같고?)

목요일 으쌰 복습에서 정리해준 걸 봤더니 이렇게 정리해주었다.
1. 간단한 모델 A를 통해 y를 예측
2. 예측하고 남은 잔차 (residual)을 다시 B라는 모델을 통해 예측
3. A+B 모델을 통해 y를 예측

  • 모델의 학습이 순차적으로 진행된다.
  • 데이터에 가중치를 부여한다.
  • 개별 트리의 성능이 낮은 underfitting에 적합하다.
  • 앞에서부터 순차적으로 학습하므로 overfitting될 우려가 있다.
  • 시간이 오래걸린다.

-> 개별 결정 트리의 낮은 성능이 문제라면 boosting이 적합하고, 오버피팅이 문제라면 bagging이 적합하다!

Voting

  • Hard Voting
    다수의 분류기들 간 다수결을 통해 최종 클래스를 선정하는 방법.
    가장 많은 분류기들이 예측한 값이 최종 앙상블 모델의 예측값이 된다.

  • Soft Voting
    다수의 분류기들이 예측한 '확률값의 평균'을 통해 최종 클래스를 선정하는 방법
    분류기들이 예측한 각 클래스의 평균 확률이 높은 쪽이 앙상블 모델의 예측값이 된다.

  • 이 외에도 가중치를 두어 투표하는 등의 방법이 있다.

앙상블 모델

RandomForest

DecisionTree를 Bagging하여 만들어진 앙상블의 대표적인 모델이다.

사이킷런에서 RandomForestClassifier는 기본적으로 전체 특성 개수의 제곱근만큼의 특성을 선택하여 해당 특성들 중에서 최선의 분할을 찾아가는 방식으로 각각의 트리를 분할한다. RandomForestRegressor는 분할에 전체 특성을 사용한다고 한다.

-> 분류일때는 각 트리의 클래스별 확률을 평균하여 가장 높은 확률을 가진 클래스를 예측으로 한다.
-> 회귀일때는 각 트리의 예측을 평균한 값을 예측으로 한다.

oobscore = True를 인자로 준다면, .oob_score 메소드를 통해 OOB점수를 알 수 있다.

ExtraTrees

엑스트라 트리는 랜덤포레스트와 유사하지만, 각 결정트리를 만들때 전체 훈련 데이터를 사용하여 만든다. 즉, 부트스트랩을 사용하지 않는 것이다.
거기에 더해, 각 결정트리가 최선의 분할을 찾아가는 것이 아니라 무작위의 분할을 시행한다.

결론적으로 전체 훈련 데이터를 사용하는 여러개의 트리로 구성되는데, 각 트리는 최선의 분할이 아닌 임의의 분할을 통해 학습과 예측을 진행하는 것이다.

DecisionTree를 만들때 splitter = 'random'으로 지정한다면 ExtraTree가 되는데(ExtraTreeClassifier), Decision Tree가 아닌 이것들이 모여있다고 볼 수 있다.

엑스트라트리는 무작위성이 크기 때문에 랜덤포레스트보다 더 많은 결정트리를 훈련해야할 필요가 있다.
그러나, 랜덤하게 노드를 분할하기 때문에 계산속도가 랜덤포레스트보다 빠르며, 많은 트리를 앙상블하여 과대적합을 막을 수 있다.

  • VotingClassifier
    사이킷런 공식 문서 예제 참고
from sklearn.ensemble import VotingClassifier

clf1 = LogisticRegression(multi_class='multinomial', random_state=1)
clf2 = RandomForestClassifier(n_estimators=50, random_state=1)
clf3 = GaussianNB()

eclf1 = VotingClassifier(estimators=[
        ('lr', clf1), ('rf', clf2), ('gnb', clf3)], voting='hard')
eclf1 = eclf1.fit(X, y)
print(eclf1.predict(X))

공식문서

  • BaggingClassifier
    사이킷런 공식 문서 예제 참고
from sklearn.svm import SVC
from sklearn.ensemble import BaggingClassifier

clf = BaggingClassifier(base_estimator=SVC(),
                        n_estimators=10, random_state=0).fit(X, y)
clf.predict([[0, 0, 0, 0]])

공식문서

  • GradientBoostingClassifier
    깊이가 얕은 결정트리를 사용하여 이전 트리의 오차를 보완하는 방식으로 앙상블 하는 방법.
    기본적으로 깊이가 3인 결정트리를 100개 사용한다고 한다. 따라서 과대적합에 강하고 높은 일반화 성능을 기대할 수 있다.
    트리를 앙상블에 추가하는 과정에서 경사하강법을 사용한다. 손실함수로는 로지스틱 손실함수와 MSE를 사용한다.
from sklearn.ensemble import GradientBoostingClassifier
 
 clf = GradientBoostingClassifier(n_estimators=100, learning_rate=1.0,
    max_depth=1, random_state=0).fit(X_train, y_train)
clf.score(X_test, y_test)

공식문서

  • xgboost, lightgbm, catboost
    천천히 공부해보자...

https://zephyrus1111.tistory.com/224
https://tensorflow.blog/2017/11/30/%EB%8D%94%EC%9A%B1-%EB%9E%9C%EB%8D%A4%ED%95%9C-%ED%8F%AC%EB%A0%88%EC%8A%A4%ED%8A%B8-%EC%9D%B5%EC%8A%A4%ED%8A%B8%EB%A6%BC-%EB%9E%9C%EB%8D%A4-%ED%8A%B8%EB%A6%ACextratreesclassifier/
https://itstory1592.tistory.com/16
https://m.blog.naver.com/fbfbf1/222432485622
https://erdnussretono.tistory.com/49

profile
ai school 기간 동안의 TIL!

0개의 댓글