본문 바로가기
CS/MachineLearning

케글 메달리스트가 알려주는 캐글 노하우

by Diligejy 2023. 10. 14.

https://link.coupang.com/a/bcwWoT

 

캐글 메달리스트가 알려주는 캐글 노하우

COUPANG

www.coupang.com

여러 명의 저자가 공동 집필하고 각자 파트별로 집필한 만큼, 중복되는 내용도 가끔씩 나온다.

 

 

밑줄긋기

p.34

Code Competition은 Simple Competition가 비교했을 때 몇 가지 장점이 있습니다.

 

첫째, 점수 계산에 사용될 테스트 셋을 참가자에게 공개하지 않고 컴페티션을 진행할 수 있습니다. 정답 파일을 만들기 위해서는 테스트 셋에 대한 예측이 필요하기 때문에 일반적으로는 정답을 제이한 테스트 셋을 참가자들에게 공개합니다. 다만, 이 과정에서 테스트 셋의 정보를 모델 생성에 활용하거나 테스트 셋의 분포를 미리 파악해 테스트 셋에 적합한 솔루션을 만들 수 있습니다. 이러면 테스트 셋에 대한 점수는 높게 나올지 몰라도 일반화(Generalization) 측면에서 좋지 못한 솔루션이 만들어질 수 있으므로 결코 좋은 솔루션이라고 볼 수 없습니다. 이런 일을 방지하기 위해 Code Competition에서는 서브미션 제출 시 내부 컴퓨터에서 점수를 계산할 때 테스트 셋을 비공개 데이터로 교체합니다. 이렇게 하면 테스트 셋을 공개하지 않고도 테스트 셋에 대한 예측을 만들 수 있습니다.

 

둘째, 제출한 코드의 전체 수행 시간에 제한을 둘 수 있습니다. 문제의 정답을 잘 맞히는 것도 중요하지만, 실제 환경에 적응하기 위해서는 솔루션의 수행 시간 효율도 매우 중요합니다. Simple Competition은 단지 정답 파일만 제출하면 되므로 그 정답 파일이 만들어지기까지 전체 예측 시간이 얼마가 소요되든지 상관이 없습니다. 반면, Code Competition은 제출한 노트북의 런타임에 제한을 걸 수 있으며, 만약 제출한 노트북의 실행 시간이 제한 시간을 넘긴다면 그 제출은 서브미션으로 인정되지 않습니다. 참고로 제한 시간은 컴페티션마다 다를 수 있으므로 각 컴페티션 페이지의 Overview > Code Requirements에 있는 정보를 확인해야 합니다.

 

이러한 장점으로 Code Competition은 최근 높은 비중으로 채택되고 있습니다. 다만 참가자 입장에서는 제출 난이도가 상승한 셈입니다. 코드를 작성할 때는 새로운 테스트 셋이 적용된다는 것을 감안해서 에러가 나지 않도록 고려해야 함은 물론 제한 시간을 넘지 않도록 유의해야 합니다. 무엇보다도 제출한 노트북에 테스트 셋을 적용하여 재계산하므로 계산이 끝날 때까지 결과를 확인할 수 없다는 단점이 있습니다.

 

Note - 인터넷 연결 주의

 

Code Competition은 간단히 정답 파일을 제출하는 방식에 비해 새로운 데이터셋을 적용하고 제출하는 시간을 고려해야 하므로 난이도가 높은 편입니다. 심지어 부정행위 방지를 위해 제출한 캐글 노트북 환경은 인터넷 연결이 불가능하도록 기본 설정됩니다. 만약 제출한 코드에 인터넷을 연결해야 하는 경우, 예컨대 사전 훈련 모델(Pretrained Model)을 사용하는 코드 등이 있다면 사용할 수 없습니다. 

 

하지만 이를 해결할 방법이 전혀 없는 것은 아닙니다. 숙련된 캐글러들은 인터넷 연결 없이 캐글 플랫폼의 기능을 활용해 이 문제를 해결하고 있습니다. 

 

p.46~47

간단한 예를 하나 들어보겠습니다. 한자(漢字)의 글씨체를 자동으로 인식하는 시스템을 개발해야 한다고 생각해봅시다. 이에 대해 다음과 같이 조금 막연하게 문제를 정의해볼 수 있습니다.

 

글씨체 이미지를 정답 클래스로 예측하는 머신러닝 모델을 개발한다.

 

이 문제 정의로는 그저 필체 인식을 위한 딥러닝 모델을 구성하고 주어진 데이터로 학습시키도록 설계하기만 해도 본래 목적을 어느 정도 달성한 것으로 볼 수 있습니다. 그런데 한자의 글자 수가 워낙 다양하고 많다 보니 특정 글자는 글씨체 데이터가 충분하지 않을 수 있다고 유추해볼 수 있습니다. 이런 아이디어와 질문은 보통 자신이 평소에 알고 있던 지식과 경험, 그리고 데이터 분석 과정에서 자연스럽게 떠오르는 생각으로부터 출발합니다. 앞서 정의했던 문제에 유추한 생각을 더해 다음과 같이 문제를 더 구체적으로 정의해볼 수 있습니다.

 

글씨체의 견본이 부족한 글자도 잘 예측할 수 있는 모델을 만들어야 한다.

 

이 문제 정의로는 '글씨체의 견본이 부족한 클래스'를 해결하기 위한 방안을 마련해야 하며, 모델을 평가할 때도 정의한 조건에 맞게 결과에 잘 반영되었는지 확인하기 위한 평가 방식을 구성해야 할 것입니다.

 

문제 정의가 중요한 이유는, 위 경우처럼 글자를 잘 분류해야 한다는 목적은 동일하지만 더 나은 결과를 위해 내가 데이터를 주고 이해한 내용을 바탕으로 문제를 정의함으로써 그에 따라 해결 방향을 정하는 데 도움을 주기 때문입니다.

 

p.47~49

문제 정의는 구체적으로 어떤 과정으로 이루어지는 것이 좋을까요? 간단히 살펴보겠습니다.

 

(1) 문제 해결이 필요하게 된 배경은 무엇인가?

 

컴페티션의 문제가 발생한 배경을 이해하는 것이 문제 정의를 위한 근거를 찾는 데 도움이 됩니다. 이 과정을 진행하면서 자연스럽게 문제와 관련한 도메인 지식을 공부하게 됩니다. 문제 정의를 잘 하기 위해서는 도메인에 대해 이해하고, 도메인의 특성을 잘 파악하는 것이 무엇보다 중요합니다. 

 

EDA를 하는 이유는 이를 파악하고 문제 정의 내용이 합당한 것인가를 확인하려는 목적이 큽니다. EDA와 문제 정의를 반복하면서 내가 풀어야 할 문제를 점점 구체화할 수 있습니다.

 

배경 정보를 가장 잘 설명하는 곳이 바로 Overview 페이지입니다. Overview의 내용을 토대로 도메인 지식과 관련한 정보를 수집하고 컴페티션을 전체적으로 이해하는 과정을 거치면서 문제를 정의할 기반을 만드는 것이 이 단계에서 해야 할 일입니다. 

 

(2) 무엇을 만들어야 하는가?

 

문제 발생 배경을 이해하면서 컴페티션이 제시하는 목적을 알았다면, 다음으로는 그 목적에 부합하도록 무엇을 만들어야 하는지 구체적으로 설정해야 합니다. Overview의 'Evaluation' 페이지와 Data의 'Description' 페이지를 보면 이 컴페티션에서 최종적으로 어떤 결과를 만들어야 하는지 명시하고 있습니다. 이렇게 표면적으로 드러난 문제를 두고, 도메인 지식과 EDA를 바탕으로 문제를 해결하기 위한 방법 및 방향을 설정합니다. 

 

예를 들면 다음과 같이 표현할 수 있습니다.

 

- 데이터의 ~의 피처(Feature)를 사용해서 ~을 해결하는 ~라는 결과를 만들겠다.

- ~의 과정에서 ~을 개선할 수 있는 ~을 만들겠다.

 

방금 전에도 언급했지만 자신의 경험과 도메인 지식에 따라, EDA에서 관찰한 결과를 토대로 구체적으로 설정한 문제에 따라, 표면적으로 고정된 문제의 해결 방법이 다양한 루트로 갈라질 수 있습니다. 

 

(3) 필요한 것과 얻을 수 있는 것은 무엇인가?

 

현재 자신의 힘으로 만들 수 있는 것과 아직 잘 모르는 것을 구분하는 일도 매우 중요합니다. 공부해야 하는 부분과 그렇지 않은 부분을 헷갈리지 않게 표시해두면 일의 우선순위를 정할 수 있고 일정 관리에도 도움이 됩니다. 

 

이를 잘 정리했다면, 앞으로 컴페티션을 선택할 때 각 컴페티션이 현재 자신에게 어느 정도 난이도인지 전보다 수월하게 가늠할 수 있습니다. 만약 예상 난이도가 높다면, 컴페티션에 투자하는 시간에 공부 시간을 추가할 수 있습니다. 약간 색다르게 생각해본다면, 애당초 달성하고 싶은 목적을 축소하거나 원하는 요소를 선택할 수도 있습니다. 예컨대 목표를 꼭 리더보드 순위로 설정하는 것이 아니라,

 

- 선택한 컴페티션에서 사용하는 데이터 도메일을 원하는 대로 분석해보겠다

- 여기서 사용할 딥러닝 라이브러리를 아직 잘 모르니 한번 경험해보겠다.

 

라는 식으로 말입니다. 이렇게 자신이 얻을 수 있는 것을 확실히 결정하는 것도 중요합니다.

 

정리하면, 데이터 및 도메인에 대한 이해가 높을수록 문제를 올바르게 결정할 확률이 높아지며 좋은 결과로 이어질 확률도 높아집니다. 또한, 컴페티션을 진행하는 도중에 다른 캐글러로부터 새로운 힌트를 얻을 수도 있습니다. 이런 과정을 거치면서 자신이 맨 처음에 정의했던 문제가 어느 순간 점점 다양한 가짓수로 불어날 것입니다. 

 

p.49~50

어떻게 해야 필사를 제대로 할 수 있을까요? 

 

첫째, 다른 사람의 코드나 자료를 공부할 때는 무엇을 얻기 위함인지 그 목적을 명확히 정하고 시작합니다. 여기서 중요한 것은 처음부터 크고 추상적인 목적을 생각하는 것이 아니라 풀기 쉬운 간단한 하위 문제로 쪼개는 것입니다. 이를 위해서는 자신이 현재 무엇을 할 수 있고 무엇을 모르는지 알고 있어야 합니다. 앞서 예시로 언급했던 '한자 글씨체를 인식하는 문제'를 놓고 생각해보겠습니다.

 

한자 글씨체 이미지를 딥러닝 모델을 사용해 인식기를 만든다.

 

이처럼 하나의 큰 목적으로 설정하지 말고, 간단한 하위 문제로 쪼갭니다.

 

- 데이터셋의 이미지를 불러와 확인하는 방법은 무엇일까? 

- 이미지 사이즈가 너무 큰데, 작게 만들어서 관리할 방법은 없을까? etc

 

경험이 적을수록 낮은 난이도의 하위 문제들이 많이 만들어질 것이고, 점차 숙련될수록 익숙해진 하위 문제들이 간단한 구성으로 압축될 것입니다.

 

둘째, 필사를 하다가 불현듯 떠오르는 의심과 질문이 있다면 이상한 내용이라도 상관없으니 버리지 말고 가감 없이 드러냅니다. 필사 코드에 따로 설명되지는 않았지만 코드를 보면서 추가로 조사해보고 싶은 피처(Feature)가 떠오를 수도 있고 분석 내용이 처음에 예상했던 것과 다르게 나타날 수도 있습니다. 예를 들면,

 

- 견본 데이터가 아예 없는 클래스도 있지 않을까?

- 혹시 정답이 틀린 클래스는 없을까?

- 이미지 확장자가 여러 가지로 되어 있는데, 이미지를 읽을 때 문제가 생기지 않을까? etc

 

이처럼 문제를 다양한 관점에서 살필 수 있고 문제 해결의 힌트도 얻을 수 있습니다. 처음이라 잘 생각나지 않는다면 코드를 잠시 멀리하고 종이와 펜을 꺼내 마인드맵을 그려보는 것도 좋습니다. 

 

이렇게 함으로써 내가 필사하는 코드는 내가 공부해야 할 목적이 아니라 활용해야 할 재료로 그 성격이 바뀌게 됩니다. 단순히 처음 보는 코드를 이해하는 것을 넘어서 다음에는 내 손으로 직접 이렇게 멋진 코드 자료를 만들고 싶다고 생각하면서 말입니다. 자신의 질문으로 만들어낸 문제를 해결해나가는 경험은, 재미는 물론 점점 발전할 수 있는 계기가 되어줄 것입니다. 이는 앞서 소개한 '문제 정의 및 이해' 단계에서 해야 하는 내용과 다를 게 없습니다. 

 

궁극적으로 우리가 추구해야 할 목표는 자신이 공감할 수 있는 문제를 스스로 설정할 수 있고, 이를 설명하고 코드로 표현하는 데 자유로우며, 새로운 데이터셋과 도메인을 마주하더라도 지금까지 배운 것을 활용해 스스로 결과물을 만들어낼 수 있도록 자신의 능력을 가꾸는 일입니다.

 

p.60

GPU는 특히 주간 사용 시간 제한량(Quota)이 있습니다. 계정당 1주일간 사용할 수 있는 시간이 있고, 제한량을 모두 사용하면 1주일 뒤 리셋될 때까지 사용할 수 없습니다. 제한량을 절약하기 위해 보통 CPU 환경에서 코드를 작성한 후 에러가 발생하는지 여부만 판단한 뒤에 GPU를 할당받고 실행합니다. GPU 세션을 유지하는 동안은 제한량이 계속 소모되므로, 사용하지 않을 때는 세션을 종료하는 것이 좋습니다.

 

p.97~98

AUC(Area Under the  Curve)는 이진 분류 대회, 그리고 평가 함수로 타깃 분포가 불균형한 경우 많이 사용합니다. AUC를 이해하기 위해서는 먼저 ROC 곡선에 대해 이해해야 합니다.

ROC 곡선은 x축이 False Positive Rate, y축이 True Positive Rate로 구성된 곡선 그래프(그림의 빨간색 점선)입니다. 

 

- False Positive Rate : 실제 False인 데이터 중 모델이 True라고 예측한 비율 (1 - False인 데이터 중 모델이 False라고 예측한 비율)

- True Positive Rate : 실제 True인 데이터 중 모델이 True라고 예측한 비율

 

즉, True를 True로, False를 False로 얼마나 잘 맞추는지 비교하여 모델의 성능을 평가합니다.

 

ROC 곡선의 각 포인트는 특정 임곗값에서 분류 모델의 성능을 의미합니다. 다시 말해 모든 임계값에서의 서어능이 모여 ROC 곡선을 이룹니다. 하지만 이러한 곡선 분포를 명확한 수치로 비교하기는 어렵습니다. 따라서 AUC라는 값을 도입해서 성능을 수치화합니다. AUC는 ROC 곡선의 밑면적(그림의 분홍색 면적)을 의미합니다. 예측을 잘할 경우 곡선은 빨간색 화살표 방향으로 올라가며 1에 가까워지고, 예측을 잘하지 못할 경우 곡선은 회색 화살표 방향으로 이동하며 0.5에 가까워집니다. 

 

p.99

캐글에서는 데이터가 어떻게 만들어졌고 공개 및 비공개 테스트 데이터가 어떻게 분포되어 있는지 파악하는 것이 매우 중요합니다. 데이터를 만든 방법을 알게 되면 역으로 데이터를 생성해볼 수 있고 교차 검증(Cross Validation)을 시도하는 전략을 세울 수 있습니다.

 

p.106

주의할 점은, 고유한 값이 작다고 무조건 범주형 변수로 취급하면 안 된다는 것입니다. 데이터가 익명화되어 있기 때문에 이러한 방법을 사용했는데, 주로 주최 측에서 제공한 데이터 명세서를 활용하거나 알고리즘에 범주형 변수로 사용했을 때 성능 비교 등을 통해서 결정합니다.

 

p.109

EDA 과정을 요약하면 다음과 같습니다.

 

- 데이터가 어떤 형식으로 이루어졌는지 살펴봅니다. 이 대회의 데이터는 열 안에 List나 Json형태의 데이터가 없지만, 이런 정보가 들어 있다면 이 안에서 어떤 정보를 추출할 수 있는지 나열해보는 것도 좋습니다.

 

- 정답 값의 비율을 확인합니다. 정답의 불균형 여부를 확인한 뒤 추후 이 점을 고려하여 모델을 구성해야 합니다.

 

- 정답 값에 누출이 없는지 확인합니다. 캐글에서는 주최자가 의도하지 않은, 문제에 발생한 누출은 암묵적으로 공유하고 있습니다. 이러한 것을 빠르게 캐치한다면 디스커션이나 노트북에서 좋은 메달을 받을 수 있습니다. 

 

- NULL 값을 확인합니다. 알고리즘에 따라 NULL 값을 필수로 채워야 할 수도 있습니다. NULL 값은 단순히 평균, -999 같은 값으로 채우기보다는 이 NULL이 왜 생성됐고, 어떤 의미인지 먼저 파악하는 것이 좋습니다. 때로는 NULL 값의 유무가 좋은 정보가 될 수도 있습니다.

 

- 범주형 변수와 수치형 변수를 나누어서 생각합니다. 각 특성에 따라 전처리하는 방법이 다르기 때문에 EDA 단계에서 구분하는 것이 좋습니다.

 

- 피처는 정답 값과 연관지어 생각하는 것이 좋습니다. 특정 범주형 변수에 정답 값의 분포가 몰려 있거나, 수치형 변수의 분포를 살펴봤을 때 정답 값별로 분포가 다르면 좋은 변수가 될 가능성이 크기 때문입니다.

 

p.109

스태킹(Stacking)이란 여러 알고리즘이 예측한 결과를 입력으로 받아 재학습하여 결과를 도출하는 방법입니다.

 

p.110

OOF라는 이름은 Out of Fold라는 뜻으로, 사이킷런의 KFold를 사용할 때 K값에 따라 여러 폴드가 만들어지는데, 이를 예측한 결과를 말합니다. 팀으로 대회를 진행할 때 OOF 결과를 모아달라고 하기도 하는데, 이때는 학습, 테스트 예측 결과를 전달해달라는 뜻입니다.

 

 

p.294~295

판다스 라이브러리로 데이터를 로드한 후 head 함수로 처음 n개의 데이터를 확인하 고, sample 함수로 데이터에 존재하는 다양한 케이스를 랜덤으로 확인합니다. 그 옆에 함께 보고 싶은 열을 선택해서 같이 확인할 수 있습니다. 처음 데이터를 확인하기 위해 가장 보편적으로 쓰는 방법입니다.

 

이러한 방법으로 텍스트와 그 타깃값을 눈으로 보면서 텍스트와 타깃값 사이에 어떠한 연관성이 있는지 살펴볼 수 있고 텍스트와 특수문자, 이모티콘 URL, 또는 생각하지 못한 이상한 글자는 없는지 등 데이터의 품질을 체크할 수 있습니다. 이를 토대로 앞으로 분석을 진행할 태스크를 어떻게 진행해야 할지 미리 계획을 세울 수도 있습니다.

 

 

 

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."

댓글