
경마 AI 개발 기록 #26 역설적인 필터링: 인기마의 '부진'을 감지하여 기대치의 사각지대를 메우다
요약
경마 예측 AI 개발 과정에서 인기마의 부진을 감지하는 '부진 모델' 설계와 필터링 전략을 다룹니다. 모델 구현 과정에서 발생한 테스트 예측 버그, 학습의 비결정성, 소표본 데이터의 변동성 문제를 분석합니다.
핵심 포인트
- 인기마의 부진을 감지하여 기대치의 사각지대를 메우는 필터 모델 설계
- 기존 모델의 입력층을 오염시키지 않는 특징량 공간 분리 패턴 적용
- 테스트 예측 단계에서 필터가 적용되지 않는 구조적 버그 식별
- LightGBM의 비결정성이 Optuna 최적화에 미치는 영향 분석
- 소표본 데이터 사용 시 발생하는 ROI의 극심한 변동성 문제 확인
1. 개요
지난 회차에서는 예측 공간의 '통치'로서 ModelConfig와 feature_spaces를 도입하여, 랭킹 모델과 TOP3 모델을 통합한 멀티 모델 전략을 확립했습니다.
이번에는 복병마(anauma) 감지와 대조되는, 인기마의 침몰을 감지하는 **"부진 모델(underperformance model)"**의 신설과, 그 필터링 전략에서의 시행착오 프로세스를 상세히 기술합니다. "실력은 분명히 있을 인기마가 기대를 저버리고 마권권 밖으로 밀려나는(부진하는)" 케이스를 모델로 감지하여, 기대치의 사각지대를 메우는 것을 목적으로 합니다.
2. 구현 내용 (Plan, Do)
이번 개발에서는 랭킹에 스코어를 가산하여 순위를 왜곡하는 것이 아니라, **기대치가 낮은 말을 걸러내는 "filter"**로서 부진 모델을 설계했습니다.
2-1. 타겟 정의와 샘플 가중치
부진의 정의를 "인기 3위 이내의 말이 5위 이내에 들지 못하는 케이스"로 설정하고, 다음과 같은 사양으로 학습을 진행했습니다.
- 목적 변수 (Target):
is_underperform = (rank > 5)로 정의한 이진 분류. - 샘플 웨이트 (Sample Weight):
popularity <= 3인 인기마에 대해high_pop_weight=5.0을 부여. - 클래스 불균형 (Class Imbalance): 정례(착외)가 약 63%로 다수파가 되기 때문에, 의도적으로
scale_pos_weight는 사용하지 않고 인기마 식별에 특화시켰습니다.
2-2. 예측 파이프라인으로의 통합
부진 모델의 출력을 "제외 임계값 (Percentile)"으로 취급하여 전략층에 포함시켰습니다.
- 필터링 로직 (Filtering Logic):
부진 예측 스코어(rank_underperform)가 높은 말부터 순차적으로 제외합니다. 구체적으로는 아래 식과 같이 기대치 계산 전 단계에서 후보에서 제외합니다.
2-3. 특징량 공간의 분리
지난 회차(제25화)에서 확립한 "예측 공간의 통치" 설계 패턴에 따라, 부진 모델 전용 특징량 공간(get_feature_columns_underperform)을 정의했습니다. 이를 통해 기존의 랭킹 모델이나 복병마 모델의 입력층을 오염시키지 않고, 신규 모델을 "플러그인"으로서 추가하는 것이 가능해졌습니다.
3. 직면한 문제 (Check)
구현 후 시뮬레이션에서 세 가지 심각한 과제에 직면했습니다.
3-1. 테스트 예측에서의 "사일런트 버그 (Silent Bug)"
시뮬레이션을 실행한 결과, EvalConfig의 실적치가 변동하고 있었으나, 사실은 테스트 예측 계산 블록에서 필터가 전혀 적용되지 않고 있다는 치명적인 구조적 버그를 발견했습니다. best_strategy에 파라미터가 저장될 뿐, 실제 적중 판정에는 반영되지 않는 "작동하는 것처럼 보이기만 하는" 상태였습니다.
3-2. 학습 프로세스의 비결정성 (Non-determinism)
동일한 코드, 동일한 데이터, 동일한 seed=42로 실행해도 tune_strategy()의 수렴 결과가 매번 달라지는 현상이 발생했습니다. 조사 결과, LightGBM 학습에 포함된 미세한 비결정성이 전략 튜너의 이산적인 선택지가 많은 "평탄한 최적화 지형 (Flat optimization landscape)"에서 증폭되어, Optuna의 최적해를 분산시키고 있음이 판명되었습니다.
3-3. 2026년 데이터의 소표본 변동
2026년 Q1의 ROI가 130%를 초과하며 다른 연도(7078%)와 비교해 돌출된 이상치를 기록했습니다. 2026년은 1월3월 데이터를 소스로 사용하고 있습니다. 데이터 수가 다른 연도의 약 25%(858 레이스)에 불과하여, 상위 3건의 적중이 총 배당금의 28.2%를 차지하는 소표본 특유의 격심한 변동이 일어나고 있음을 특정했습니다.
4. 해결 접근 방식 (Action)
이러한 과제들에 대해 파이프라인의 건전화와 탐색 수법의 쇄신을 수행했습니다.
4-1. 탐색 차원의 축소
"필터의 ON/OFF (Categorical)"와 "제외율 (Conditional continuous value)"이라는 2단계 구조가 Optuna 탐색을 불안정하게 만드는 주된 원인이었습니다. 이에 따라 underperform_filter_pct 단일 변수(0.0~0.15)로 일원화했습니다. pct=0.0을 "필터 OFF"로 정의함으로써 정보 손실 없이 탐색 공간을 단순화했습니다.
4-2. 철저한 감도 분석과 "고정값화"
연도별 자유 탐색은 검증 데이터의 노이즈에 끌려 **과적합 (Overfitting)**을 일으킨다는 점이 확인되었습니다. 따라서 analyzer 측에서 「고정 조건에서의 감도 분석 (Sweep)」을 실시하여, ROI가 최대화되는 산 모양의 피크(0.15 부근)를 특정하는 접근 방식으로 전환했습니다.
5. 최종적인 해결책
수차례의 실험을 거쳐, 다음과 같은 구성을 최종적으로 확정했습니다.
- 시스템 구성: 범주(凡走, 부진) 모델을
role="filter"로 통합. - 전략 파라미터:
underperform_filter_pct = 0.15를 수동 고정값으로 채택. - 캐시 대책: Jupyter의 동적 로드 시 발생하는 캐시 불일치를 방지하기 위해,
importlib.invalidate_caches()를 도입하여 재현성을 보장했습니다.
개선된 구체적인 수치
| 지표 | 목표치 | 실적치 | 판정 |
|---|---|---|---|
| underperform AUC | 0.7190 | ✅ 달성 | |
| 전체 ROI (ON/OFF 차이) | OFF 대비 개선 | 74.13% → 75.46% (+1.33pt) | ✅ 달성 |
| ranking ROI (Cell37) | - | 81.56% (+6.28pt 개선) | ✅ 대폭 향상 |
범주 필터의 도입을 통해 기대치가 낮은 인기마를 확실하게 배제할 수 있게 된 것이 ROI 향상에 기여했습니다.
6. 배운 점
탐색 공간의 차원 수가 수렴의 안정성에 직결된다는 점은 큰 배움이었습니다. 복잡한 2단 구조를 버리고 1차원의 연속값으로만 정리함으로써, ROI 재실행 오차가 극적으로 압축되었습니다. 머신러닝 시스템에 있어서는 가능한 한 「평이하고 단조로운 최적화 지형」을 유지하는 것이 재현성 확보의 철칙입니다.
7. 차회 예고
범주 모델의 확립으로 시스템의 「방어력」은 한 단계 올라갔습니다. 하지만 이전부터 우려되었던 「穴馬 (아나우마, 배당 높은 복병마) 필터」 측에도 범주 모델과 동일한 「테스트 예측에 미적용된 버그」가 잠재되어 있을 가능성이 매우 높다는 것을 알게 되었습니다.
다음 회, 제27화 「穴馬 필터의 최적화: 버그의 연쇄를 끊고 진정한 효과를 드러내다」.
오랫동안 방치되었던 穴馬 필터를 「버그 수정 → 차원 축소 → 감도 분석 → 고정값화」의 흐름으로 철저하게 다듬어 보겠습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기