'averaging'에 해당되는 글 1건

  1. 2020.09.08 Kaggle Ensembling Guide (MLWave) / 한글 번역 / Part. 1 - (Averaging)
글 번역2020. 9. 8. 19:16
반응형

원글은 다음 링크의 글입니다. 

 

Kaggle Ensembling Guide | MLWave

Model ensembling is a very powerful technique to increase accuracy on a variety of ML tasks. In this article I will share my ensembling approaches for Kaggle Competitions. For the first part we look at creating ensembles from submission files. The second p

mlwave.com

이 글은 위 문서에 대한 자의적인 한글 번역본입니다. 번역을 하면서 이해한대로 설명을 더 추가할것이고, 아무리 시도해도 이해가 되지 않은 부분은 빠진 내용이 있을 수 있습니다. 영어 실력의 부족으로 번역이 매끄럽지 않을 수 있습니다. 댓글로 번역, 내용을 지적해주시면 감사한 마음으로 수정할 수 있도록 하겠습니다. 본문이 매우, 매우, 매우 긴 관계로 몇 편의 글로 끊어서 올릴 수 있습니다. 

번역상 '나' 는 필자가 아니라, 원 글의 저자임을 밝힙니다.

 


 

Kaggle Ensembling Guide

모델 앙상블은 여러 가지의 머신러닝 문제의 정확도를 올릴 수 있는 아주 강력한 방법입니다. 이번 글에서는 내가 캐글 대회에서 사용했던 앙상블 방법들을 공유하고자 합니다. 

첫번째 파트에서는 우리가 만든 제출 파일들로 앙상블하는 방법을 먼저 볼 것이고, 두번째 파트로는 스태킹(stacked generalization) 과 블렌딩(blending) 방법으로 앙상블을 하는 것을 볼 것입니다. 

'왜 앙상블이 일반화 오류를 줄여주는가?' 에 대한 답이 글에 포함되어있고, 마지막으로는 여러가지 앙상블 방법들을 보여줄 것이고, 스스로 시도해 볼 수 있도록 결과물과 코드들 역시 공유할 것입니다. 

"이것이야말로 당신이 머신러닝 대회를 우승할 수 있는 방법입니다. 다른 사람들의 결과물을 가져와서 앙상블하는것." 
- Vitaly Kuznetsov (NIPS2014)

 

제출 파일들로 앙상블 만들기

앙상블을 시도하는데 가장 편리하고 기본적인 방법은 캐글에 제출하는 csv 파일들을 사용하는 것입니다. test 데이터에 대한 예측값들만 필요하고, 새로운 모델을 학습시킬 필요가 없습니다. 이건 이미 존재하는 모델들의 예측값을 앙상블하기 가장 빠른 방법이고, 팀을 만들어 앙상블 하는 과정에 적합합니다.

투표 방법 (Voting Ensemble)

처음으로 시도할 만한 것은, 단순한 투표 방식입니다. 왜 모델 앙상블 방법이 에러를 줄여주고, 낮은 상관관계를 가진 예측값들에 더 잘 작동하는지 볼 것입니다.

우주에 관한 임무를 실행할 때에는 모든 신호(signal)들이 순서대로 잘 배치되는것이 중요합니다. 우리가 가진 신호가 다음과 같은 이진 문자열이라 해봅시다.

1110110011101111011111011011

만약 신호가 다음과 같이 망가졌다면, (1 한개가 0으로 바뀐 상황):

1010110011101111011111011011

하나의 생명을 잃을 수도 있습니다. 

에러 수정 코드에서 방법을 찾을 수 있습니다. 가장 단순한 방법은 repetition-code 라는 방법입니다. 이는 신호를 같은 크기의 덩어리로 여러 번 반복하고, 다수결 투표 방식을 취합니다. 

Original signal: 1110110011

Encoded: 10,3 101011001111101100111110110011

      Decoding: 1010110011

                       1110110011

                       1110110011

Majority vote: 1110110011

신호가 망가지는 것은 흔하게 발생하는 것은 아닙니다. 그래서 이러한 다수결 투표 방식이 망가진 신호를 '망가지게' 할 가능성은 더더욱 적습니다. 

이런식으로 신호가 망가지는것을 100% 예측할 수 없지는 않습니다. 따라서 이러한 방식으로, 망가진 신호를 원래의 신호로 고쳐질 수 있습니다.  

 

머신러닝에서의 예시

우리가 10개의 샘플을 가지고 있다고 가정합시다. 이 샘플들의 정답(ground truth)은 모두 1입니다. 

1111111111

그리고 우리는 세 개의 이진 분류기 (binary classifiers) 들이 있습니다. 각각의 모델은 70%의 정확도를 가지고 있습니다. 이 세 개의 분류기를 70%확률로 1을 뱉고, 30%의 확률로 0을 뱉는 난수 생성기로 볼 수도 있습니다. 이러한 랜덤 모델들도 다수결 투표 방법으로 78%의 정확도를 가지도록 할 수 있습니다. 약간의 수학을 더하자면 : 

3명의 다수결 투표 방식으로는 4가지의 결과값을 기대할 수 있습니다.

세개 모두 정답 : 0.7 * 0.7 * 0.7 = 0.3429

두개만 정답 :  0.7 * 0.7 * 0.3 + 0.7 * 0.3 * 0.7 + 0.3 * 0.7 * 0.7 = 0.4409

한개만 정답 : 0.3 * 0.3 * 0.7 + 0.3 * 0.7 * 0.3 + 0.7 * 0.3 * 0.3 = 0.189

셋 다 틀림 : 0.3 * 0.3 * 0.3 = 0.027

우리는 여기서 약 44%라는 많은 경우에 대해서 다수결 투표가 오답을 정답으로 고칠 수 있는 것을 알 수 있습니다. 이러한 투표는 정답률을 78%까지 올려줍니다. (0.3429 + 0.4409 = 0.7838)

 

투표 구성원 수

여러 번 코드가 반복될 수록 에러 수정 능력이 증가합니다. 마찬가지로, 앙상블 방법도 많은 앙상블 구성원이 있을 때 일반적으로 더 좋은 결과를 줍니다. 

위에서의 예시를 다시 가져온다면, 3개가 아니라 5개의 70% 정확도를 가진 모델을 앙상블한다면, 약 83%정도의 정확도를 기대할 수 있습니다. 한두 개의 오답은 66% 정도의 다수결 투표로 고쳐질 수 있습니다 (0.36015 + 0.3087)

 

상관관계 (Correlation)

KDD-cup 2014에 참가하면서 팀을 꾸렸는데, Marios Michailidis (KazAnova) 가 아주 특이한 것을 제안했습니다. 그는 우리가 제출했던 모든 파일의 피어슨 상관계수를 계산해서 상관관계가 적은 괜찮은 모델들을 모았습니다. 그리고 이들의 평균을 내서 제출하는 것 만으로 우리는 50등수를 올릴 수 있었습니다. 확실히 상관관계가 적은 결과물들이 앙상블 된 것이, 상관관계가 높은것들의 앙상블보다 좋은 결과를 보였는데, 왜일까요?

위에서와 마찬가지로 3가지의 모델 결과물들을 생각해봅시다. 예측해야 하는 정답은 여전히 1 들입니다.

1111111100 = 80% accuracy

1111111100 = 80% accuracy

1011111100 = 70% accuracy.

이 세 개의 모델은 상당히 상관관계가 있어서, 다수결 투표를 적용해도 전혀 발전이 없습니다 : 

1111111100 = 80% accuracy (다수결 투표 결과)

하지만, 성능은 좀 덜하지만, 낮은 상관관계가 있는 모델들을 생각해보면 다음과 같습니다. 

1111111100 = 80% accuracy

0111011101 = 70% accuracy

1000101111 = 60% accuracy

다수결 투표를 하면:

1111111101 = 90% accuracy (다수결 투표 결과)

엄청난 발전입니다. 앙상블 구성원의 상관관계가 낮을수록, 에러 수정 능력이 더 향상되는 것 같습니다. 

 

캐글 예시 : Forest Cover Type Predictions

다수결 투표 방식은 측정공식(evaluation metrics)이 더 정확한 답을 요구할 수록  빛을 발합니다. 예를 들면 '정확도' (accuracy) 가 있습니다.

 forest cover type prediction 대회는 UCI Forest CoverType dataset 을 활용하고 있습니다. 변수의 갯수는 54개, 정답에는 6개의 클래스가 있습니다.  우리는 일단 아주 간단한 모델 을 만들었습니다. 500개의 트리가 있는 랜덤 포레스트 모델입니다. 일단 이 모델을 몇 개 만든 이후, 가장 좋은 1개의 모델을 골랐습니다. 이 상황에서는 ExtraTreesClassifier로 만든 모델이 가장 좋았네요.  

 

가중 투표 (Weighing)

그리고 우리는 가중 투표 방식을 취했습니다. 이유는, 우리는 일반적으로 '더 잘 맞추는 모델' 에 더 가중치를 주고 싶습니다. 그래서 '가장 잘 맞추는 모델' 에게 3표를 주고, 나머지 4개의 모델에는 한표씩을 주었습니다. (역주 : 총 모델은 5개지만, 투표 수는 7표겠네요.) 이유는 다음과 같습니다 : 

'좋지 않은 모델'들이 가장 좋은 모델을 이길 수 있는 방법은 그들이 가진 예측값(오답)들을 모아서 확실한 다른 답(정답)을 내는 것이기 때문입니다. 

우리는 이 앙상블이 '가장 잘 맞추는 모델' 의 몇개의 잘못된 선택을 바로잡을 수 있을 것이라 기대할 수 있습니다. 아주 약간의 성능 개선이 있겠지요. 그것이 민주주의를 잃어버리고, 플라톤의 <국가>를 만든 것에 대한 우리의 벌칙이라 할 수 있겠습니다.

(역주 : <국가> 를 읽어보지 않아서 어떤 비유인지 잘 모르겠네요. 직역하긴 했지만 이상합니다.)

“모든 도시는 서로 전쟁중에 있는 두 도시를 포함한다.” 플라톤  <국가>

아래 표는 위에서 언급한 5개의 모델을 학습시키고, 가중 투표 방식을 적용한 결과물을 보여줍니다.

GradientBoostingMachine 0.65057
RandomForest Gini 0.75107
RandomForest Entropy 0.75222
ExtraTrees Entropy 0.75524
ExtraTrees Gini (Best) 0.75571
Voting Ensemble (Democracy) 0.75337
Voting Ensemble (3*Best vs. Rest) 0.75667

 

캐글 예시 : CIFAR-10 Object detection in images

CIFAR-10 은 정확도를 보는 또 다른 다중 분류 문제입니다. 우리 팀의 리더인 Phil Culliton이 Graham 박사의 좋은 모델 구조를 채용할 수 있는 모델을 만들었습니다. 그 후 90%의 정확도가 넘는 30개의 모델에 대해 다수결 투표 방식을 적용했습니다. 이중 가장 좋은 모델의 정확도는 0.93170 이었습니다. 

다수결 투표를 한 결과물의 점수는 0.94120 이었고, 이는 인간이 분류할 수 있는 정확도를 뛰어넘었습니다. 

 

코드 예시

우리는 MLWave의 깃헙 저장소에 샘플 투표 코드를 사용할 수 있게 두었습니다. 이것은 캐글 제출 파일 디렉토리에서 실행되고, 새로 결과물을 제출합니다. Update: Armando Segnini 가 투표에 가중치를 추가하였습니다. 

10개의 신경망을 만들고, 예측 결과를 평균해라. 이것은 상당히 단순한 방법이지만 결과를 상당히 향상시킬 수 있다. 

혹자는 왜 평균을 내는 것이 이렇게 도움이 되는가 신기해 할 수도 있지만, 평균이 효과가 있는 이유는 아주 단순하다. 
두 개의 모델이 70%의 정확도를 내고 있다고 가정하자. 그 두 모델의 합의는 옳을 때도 있지만 옳지 않다면, 어느 한쪽이 옳은 경우가 종종 있다. 이때 평균을 낸 결과물은 정답에 더 많은 가중치를 둔 결과가 된다. 

이 효과는 모델이 '맞출 것' 은 확실히 맞추지만 '틀린 것' 에 대해서 애매하게 찍고있는 경우 더 잘 작동하게 된다. 
Ilya Sutskever A brief overview of Deep Learning.

 

평균 (Averaging)

평균은 분류, 회귀 문제에 상관 없이, 측정 공식(AUC, squared error, log loss) 에 따라서도 별 상관 없이 다양한 분야의 문제에서 잘 작동하는 편입니다. 

각각의 모델의 결과물을 더해서 평균을 내는 것 이상의 대단한 것도 없습니다. 캐글에서 종종 "Bagging submissions" 라고 하는 것이 이것을 의미합니다.  평균을 내는 것은 종종 오버피팅을 줄여줍니다. 당신은 몇 개의 클래스를 '부드럽게' 분리해내고 싶을겁니다. (원 : smooth seperation) 하지만 단일 모델은 그 '결정 경계' (원 : edges) 가 그렇게 부드럽지 않을 수 있지요. 

 

이 캐글 대회(Don’t Overfit!) 을 보면 (역주 : 사진이 안들어가서 문장을 약간 수정했습니다), 검정색 선이 초록색 선보다 더 좋다고 볼 수 있습니다. 초록색 선은 데이터의 노이즈를 더 학습한 상태입니다. 여러개의 초록색 선을 구해서 평균을 낸다면, 우리가 얻을 결과값은 검정 선에 더 가까워질 것입니다. 

우리가 항상 기억해야 할 것은, 절대 학습데이터를 '외워'서는 안된다는 것입니다. 새로 보게 될 데이타에서도 '일반적으로' 잘 작동하는 모델을 만들어야 합니다. (데이터를 외울거면 더 효율적인 방법들이 있습니다)

 

캐글 예시 : Bag of Words Meets Bags of Popcorn

이 대회는 영화 감정 분석 대회 입니다. 이 전 게시물에서 퍼셉트론을 이용해서 95.2 의 AUC를 얻는 것에 대해 쓴 적이 있습니다. 

퍼셉트론은 '선형 분류' 모델입니다. 이건 참 환영할만한 특성이지만, 퍼셉트론은 데이터를 분류할 수 있게 되면 더이상 학습을 하지 않는다는 사실을 알아야 합니다. 이는 새로운 데이터에 대해서 '최고의 결정 경계' (원 : best seperation) 을 찾아주지는 않을 것입니다. 

우리가 5개의 퍼셉트론 모델을 랜덤한 가중치로 초기화하고, 그 예측 결과물의 평균을 구한다면 어떨까요? 우리는 test 데이터에 대해 성능 향상을 가져왔습니다.

PUBLIC AUC 점수

Perceptron 0.95288
Random Perceptron 0.95092
Random Perceptron 0.95128
Random Perceptron 0.95118
Random Perceptron 0.95072
Bagged Perceptrons 0.95427

위 결과는 앙상블 방법이 (임시적으로) 데이터의 세부적인 내용들과 특정 머신러닝 알고리즘의 내부 작동 원리들을 연구해야 하는 당신을 구했습니다. 만약 앙상블이 잘 된다면, 좋은것이고, 잘 되지 않더라도 크게 손해나는 것은 없습니다. 

그리고 당신은 10개의 '똑같은'  선형회귀 모델을 평균내는 것에 대한 페널티도 받지 않습니다. 한개의 '올바르지 못한 교차검증 방법으로 인해 과적합된 예시를 평균내는 것 조차도 평균의 다양성을 추가하는 것이기 때문에 약간의 성능 향상을 가져올 수도 있습니다. 

코드 예시

단순 평균 예시 코드를 깃헙에 올려두었습니다. csv 파일들의 경로를 인풋으로 받고, 평균된 결과물을 출력합니다. Update: Dat Le 가 기하 평균 예시 코드를 추가했습니다. 기하평균은 단순 평균(원 : plain average, 역주 : 산술평균)보다 더 좋을 수도 있습니다.  

 

순위 평균 (Rank averaging)

서로 다른 여러개의 모델의 결과물들의 평균을 구할때 몇 가지의 문제점들이 생길 수 있습니다. 모든 예측 모델이 완벽하게 보정되지 않았다는것인데, 각각은 예측해야 할 확률값들을 지나치게 과신하거나 불신할 수 있으며, 예측값들은 특정 범위에 대충 흩어져 있는 모양새일 수 있습니다. 아주 극단적인 제출 파일의 예시를 하나 적어보자면 다음과 같습니다:

Id,Prediction 

1,0.35000056 

2,0.35000002 

3,0.35000098 

4,0.35000111

이런 예측은 측정공식이 AUC 처럼 경계값(원 : threshold) 을 기반으로 하거나, 순위를 매기는 방식이라면 리더보드에서는 결과가 좋게 나올 것입니다. 하지만 이렇게 생긴 다른 모델의 예측값과 평균을 구한다면: 

Id,Prediction 

1,0.57 

2,0.04 

3,0.96 

4,0.99

결과는 전혀 바뀌지 않을 것입니다. 

(역주 : 각 행의 값들이 거의 비슷해서, 평균을 내도 두번째 파일의 값들의 분포와 비슷해집니다. 평균을 해서 값이 변해서 오답을 고치는 능력이 적어지겠네요.)

우리의 해결책은 예측값들의 '순위' 를 매기는 것입니다. 그리고 이 순위들의 평균을 구합니다. 

Id,Rank,Prediction 

1,1,0.35000056 

2,0,0.35000002 

3,2,0.35000098 

4,3,0.35000111

이렇게 평균을 낸 순위를 0과 1 사이의 값으로 normalize 하면, 아마 예측 결과물은 균등 분포(원 : even distribution)를 이룰 것입니다. 순위 평균의 결과를 보자면 : 

Id,Prediction 

1,0.33 

2,0.0 

3,0.66 

4,1.0

(역주 : 결과물을 보시면, 1 * 0.35000056  |  0 * 0.35000002  |  2 * 0.35000098  |  3 * 0.35000111 로 되어 있습니다)

 

Historical rank.

랭킹은 test 데이터셋이 필요합니다. 하지만 새로운 1개의 샘플에 대해서만 예측하기를 원한다면 어떻게 해야할까요? 아마도 예전에 쓰던 (역주 : 모델 검증에 사용하던) test 셋에 섞어서 랭킹을 구할 수도 있겠지만, 이것은 솔루션의 복잡도를 증가시킬 것입니다. 

한 가지 방법은 'Historical rank' 를 사용하는 것입니다. 우리가 원하는 새로운 샘플의 예측값이 '0.35000110' 이라면, test 셋의 예측값들 중에서 이 예측값과 가장 가까운 값을 찾아, 그 순위를 가져옵니다. (이 경우의 순위는 '3'을 가져오겠네요. 값이 0.35000111 로 가장 비슷합니다.)

캐글 예시 : Acquire Valued Shoppers Challenge

이 순위 평균 방식은 순위를 예측하는 경우나, AUC 같은 경계값이 있는 측정공식, 그리고 Average Precision at k 와 같은 'search-engine quality metrics' 에 잘 작동하는 편입니다. 

Shopper challenge 의 목표는 해당 고객이 다음에도 다시 올 가능성이 높은지 순위를 매기는 것입니다. 

우리 팀은 첫 번째로 여러 개의 'Vowpal Wabbit' 모델들과 'R GLMNet model' 의 평균을 구했습니다. 그 후에 순위 평균 방법을 적용해서 성능을 향상시켰습니다. 

MODEL     |          PUBLIC        |          PRIVATE

Vowpal Wabbit A 0.60764 0.59962
Vowpal Wabbit B 0.60737 0.59957
Vowpal Wabbit C 0.60757 0.59954
GLMNet 0.60433 0.59665
Average Bag 0.60795 0.60031
Rank average Bag 0.61027 0.60187

나는 전에 Avito challenge 에서 순위 평균으로 엄청난 성능 향상이 있었다는 것에 대해 글을 쓴 적이 있습니다. 

 

코드 예시

간단한 순위 평균 코드 를 MLWave 의 깃헙 저장소에 추가되었습니다. 

대회가 참 좋은 이유로는, 정말 여러 가지의 모델링 방법들이 있고, 적용할 수 있는 테크닉들도 다양한데, 우리는 어떤게 효과적이었는지 절대 미리 알 수가 없다는 점입니다. - Anthony Goldbloom Data Prediction Competitions — Far More than Just a Bit of Fun

 

From ‘How Scotch Blended Whisky is Made’ on Youtube

 

 

 

 

....계속...

 

Part 2 링크 : 

 

Kaggle Ensembling Guide (MLWave) / 한글 번역 / Part. 2 - (Stacking, Blending Ensemble)

Part 1 링크 : Kaggle Ensembling Guide(mlwave) / 캐글 앙상블 가이드 한글 번역 / Part. 1 원글은 다음 링크의 글입니다. Kaggle Ensembling Guide | MLWave Model ensembling is a very powerful technique to..

jamm-notnull.tistory.com

 

반응형
Posted by Jamm_