Overfitting을 피해보자!

Overfitting은 노이즈와 시그널을 구분하지 못하고 노이즈를 과도하게 학습에 사용하게 됨으로써 미래의 데이터에 대한 예측 퍼포먼스를 갉아 먹는 모형 상태를 의미한다.  이런 부분이 최근 빅 데이터 시대에 문제가 되는건 바로 다양한 데이터 때문이다.  필자는 지난번 포스팅에서 데이터가 부족해서 일어났던 과거의 오버피팅이 속성이 다양해지면서 발생하는 오버피팅문제로 전환 시켰다고 언급했는데, Lasso와 같은 Regularization 이외의 방식으로 오버피팅을 피하는 방안들을 정리해 보기 위해서 글을 써본다.

 

수백여개의 변수 사용

필자가 지난번 포스팅에서 다양한 속성 때문에 발생한다고 한 문제는 아래와 같은 방식으로 해결 가능하다.  뭐… 가장 일반적으로 일어나는 오버피팅은 아래와 같은 조치로 대부분 해결 가능하다.

  • 좀더 많은 데이터를 구한다
    •  – 필자 경험상 효과는 있지만 속성 자체를 줄이는 것만큼 큰 효과를 주지는 않았다.
  • 적은 수의 변수를 사용한다.
    •  – 경험이 많은 사람들은 알고 있다. 오히려 변수를 줄임으로써 out of time validation 퍼포먼스가 test set 퍼포먼스보다 더 좋아질 수 있다는 것을…
    •  – 70년 전통의 역사상 가장 상업적으로 성공한 예측모형인 신용평가모형은 10개 내외의 변수를 사용하라고 필드 메뉴얼에 언급하고 있고, 메뉴얼 대로 작성한 모형은 2년이 넘어도 안정적인 성능을 보여준다.

잘못된 테스트 데이터 선택

전체 데이터의 부분으로 학습하고 나머지 부분으로 테스트하는 행위는 전혀 오버피팅을 검출할 수 없게 하고 모형의 잘못된 퍼포먼스만을 보여준다. 반드시 예측 목적에 맞게 out of time validation셋으로 평가해야 된다.  종종 학습시 training AUC, error 가 모형 결과로 도출되어 희망에 부풀곤 하는데, 앞에 training ~ 이라 붙은 성능 지표 결과는 무시하는게 정신 건강상 좋다.

 

상식적이지 않은 변수 관계

알려져 있는 상식은 잘 깨지지 않고, 위배되는 경우가 거의 없으며 그런 상식은 앞으로 1,2년 내에 변할 가능성은 없을 것이다. 예를 들어 최근 1년 동안의 가스요금 체납 횟수가 많으면 많을 수록 향후 90일동안의 채무불이행 확률은 늘어날 것이라는걸 상식적으로 알 수 있다. 만일 모형에서 이와는 반대 방향으로 설명한다든지 비선형적인 패턴을 보인다면 해당 변수는 일단 면밀히 살펴볼 필요가 있다.  과연 그러한 패턴이 그 전과 후에도 발견이 되는지와 앞으로도 그럴 것이라는 확신이 들때 비로소 해당 변수를 사용할 수 있으며 만일 그럴지 아닐지 계속 의문이 든다면 심한 경우 모델에서 제외하는 것도 고려해 봐야 된다.

아쉽게도 이런 변수간의 관련성을 black-box 모형에서는 알기 어려운 경우가 많다. 물론 관련 연구가 없는 것은 아니다. 예를 들어 SVM의 경우 support vector만을 가지고 tree 모형으로 학습해 모형을 해석하는 연구도 되어 있기 때문이다. 하지만 명확히 검증된 방법은 없기 때문에 지금도 regression  혹은 트리모형이 많이 사용된다. regression이 많이 쓰이는건 내부를 면밀하게 들여다 볼 수 있는 장점 때문에 흡사 나침반을 들고 모델링을 하는 느낌을 주기 때문이다.

 

엄청난 파라메터들…

GBM알고리즘의 구현체 중에서 최근 가장 많이 사용하는 xgboost의 경우 굉장히 많고 다양한 모형 파라메터를 제공하고 있다. 이들을 caret과 cross-validation을 이용해 최적의 파라메터를 찾았다고 한다면 과연 이 파라메터가 미래 데이터에서도 최적일지 반드시 고민해야 된다. 결국 이 파라메터도 현재 데이터에 오버피팅 하는데 일조하고 있을지 모른다.  역시 적절한 validation 셋으로 파라메터를 설정해야 될 것이다.

 

변수 종류에 따른 표현…

기계학습 변수에는 크게 두가지 변수가 존재한다.

  1. contextual feature
  2. historical feature

contextual feature는 성별, 나이, 주소 등 시간이 지나도 잘 변하지 않는 속성을 의미한다. historical feature는 이와는 반대로 사용성을 의미하는 속성들이 속하게 되는데, 예를 들어 어제 특정 번호에 전화를 몇번 했는지, 1시간전에 특정 광고를 몇번 클릭 했는지 등 예측의 대상이 되는 개체의 행동을 포괄하고 있는 속성을 의미한다.  최근 다양한 종류의 데이터가 수집되면서 historical feature가 예측력에 기여하는 정도가 매우 커지고 있는 상황임에도 불구하고 일반 contextual feature와 같은 방식으로 모형에 적용하다가 오버피팅의 수렁에 빠지는 경우를 많이 목격하곤 한다.

아래와 같은 변수 전환이 필요하다.

1시간전 광고 클릭수 -> 3시간 동안의  총 광고 클릭수 대비 최근 1시간  광고 클릭수 비율

클릭수의 경우 수치의 variation이 0~무한대 인 반면, 비율의 경우 0~100% 사이에서 변동하기 때문에 변수 변동성이 적어 시점에 따라 크게 변화하지 않는다.

결국 contextual feature의 경우 그대로 사용해도 시점에 따른 변동성만 적당히 체크하면 그대로 사용할 수 있으나, historical feature의 경우 시점에 따라 변동이 심할 가능성이 많아 변동이 적은 방향으로 변수를 변환하여 사용해야 된다.

 

좋은 패키지

 

model_complexity_error_training_test

유명한 오버피팅에 대한 설명중에 하나인데, 위 컨셉 그대로 몇몇 기계학습 패키지는 적절한 시점에 학습을 멈추게끔 설계되어 있기도 하다. 물론 학습시 test set을 별도 입력해줘야 되는 불편함이 있는데, 나중에 발생할 사태에 비해면 매우 적은 비용이다.  당연히 test set은 예측 목적에 맞는 out of time set 이여야 될 것이다.

 

면밀하고 비판적인 모델링

단 1회의 모델링에 AUC 0.9 이상의 모형이 나올 가능성은 거의 없다. 설령 나왔다고 한다면 그게 진짜인지 오버피팅에 의한 결과인지(혹은 데이터가 오염된 것인지…) 모형을 비판적으로 바라봐야 된다.  10%의 시간을 모델링 하는데 썼다면 나머지 90%의 시간은 성능에 대한 확신을 가지는데 써야 된다.

 


실무 모델링에서 오버피팅은 매우 자주 발생한다. 따라서 발생했다고 해서 당황할 필요는 없으며, 오히려 그런 과정을 통해 모델링의 목적을 다시 상기시킬 수 있는 좋은 계기가 된다.

필자가 생각하는 오버피팅의 가장 큰 부작용은 오버피팅이 무서워서 neural net과 같은 알고리즘을 거들떠도 보지 않는 상황이다. 특히 관련된 심한 트라우마가 존재하는 사람일 수록  neural net 사용을 피하고 더 나아가서 Deep Learning 역시 피하곤 하는데, 이는 정말 잘못된 자세라 생각한다. 어떠한 방법론이든 충분히 사용해보지 못하면 문제를 발견하기 어렵고 장점 역시 발견하기 어렵다.

필자의 경우 NN와 RandomForest 애호가로 예측 모델링에 발을 들여 놓았다가 inference가 가능한 regression류의 방법론에 심취하여 사용했고, 이후  Boosting기법의 파워에 매료되어 한동안 Boosting만을 사용하였다가 최근엔 Lasso 등의 방법론을 활용중에 있다. 결국 Variance가 큰 모형 <-> Bias가 큰 모형 사이를 오간 것이다. 그러다 보니 필요에 따라 모형선택의 폭이 넓어지며 성격이 다른 모형을 깊게 사용하면서 서로의 장단점을 두드러지게 느끼게 되어 이해의 깊이도 깊어지게 되었으며, 최근엔 두 모형의 장점을 결합한 하이브리드 모델링 기법을 사용하기도 하면서 재미를 보기도 했다. 결국 이런 유연성은 깊은 이해를 통해 얻어지게 되는 것인데, 그런 좋은 경험의 기회를 오버피팅이라는 흔히 발생하는 문제 때문에 잃지 않길 바랄 뿐이다. 오버피팅은 당연히 발생할 수 있는 문제이며 이를 해결하는 것은 모델링 과정의 일환이라는 걸 이해해야 될 필요가 있다.

CC BY-NC 4.0 Overfitting을 피해보자! by from __future__ import dream is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.