점수 및 순위

  • Private LB / AUROC : 0.8389, ACC : 0.7527 / 6위
  • Public LB / AUROC : 0.8381, ACC : 0.7634 / 3위

Final Submit의 Options

Inference and Ensemble

  • Team Custom Ensemble 사용 (Threads hold 0.4, 0.6)

Model

  • Causal Convolution Layer, GRU, Attention Layer를 활용한 Custom Model
  • Parallel 하게 연산하여, 각 Embedding Vector를 더하여 활용
  • Skip Connection 등의 추가로 Embedding Layer 학습을 강조

Training

  • 정답률의 분포가 바뀌는 19개의 Feature를 사용
  • User ID 기준으로 Fold를 구성했고, User 별 마지막 Interaction을 Validation set으로 활용
  • User ID와 Test ID 기준으로 Data Augmentation 진행
  • Max Sequence Length를 10으로 짧게 주어, User의 일반적인 특징 학습

성능 향상을 위해 시도한 실험

다양한 Idea와 설정으로 실험을 수행했다.

Version별 수행한 실험 List의 예시
Version별 실험의 Socre의 예시

실험 List

  • EDA 및 Feature Engineering
  • Baseline Models 실험
  • Data Augmentation 실험
  • Team Validation Strategy 실험
  • GRU Model 실험
  • Causal Convolution Model 실험
  • ConvGRU Model 구현 및 변형 실험
  • Parallel Operation Model 구현 및 변형 실험
  • Multi Task Learning Model 구현 및 실험
  • Ensemble 전략 실험

실험의 근거와 의의

  • EDA 및 Feature Engineering

    대회에서 사용하는 Data가 정형 데이터이고, 사용할 수 있는 Feature가 4개에 불과했다. 어떤 접근 방법을 사용하더라도, Feature Engineering이 필요한 상황이었고 이를 위해 기준을 먼저 세웠다.

    이 Task를 수행하기 위해 필요한 특징정보는 결국 정답과 관련된 Feature라는 결론을 내릴 수 있었다. (Link) 이에, 각 Feature를 기준으로 정답률이 달라지는지를 확인해가며 Feature를 만들었고, 최종적으로는 19개의 Feature를 사용하게 되었다.

    Feature를 만들 때 유의했던 점 중 하나는, 미래의 Label 정보가 과거 Data의 Feature로 드러나지 않도록 하는 것이었다. 이를 위해서는 시간 단위로 Engineering을 하거나, 미래 Label 정보를 Masking하는 방법을 사용했다.

  • Baseline Models 실험

    Baseline에서는 생각보다 많은 Model을 제공해줬다. LGBM, LSTM, LSTMATTN, BERT, SAINT, LastQueryTransformer 등 각각의 Model이 구현되어 있어 손쉽게 실험을 진행할 수 있었다.

    Baseline 환경에서 각 모델을 실험해 본 결과, Model의 Size가 커질수록 과적합되는 현상이 두드러지게 나타났다. 우리한테 주어진 Data가 많지 않고, User의 특징정보가 적었으며, Sequence의 평균 길이도 짧았기 때문에 위 모델을 그대로 사용하는 것은 적합하지 않다고 여겨졌다.

    최종적으로는 위 모델들로부터 얻은 Idea로 Custom Model을 구현하게 되었고, 성능도 높일 수 있었다.

  • Data Augmentation 실험

    Baseline에서는 User 기준으로 마지막 N개의 Interaction으로만 Sample을 구성했다. Train에 있는 약 7천명의 User를 기준으로 Sample을 구성하고 있으니, 약 7천개의 Sample로만 학습을 하는 상황이었다. Data Augmentation이 절실한 상황으로, 이를 타개할 방법을 찾기 시작했다.

    먼저 활용한 점은, Test Dataset을 학습에 활용하는 것이었다. 최종 Target을 제외하면, Testset의 User의 Interaction은 Label을 가지고 있으니, 이를 활용할 수 있다는 점에 착안했다. 이 방법은 Testset의 User의 특징을 학습 할 수 있다는 장점이 있었지만, Data는 약 10%의 증강효과만을 얻을 수 있었다.

    최종적으로 사용한 Augmentation 방법은, User와 TestID(문제지)를 기준으로 Sample을 구성하는 것이었다. 이렇게 하면, 각 유저가 문제지를 접한 횟수만큼 Sample을 늘릴 수 있었으며, Sample의 형태도 고르게 만들 수 있었다. 각 Sample의 마지막 Interaction이 해당 문제지의 마지막 문제가 되었고, 이런 형태를 통해서 일관적인 학습을 유도할 수 있었다.

  • Team Validation Strategy 실험

    대회의 데이터는 시계열 데이터인 동시에 User와 Item을 기준으로 만들어진 Interaction 정보였다. 단순한 방법인 KFold나 Cross Validation을 사용하는 경우에는 Public LB Score와 경향성이 매우다르게 나타났다. 또한, 우리 팀은 LGBM과 같은 접근 방법도 활용하고 있었기 때문에, 다양한 접근방법이 일관적인 기준을 가질 수 있도록 설계할 필요가 있었다.

    우리 팀은 이 전략을 각각의 환경에서만 맞춘 것이 아니라, 팀단위로 전략을 수립하고 검증했다. 꽤 많은 Validation 전략을 검증하게 됐고, 최종적으로는 User의 마지막 Interaction을 Validation으로 활용하는 전략을 사용했다.

    위와 같이 정립된 Validation 전략으로, 각 실험의 비교가 가능해졌으며, 최종적으로 강건한 Solution을 개발 할 수 있었다.

  • GRU Model 실험

    Baseline으로 주어진 Code를 보다가, LSTM보다는 GRU가 이번 대회에 적합할 것이라는 생각이 들었다.

    먼저, 현재 문제가 되는 상황은 과적합이었다. 과적합을 막기 위해 Model의 Size를 줄일 필요가 있었고, GRU는 LSTM에 비해 Model이 가벼운 만큼 이에 적합하리라 생각했다.

    또, 우리는 Input Data의 Sequence가 길지 않다는 특징이 있다. 이런 형태를 고려했을 때 Long Time을 고려하는 State는 필요 없다고 생각되었고, GRU가 적합하리라 생각했다.

    실제로, LSTM에서 GRU로 바꾼 것 만으로 성능 향상을 확인할 수 있었다.

  • Causal Convolution Model 실험

    위 아이디어와 더불어서, 짧은 시계열 Data의 특징 추출을 더 잘할 수 있는 방법을 고려하게 됐다.

    Interaction의 Time Step을 기준으로 Convolution 연산을 수행하면, 특정 길이만큼의 과거의 정보를 고려하여 특징을 추출할 수 있으리라 생각했다.

    기존의 Conv Layer가 양옆으로부터 연산을 수행하는데, 우리가 원하는 형태로 연산할 수 있도록 Padding을 앞쪽에만 주도록 설계했다. 이를 통해 Causal Conv 연산을 구현했다.

    Attention Layer를 추가할 때마다 과적합이 되던 문제를 해결할 수 있었고, 미래정보가 같이 연산되지 않는다는 확신을 가지고 실험을 진행할 수 있었다.

  • ConvGRU Model 구현 및 변형 실험

    Causal Convolution Model의 성과를 기반으로 다양한 형태의 Model을 구현하고 실험했다. Causal Conv 연산을 통해 Sequential Data의 특징을 잘 추출할 수 있었으니, 이를 다시 Input으로 활용하고자 했다.

    앞서 성능이 좋았던 GRU를 이후에 추가하여, 연산하도록 했다. 단순한 구조임에도 불구하고 단일 모델로 가장 높은 성능을 낼 수 있었고, 이에 Activation Function이나 Skip Connection 연산 등을 수정해가며 실험을 진행했다.

  • Parallel Operation Model 구현 및 변형 실험

    위 Model은 Causal Convolution의 Output을 GRU의 Input으로 활용하는 방법이었는데, 이번에는 두 Module로부터 각각의 Vector를 뽑아 활용하는 방법을 고안했다.

    Embedding Vector를 Input으로 활용하여 Output을 얻었고, 이를 Concat하거나, Sum하는 방식으로 특징을 추출했다.

    이렇게 얻은 Vector를 그대로 Dense Layer를 통해 예측하도록 하기도 했고, Attention Layer를 한 번 더 통과시키기도 했다.

    병렬형태로 연산하는 Model이 앞선 모델보다 좋은 성능을 보였고, 팀내 단일모델 최고 성능을 기록할 수 있었다.

    이후, 이를 토대로 하여 다양한 변형 Model을 만들었고, 최종 Solution에 활용할 수 있었다.

  • Multi Task Learning Model 구현 및 실험

    Item 즉 문제는 시간의 흐름에 따라 특징이 변화하지 않는다는 생각이 들었다. 이에, User와 Item은 따로 Embedding Vector를 구해야한다고 생각했고, 이를 구현하는 것은 어렵지 않았다. Item Embedding Vector가 Item의 특징을 더 잘 표현할 수 있도록 하고 싶었고, 이 방법으로 Multi Task Learning Branch를 구성하게 되었다.

    Multi Task Learning을 위해선 해야할 일이 많았다. 이를 위한 GT를 만들어야 했으며, 출력의 형태를 바꾸고, 해당 출력으로부터 Loss를 얻어야 했다. GT로는 난이도 Feature를 따로 구성하여 만들었으며, 20개의 Class를 예측하는 형태로 구성했다. 이에 적합한 구조로 Code를 개선하게 되었다.

    Model 구조는 앞선 모델과 다를 수 밖에 없었는데, User의 특징 정보와 Item의 특징 정보를 단순히 Concat하는 것이 옳지 않다고 생각했기 때문이다. 이에, Attention 연산을 사용하였고, 두 Vector의 연산으로 Interaction 전체의 Embedding을 구하고자 했다. 위 방법만을 사용하니, 정보의 손실이 많아졌고, 실제로 성능 하락의 이슈가 생겼다. 이를 방지하기 위해 Skip Connection 연산을 추가하니 어느정도의 성능이 회복되었다.

  • Ensemble 전략 실험

    마지막 날에는 다같이 모여서 Ensemble 전략을 수립했다. 다양한 방법을 사용했는데, 최종적으로는 우리 팀만의 Custom Ensemble로 성능을 올릴 수 있었다.

    AUC Score에 적합한 Power Ensemble이나, Stacking도 활용했지만, 두 방법은 큰 성과를 거두지 못했다.

    팀원이 제시한 방법으로, 특정 모델을 기준으로 Thread hold를 정하고 Soft Voting의 결과를 변형하는 방식을 사용했다.

P4을 통해 얻은 교훈

개선해야 할 점

  • 코드를 더 꼼꼼히 확인하는 습관이 필요하다.
  • 오류가 나지 않는다고 해서, 내가 원하는 연산이 이루어진다고 생각하면 안되겠다.
  • 컨디션과 집중력을 관리해야 한다.
  • 정형 데이터를 다루는 능력을 길러야 한다.

느낀 점

굉장히 지치고 힘들었다. 부스트 캠프에서 가장 잘 하고 싶던 Task였는데, 실제 Data를 받아보고는 큰 실망을 했다. 정형 데이터를 다루는 것이 익숙하지도 않았고, 이를 즐기지도 않았던 나는 대회 초반부터 빠르게 흥미를 잃어가고 있었다.

이와 더불어, Code를 구성하는데 치명적인 오류를 만들어냈다. Label Encoder가 활용하는 Map을 건드리는 바람에 Inference가 엉망이 된 것이었다. 처음에는 Validation의 문제겠거니 하고 팀단위로 이를 검증했는데, 내 Code에서만 이상하게 경향성이 깨지는 것이었다. 이를 발견하는데까지 약 1주가 걸렸고, 그동안 실험의 진척도 없었으며, 에너지만 크게 잃고 있었다.

이번 대회는 순전히 나의 불찰과 실수로 인해 좋은 결과를 얻지 못한 것 같아 속상하다. 여태 좋은 결과만 얻어서인지, 자만심에 빠져있던 것도 사실이었다.

또, 이번 대회에서도 논문을 제대로 읽는 연습을 하지 못했다. 자꾸 쉬운 방법으로 아이디어를 얻고 검증하려는 것 같은데... 이는 정말 빨리 고쳐야 할 버릇인 것 같다.

아무튼, 이로써 부스트 캠프를 마무리하게 됐다. 정말 느낀 것도 많고 얻은 것도 많은 시간이었다.

'네이버 부스트캠프 AI Tech' 카테고리의 다른 글

[P4] Day 95 (21.06.15)  (0) 2021.06.26
[P4] Day 94 (21.06.14)  (0) 2021.06.26
[P4] Sunday 13 June (21.06.13)  (0) 2021.06.26
[P4] Saturday 12 June (21.06.12)  (0) 2021.06.26
[P4] Day 93 (21.06.11)  (0) 2021.06.26

+ Recent posts