[개인 경진 대회] Kaggle Playground Series S6E6 연구 기록 3일차

2026. 6. 16. 11:38·6. 경진 대회 (kaggle, dacon 등)/6-1 연구 및 개선 기록

안녕하세요. 이번 글에서는 Kaggle Playground Series S6E6 대회에서 진행한 세 번째 연구 기록을 정리하겠습니다.

 

이전 글 이후의 시작점은 public score 0.97141이였습니다. 그때까지는 모델 확률과 local evidence를 이용해서 row-level patch 후보를 만들고, 실제 public leaderboard feedback을 보면서 어떤 row가 점수에 영향을 주는지 확인했습니다.

 

하지만 0.97141 이후에는 비슷한 방식의 후보를 계속 제출해도 점수가 거의 동일!!

 

이번 글의 핵심은 다음이다.

  1. 0.97141 이후 기존 row-level patch 방식이 왜 막혔는지
  2. 상위권 notebook과 submission bank가 어떤 구조를 쓰는지
  3. 공개 output CSV를 그대로 쓰지 않고 연구 신호로만 해석한 과정
  4. public+generalization 후보를 0.97207까지 올린 과정
  5. 그 이후 micro flip이 다시 한계에 닿았다는 결론
  6. 앞으로는 hard-label CSV 수정이 아니라 OOF/proba 기반 일반화 모델 개선으로 가야 한다는 점

1. 0.97141 이후 문제

처음에는 STAR→GALAXY, QSO→GALAXY, GALAXY→STAR 같은 class transition 후보를 계속 만들면 점수가 더 올라갈 수 있을 것이라고 생각했다.

하지만 실제 제출 결과는 대부분 같았다.

제출 파일 Public Score
transition_QSO_to_GALAXY_top_01.csv 0.97141
transition_QSO_to_GALAXY_top_03.csv 0.97141
feedback_replace_rank09_with_rank17.csv 0.97141

 

이런 결과가 반복되면서 중요한 사실이 드러났다.

  • 현재 가지고 있는 순수 모델 확률만으로는 public test에서 더 맞출 row를 안정적으로 고르기 어렵다.
  • row를 몇 개 바꾸는 방식 자체가 틀린 것은 아니지만, 기존 LightGBM/CatBoost ensemble과 local evidence만으로는 더 이상 새로운 정보를 만들지 못하고 있었다.

이때부터 문제를 다시 나눠서 보기로 했다.

  1. 순수 모델 generalization 성능
  2. public leaderboard를 움직이는 submission-level 신호

두 목표를 섞으면 판단이 흐려진다. 순수 모델 성능은 OOF balanced accuracy로 봐야 하고, public leaderboard용 후보는 public feedback과 submission bank 구조를 따로 봐야 한다.


2. 상위권 notebook을 보면서 확인한 것

상위권 notebook들을 확인해보니, 단순히 train.csv 하나로 모델을 학습해서 제출하는 구조만 있는 것이 아니었다. 특히 일부 notebook은 다음과 같은 input을 함께 사용했다.

  • XGB 모델의 OOF / test prediction
  • NN 모델의 OOF / test prediction
  • RealMLP 모델의 OOF / test prediction
  • CatBoost 모델의 OOF / test prediction
  • 여러 submission.csv

처음에는 이 구조가 이상하게 보였다. 대회는 모델을 만들어서 일반화 성능을 겨루는 것인데, 왜 이미 만들어진 submission이나 다른 사람의 prediction file을 input으로 쓰는지 의문이 들었다. 정리하면 이유는 다음과 같았다.

  • Kaggle notebook에서 공개 dataset으로 공유된 OOF/test prediction은 다른 참가자도 접근 가능한 외부 데이터처럼 사용할 수 있다.
  • 상위권에서는 여러 모델이 만든 test probability와 OOF probability를 ensemble 재료로 사용한다.
  • final submission CSV 하나만 있는 것보다 OOF와 test proba가 함께 있을 때 훨씬 더 재현 가능한 ensemble을 만들 수 있다.

즉, 중요한 차이는 최종 CSV만 베끼는 것과 공개된 모델 예측을 ensemble 재료로 쓰는 것이다. 나는 이 둘을 분리해서 보기로 했다.

  • 최종 output CSV를 그대로 제출하면 연구가 아니라 복사에 가깝다. (근데 보니깐 복사해서 제출하는 사람들도 많은 거 같다...왜지...?)
  • OOF/test probability는 모델이 어디서 확신했고 어디서 흔들렸는지 볼 수 있으므로 ensemble 연구 재료가 된다.

3. submission bank를 따로 구축한 이유 (핵심)

기존에는 내가 만든 모델과 현재 anchor submission 사이의 차이만 봤다.

하지만 상위권 파일 구조를 보면서 관점을 바꿨다. 여러 공개 submission을 모으면 각 row에 대해 다음 정보를 얻을 수 있다.

  • 이 row에서 참가자들이 얼마나 같은 label을 예측했는가
  • 상위 점수 submission들은 어떤 label을 더 자주 선택했는가
  • 낮은 점수 submission과 높은 점수 submission이 갈리는 row는 어디인가
  • 특정 class transition이 실제로 public score와 관련이 있는가

그래서 external_preds 폴더에 공개 submission bank와 prediction file을 모아 분석했다.

항목 값
hard-label submission 94개
probability source 6개
anchor file 0.97183.csv
design matrix shape 94 × 10792
raw flip candidates 839개
usable flips 749개

 

여기서 anchor는 0.97183.csv였다. 이 파일은 우리가 직접 만든 순수 모델은 아니지만, 공개 bank 안에서 가장 강한 기준점으로 사용할 수 있었다.

중요한 점은 이 anchor를 그대로 복사하려는 것이 아니라, submission bank 내부에서 어떤 row가 점수 차이를 만들었는지 역추정하려고 했다는 점이다.

4. ridge 기반 row contribution 추정

submission bank에는 각 파일의 public score와 각 row의 label 선택이 있다. 이를 이용하면 이런 질문과 가설을 세울 수 있다.

어떤 row의 어떤 label 선택이 높은 public score submission에서 자주 등장했는가?

 

물론 public score는 전체 test 중 public split에 대해서만 계산되고, rounded score만 보인다. 그래서 row 하나의 진짜 정답을 알 수는 없다. 하지만 많은 submission을 모으면 약한 통계 신호를 만들 수 있다. 이번에는 ridge regression을 이용해서 row-level flip 후보를 추정했다.

구현한 스크립트는 scripts/build_bank_ridge_flip_candidates.py이다.

핵심 흐름은 다음과 같다.

  1. 공개 submission bank를 읽는다.
  2. 가장 높은 점수의 anchor를 잡는다.
  3. anchor와 다른 label을 선택한 row를 feature로 만든다.
  4. 각 submission의 public score 차이를 target으로 둔다.
  5. ridge regression으로 row-level contribution을 추정한다.
  6. 모델 probability source와 bank vote support를 함께 사용해 후보를 거른다.
  7. 여러 후보 파일을 만들고, 그중 안정적으로 보이는 후보를 선택한다.

이 방식은 정답을 아는 것이 아니다. public leaderboard의 약한 feedback과 submission bank의 agreement를 이용해 어떤 row가 public split에서 중요할 가능성이 있는지 추정하는 방식이다.


5. 0.97207 후보 생성

여러 후보 중 최종적으로 선택한 public+generalization 후보는 artifacts/bank_ridge_flip_v5/v5_voted_ensemble.csv였다.

이 파일의 특징은 다음과 같다.

항목 값
anchor 대비 변경 row 170개
GALAXY 156,934
QSO 51,457
STAR 39,044

 

실제 제출 결과는 다음과 같았다.

제출 파일 Public Score
final_public_generalization.csv 0.97207

 

이 결과로 0.97141 plateau는 깨졌다.

 

다만 여기서 착각하면 안 된다. 이 점수는 순수 모델 하나의 성능이 아니다. 공개 submission bank와 모델 probability를 함께 사용한 public+generalization track의 결과이다.

 

그래서 최종 후보도 두 개로 분리했다.

Generalization track: artifacts/final_submissions/final_generalization_model.csv
Public+generalization track: artifacts/final_submissions/final_public_generalization.csv

순수 모델 track은 여전히 중요하다. public score만 보고 최종 제출을 고르면 private leaderboard에서 무너질 수 있기 때문이다.


6. 순수 모델 track의 현재 상태

순수 모델은 공개 submission CSV를 사용하지 않는다.

현재 기준은 LightGBM과 CatBoost의 OOF/test probability를 조합한 pure ensemble이다.

현재 OOF 결과는 다음과 같다.

모델 OOF balanced accuracy
LightGBM 0.964320
CatBoost 0.964947
unweighted ensemble 0.965489
optimized pure ensemble 0.966345

 

최적 조합은 다음과 같았다.

항목 값
LightGBM weight 0.48625
CatBoost weight 0.51375
GALAXY bias 0.79879
QSO bias 1.06739
STAR bias 1.13382

이 순수 모델의 public 제출 점수는 bank 기반 후보보다 낮았다.

 

제출 파일 Public Score
generalization_model_baseline.csv 0.96688

 

하지만 이 파일의 의미는 public leaderboard 점수가 아니다. train/test data만으로 재현 가능한 baseline이고, private/generalization 관점에서 기준점이다.

public+generalization 후보와 순수 generalization 후보의 test prediction 차이는 3335 rows였다.

이 차이가 바로 앞으로 연구해야 할 영역이다. public bank가 맞춘 row를 순수 모델은 왜 다르게 봤는지 설명할 수 있어야 한다.

7. 더 높은 참고 output은 어떻게 봐야 하는가

중간에 0.97209, 0.97214 수준으로 보이는 참고 output CSV도 확인했다.

여기서 원칙을 명확히 했다.

  • 이 파일을 그대로 제출하지 않는다.
  • 이 파일을 정답지처럼 사용하지 않는다.
  • 우리 모델과 무엇이 다른지 분석하는 연구 신호로만 사용한다.

현재 0.97207 후보와 참고 output의 차이는 생각보다 작았다.

비교 차이 row
0.97214 reference vs current 0.97207 candidate 165
0.97209 reference vs current 0.97207 candidate 168

 

0.97214 reference와 현재 후보의 transition 차이는 다음과 같았다.

transition count
GALAXY → QSO 16
GALAXY → STAR 56
QSO → GALAXY 25
QSO → STAR 5
STAR → GALAXY 56
STAR → QSO 7

여기서 중요한 것: 현재 후보와 더 높은 참고 output의 차이는 대부분 GALAXY↔STAR 경계와 QSO↔GALAXY 경계에 있다. 즉, 성능 차이는 랜덤하게 흩어진 것이 아니라 특정 class boundary에 몰려 있다.

앞으로 해야 할 일은 이 165개 row를 그대로 따라 하는 것이 아니다. 이제 다음 질문들이 생겼다.

  • 왜 이 row들은 bank와 참고 output에서 다른 label로 가는가?
  • 우리 순수 모델은 이 row에서 어떤 probability margin을 보였는가?
  • OOF에서 비슷한 feature 구간은 어떤 class로 자주 틀렸는가?
  • spectral_type, galaxy_population, redshift, color index 기준으로 어느 subset에 몰려 있는가?

이 질문에 답할 수 있어야 진짜 모델 개선으로 이어진다.

8. 0.97207 이후 micro flip 실험

0.97207까지 오른 뒤에도 바로 멈추지는 않았다. 현재 후보 주변에서 아주 작은 row 변경을 테스트했다.

 

제출 결과는 다음과 같았다.

제출 파일 변경 row Public Score 해석
post097207_refbank_proba_top03.csv 3 0.97207 동점
02_NEXT_refbank_proba_5rows.csv 5 0.97207 동점
03_ALT_remove_ridge_tail10.csv 10 0.97206 하락
04_RESEARCH_bankproba_noref_3rows.csv 3 0.97206 하락
v5_ridge_top130.csv 40개 차이 0.97202 하락

 

결과 분석:

  • 0.97207 이후 hard-label micro flip은 포화 상태다.
  • 3~5개 row 추가 변경은 점수를 올리지 못했다.
  • tail flip 제거는 오히려 점수를 낮췄다.
  • anchor에서 너무 많은 flip을 줄이면 점수가 더 낮아졌다.

즉, 지금 단계에서 단순히 최종 CSV를 몇 줄 더 바꾸는 방식은 거의 운에 가깝다. 여기서 더 제출을 이어가면 연구라기보다 public score 도박이 될 것 같다.


9. 지금까지 정리

이번 단계에서 가장 크게 알게 된 것은 다음이다.

  1. 상위권 구조의 핵심은 최종 CSV가 아니라 OOF/test probability와 submission bank signal이다.
  2. 높은 참고 output은 복사 대상이 아니라 모델 약점을 찾는 분석 대상이다.
  3. 0.97207 이후에는 hard-label micro flip보다 OOF/proba 기반 모델 개선으로 돌아가야 한다.

더 높은 CSV가 있다고 해서 그것을 그대로 쓰면 연구가 아니다. 하지만 그 파일과 우리 모델의 차이를 분석하면, 우리 모델이 어느 feature 구간에서 틀리는지 추론할 수 있다.

이번에 확인한 차이는 대부분 GALAXY, STAR, QSO 경계에 몰려 있었다. 따라서 다음 연구는 이 boundary를 모델 학습 단계에서 다루는 방향이 되어야 한다.

10. 다음 연구 방향

다음 단계는 public CSV 미세수정이 아니라 모델 쪽이다.

  1. OOF 기반 boundary dataset 만들기
  2. pure model이 틀린 row와 bank/reference가 다르게 본 row를 feature 구간별로 비교하기
  3. GALAXY/STAR, QSO/GALAXY boundary 전용 specialist를 다시 설계하기
  4. 단순 override가 아니라 calibrated probability blending으로 연결하기
  5. external original stellar dataset을 쓸 경우 distribution shift를 따로 검증하기

이전 boundary specialist는 full OOF에서 개선되지 않았다. 하지만 그 실험은 단순 override에 가까웠다.

  • base pure ensemble probability
  • bank/ref disagreement feature
  • OOF error subset feature
  • spectral_type + galaxy_population interaction
  • redshift/color boundary feature

이 feature들을 이용해서 test row를 직접 찍는 것이 아니라, OOF에서 검증 가능한 calibration layer를 만들어야 한다.

목표는 단순히 public score를 한 번 더 올리는 것이 아니다.

  • public에서 강한 후보와 private/generalization에서 버틸 수 있는 후보를 동시에 만드는 것

현재 public best는 0.97207이고, pure model OOF 기준은 0.966345이다.

다음 연구는 이 둘 사이의 간격을 줄이는 방향으로 진행해야 한다.

11. 마무리

이번 글에서는 0.97141 이후의 연구 과정을 정리했습니다.

일단 결과는 public score는 0.97207까지 올랐습니다. 0.97207 이후에는 단순 row-level patch가 거의 막히고, 작은 후보를 더 제출해도 동점이거나 하락했습니다. 그래서 이제는 최종 CSV 수정이 아니라, OOF/probability, subset error analysis, boundary modeling으로 돌아가야 할 거 같습니다.
이 대회는 프라이빗 때 리더보드 순위가 어떻게 될 지 매우 궁금하다...

'6. 경진 대회 (kaggle, dacon 등) > 6-1 연구 및 개선 기록' 카테고리의 다른 글

[개인 경진 대회] Kaggle Playground Series S6E6 연구 (5): RealMLP 피처 뱅크 실험 기록  (0) 2026.06.19
[개인 경진 대회] Kaggle Playground Series S6E6 연구 (4) 그래프 분석편  (0) 2026.06.17
[개인 경진대회] DACON - 성균관대 멀티모달 AI 챌린지 (6): 채점 구조 역공학과 commit recovery  (0) 2026.06.15
[개인 경진 대회] Kaggle Playground Series S6E6 연구 기록 2일차  (0) 2026.06.13
[개인 경진 대회] Kaggle Playground Series S6E6 연구 기록 1일차 (현재 Public 8등)  (0) 2026.06.09
'6. 경진 대회 (kaggle, dacon 등)/6-1 연구 및 개선 기록' 카테고리의 다른 글
  • [개인 경진 대회] Kaggle Playground Series S6E6 연구 (5): RealMLP 피처 뱅크 실험 기록
  • [개인 경진 대회] Kaggle Playground Series S6E6 연구 (4) 그래프 분석편
  • [개인 경진대회] DACON - 성균관대 멀티모달 AI 챌린지 (6): 채점 구조 역공학과 commit recovery
  • [개인 경진 대회] Kaggle Playground Series S6E6 연구 기록 2일차
고니3000원
고니3000원
프로젝트의 구현 과정과 기술적 노하우를 담았습니다. AI 모델 연구와 매일의 학습 기록을 차곡차곡 공유하고 있습니다.
  • 고니3000원
    곤이의 공부 블로그
    고니3000원
  • 전체
    오늘
    어제
    • 분류 전체보기 (231)
      • 1. AI 논문 + 모델 분석 (22)
        • AI 논문 분석 (13)
        • AI 모델 분석 (9)
      • 2. 자료구조와 알고리즘 (16)
        • 2-1 자료구조와 알고리즘 (13)
        • 2-2 강화학습 알고리즘 (3)
      • 3. 자습 & 메모(실전, 실습, 프로젝트) (27)
        • 3-1 문제 해석 (4)
        • 3-2 메모(실전, 프로젝트) (14)
        • 3-3 배포 실전 공부 (7)
        • 3-4 최신 기술 분석 (2)
      • 4. [팀] 프로젝트 및 공모전 (31)
        • 4-1 팀 프로젝트(메모, 공부) (1)
        • 4-2 Meat-A-Eye (6)
        • 4-3 RL-Tycoon-Agent (3)
        • 4-4 구조물 안정성 물리 추론 AI 경진대회(D.. (4)
        • 4-5 AgentShield(보안 플랫폼) (17)
      • 5. [개인] 프로젝트 및 공모전 (25)
        • 4-1 귀멸의칼날디펜스(자바스크립트 활용) (5)
        • 4-2 바탕화면 AI 펫 프로그램 (4)
        • 4-3 개인 프로젝트(기타) (3)
        • 4-4 공모전 (9)
        • 4-5 나만의 로컬 LLM 멀티 에이전트 구축 (4)
      • 6. 경진 대회 (kaggle, dacon 등) (12)
        • 6-1 연구 및 개선 기록 (11)
        • 6-2 공유 코드 분석하기 (1)
      • 개념 정리 step1 (32)
        • Python 기초 (7)
        • DBMS (1)
        • HTML | CSS (3)
        • Git | GitHub (1)
        • JavaScript (5)
        • Node.js (5)
        • React (1)
        • 데이터 분석 (6)
        • Python Engineering (3)
      • 개념 정리 step2 (60)
        • Machine | Deep Learning (15)
        • 멀티모달(Multi-modal) (23)
        • 강화 학습 (10)
        • AI Agent (9)
        • 메디컬 이미지 (3)
      • 개인 공부 - 내가 공부하고 싶은 모든 것 (3)
        • 1. 인프라 (2)
        • 2. 자율주행 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Notion-포트폴리오
    • Github
  • 공지사항

    • 나의 핵심 가치
  • 인기 글

  • 태그

    Ai
    프로젝트
    알고리즘
    Vision
    Python
    paddleocr
    pandas
    자료구조
    Ollama
    ViT
    파인튜닝
    transformer
    공모전
    연구
    강화학습
    인공지능
    llm
    Agent
    Lora
    파이썬
    구현
    github
    OCR
    RAG
    학습
    API
    데이터분석
    전처리
    자바스크립트
    논문 리뷰
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.5
고니3000원
[개인 경진 대회] Kaggle Playground Series S6E6 연구 기록 3일차
상단으로

티스토리툴바