(네이버 블로그 게시글을 옮겨왔다!)
이번 데이콘 스터디 2차 컴퍼티션에서 엄청 열심히했는데 처음으로 실패를 경험했다.
근데 생각해보니 지금까지 참여한 컴퍼티션에서는 오버피팅을 고려한 적이 없었던거다.
그래서 다신 이런 실수를 하지 않으려고 동아리사람들한테 코드도 달라구 하고, 하나하나 내 코드랑 비교해보면서 찾은 문제점을 기록한다!
0. 이번 컴퍼티션에서 주안점을 둔 것
- Kfold를 이용해 cv를 나눠서 for 문으로 부스팅 계열 모델링. (버스 승차량에서도 이걸로 성능 향상을 경험했기 때문)
- 최대한 다양한 분류 모델을 쓰려고 노력함. (knn, gb, adaboost까지,,,,,,캐글 타이타닉 커널 참고해서 검색함)
- 베이지안 최적화(튜닝할 때 요즘 많이 쓰는 방법이라고 해서 한번 해봄)
- 피쳐를 기계적으로 늘리는 것(연속통계량이 있으면 groupby로 모든 범주에 추가했다)
> 지금 보니까 이게 제일 문제였다..... 피쳐가 편향을 학습하고 있었던거다.
- over/under sampling (but 성능이 안좋아서 결론적으론 쓰지않음)
(20.12.30 첨언)
그 당시 가장 높은 private score는 catboost + over/under sampling한 거였는데, sampling으로 기존 train 데이터의 편향을 그나마 완화할 수 있었던 듯 하다. 이 score는 public과 엄청 차이가 많이났다(그래서 최종 score로 선택할 수 없었다) 당연히 overfitting되고 피쳐가 train data 편향을 엄청 잘 흡수했으니까 그러겠지~~~~~ 하지만 그땐 이걸 몰랐다. 아무튼 groupby로 기계적으로 늘린게 잘못된 학습을 가져왔던거다.
1. 하지만 문제였던 것
- groupby로 연속 통계량을 계속 사용한 것. (겹치는 피쳐가 많이 생긴거같다)
연속형을 범주로 묶고, 이를 다시 grouby를 이용해 연속형 통계량(mean) 등을 구해 피쳐로 넣었다.
그러면 당연히 똑같은 통계량이 반복해서 칼럼에 들어가고, 이는 편향이 되었던 것이다. 그래서 오버피팅이었던 것 같다.
> 피쳐를 최대한 다양한 시각에서 만들려고 노력해야한다. 한번 쓴 피쳐는 다시 쓰지 말자.
차라리 groupby를 두개 이상으로 묶자. 이는 피쳐 개수가 늘어질수록 편향을 학습시키는 지름길이었다.
- 피쳐 생성 + 리더보드에 치중해 피쳐 하나하나에 신경을 못쓴 것.
importance와 피쳐 선택에 소홀했다. 그냥 막 넣음...
> importance와 A/B test로 피쳐 하나하나 다양하게 만들고, 이를 평가해야할 것이다. 표 만드는 방법 좋은 것 같다!
- 비율 대신 sum, count를 사용한 것.
> 비율이 통상적으로 성능이 더 좋다. 하지만 이를 모른채,, sum을 주구장창 넣음
- 범주를 get dummy로 펼치지 않은 것.
> 펼치기만 해도 높은 private 점수를 얻을 수 있었다.
- 오버피팅을 중간중간에 확인하지 않고 피쳐를 만든 것.
valid set의 중요성을 잘 몰랐던 것 같다. 마지막에 급히 시행했으나 random seed가 바뀔때마다 valid score가 바뀌더라...피쳐 하나하나 추가할 때마다 valid set으로 성능 평가를 해야할 것 같다.
(20.12.30 첨언) 지금 생각해보면 난 참 근본적인걸 놓치고있었던 듯 하다.
2. 앞으로의 해결방안과 좋은 피쳐 인사이트
문제는 고치면 된다!
- 최대한 다양한 피쳐를 만드려고 노력하자. 편향된 시각이 아닌 다양한 시각에서 모델이 타겟을 볼 수 있도록!
한번 만든 피쳐는 되도록 또 쓰지말자. 아이디어를 계속 내자!(다양한 인사이트를 담을 수 있는 창의적인 피쳐)
- 피쳐 하나하나의 중요성을 알자. 기계적으로 막 늘린다고 성능이 좋아지는건 절대아니었음을 기억하자.
(차원의 저주를 유의하자! 트리계열의 모델은 노드분할에 있어 차원의 저주의 영향을 받을 수 밖에 없을 것이다)
하나하나 공들여 만들고 A/B test와 importance, permutation 등을 통해 그 피쳐가 가지는 무게를 파악하고 있자.
(한동안은 표를 만드는 것도 좋은 방법 같다!)
- valid set의 중요성을 알자! 항상 valid score를 랜덤시드 바꾸면서 보자 (피쳐 하나하나 넣을때마다)
- sum, count보단 비율이 좋다. 다른 범주의 비율도 칼럼으로 넣어주자.
- get_dummy로 범주를 펼쳤다면 차원축소를 해주자.
- 최대 구매량, 평균 구매량 등 이런 단순 피쳐들도 좋은 것 같다. 마지막에 한번에 groupby agg로 처리하는 것도 좋아보인다.
- groupby를 두개 쓰면 ~별 통계량이 나온다. 이를 잘 활용하자!
이 컴퍼티션은 절대 잊지 못할거다,,,,