09.방향 예측 라벨 설계 — 부호 대신 초과수익을 맞히면 무엇이 달라지나

2026. 9. 12. 15:02ㆍ카테고리 없음

화면 뒤의 데이터 판단 · 방향 신호

방향 예측 라벨 설계 — 부호 대신 초과수익을 맞히면 무엇이 달라지나

기저 62.0% → 53.2%, 성적은 41~47 → 45~50. 그래도 무작위선을 넘지 못했다

주가가 오를지 내릴지를 학습시키려면 정답표(라벨)가 필요합니다. 가장 단순한 정의는 "5영업일 뒤 수익률이 0보다 크면 1"입니다. 문제는 이 정답표가 한쪽으로 쏠려 있다는 점입니다.

미국 지수는 20일 기준 기저 상승률(전체 표본 중 상승이 차지하는 비율)이 65~70%입니다. 정답의 3분의 2가 "상승"이면, 모델은 아무것도 배우지 않고 항상 상승만 외쳐도 절반을 훌쩍 넘깁니다. 실제로 방향신호 실험 52건에서 하락 적중은 19~35%로 무너졌습니다.

1. 같은 가격, 두 개의 정답표

쏠림을 없애는 표준 처방은 라벨에서 시장 전체 수익률을 빼는 것입니다. "올랐나"가 아니라 "시장보다 더 올랐나"를 묻는 초과수익 라벨입니다. 시장이 통째로 올라간 만큼은 정답에서 사라지므로 상승·하락 표본이 비슷해집니다.

가격 하나close[t+5] / close[t] − 1① 부호 라벨 (raw)수익률 > 0 이면 1질문: "올랐나"② 초과수익 라벨수익률 − 시장수익률 > 0 이면 1질문: "시장보다 나았나"정답표 구성상승 62.0%하락 38.0%쏠림 — 하락 표본이 3분의 1상승 53.2%하락 46.8%거의 반반 — 하락도 배울 수 있다

그림 1. 가격 데이터는 하나지만 라벨 정의가 갈리면 정답표의 균형이 달라진다. 수치는 SPY 기준 실측(docs/eval/2026-08-08).

2. 기저를 낮추면 성적이 오르는가

평가 지표는 균형정확도였습니다. 상승 적중률과 하락 적중률의 단순 평균이라, 희소한 하락 쪽을 못 배우면 아무리 상승을 잘 맞혀도 50(무작위)을 넘기 어렵습니다. 쏠림이 원인이라면 라벨을 바꿔 기저를 낮추는 것만으로 성적이 올라야 합니다.

실제로 올랐습니다. 다만 선을 넘지는 못했습니다.

구성기저 상승률균형정확도(50=무작위)판정

부호 라벨 62.0% 41~47 실패
초과수익 라벨 53.2% 45~50 개선했으나 무작위선
실험 전체(52건) — 평균 43.51 · 최고 50.07 50 초과 1건
기저를 9%p 가까이 낮췄는데 성적은 여전히 50 언저리였습니다. 불균형은 원인의 일부였을 뿐이라는 뜻입니다. 남은 부분은 신호 자체의 부재로 해석했습니다.

3. 반례 — 균형인데도 무너진 종목

"쏠림이 전부가 아니다"의 결정적 증거는 XLK(기술 섹터 ETF)였습니다. 이 종목은 기저가 57.9%로 이미 균형에 가까운데도 하락 적중이 29.6%로 똑같이 무너졌습니다. 정답표가 균형이어도 배울 신호가 없으면 결과는 같았습니다.

여기에 다중비교 문제가 겹칩니다. 52개 구성 × 3개 구간 = 156칸을 봤으니, 그중 몇 개가 우연히 좋아 보이는 것은 당연합니다. 실제로 XLF를 한때 "미국 첫 양방향 플러스"로 판단했다가 구간별로 쪼개 보고 기각했습니다. 50을 넘는 구성도 3구간 중 1~2구간만 넘었고, 넘는 구간이 종목마다 제각각이었습니다.

4. 정답을 어디서 재고 있었나 — 하네스 버그

라벨 실험 도중 기저 상승률이 대상 종목과 무관하게 70.6%로 똑같이 찍히는 것을 발견했습니다. 워크포워드 하네스(과거 시점으로 되돌아가 학습·예측을 반복하는 평가 장치)가 정답 수익률을 항상 지역 프록시인 SPY에서 재고 있었기 때문입니다.

버그XLE 피처섹터 입력정답 = SPY 수익률ticker 인자 없음기저가 대상과 무관하게 70.6% 로 동일대상 변경 실험 4건이 사실상 "섹터 피처로 SPY 맞히기" 였다수정XLE 피처섹터 입력정답 = XLE 수익률run·walkforward 에 ticker기저가 종목별로 갈린다SPY 66.1% · XLK 54.2% · XLE 62.5%

그림 2. 라벨 설계보다 먼저 확인할 것은 "정답을 무엇에서 재고 있는가"였다. 이 버그로 대상 변경 실험 4건이 무효가 됐다.

5. 그런데 운영 모델은 부호 라벨로 돌아왔다

초과수익 라벨은 학습 관점에서 더 균형 잡힌 문제였지만, 운영에서는 화면이 던지는 질문과 어긋납니다. 화면은 "오를까 내릴까"를 표시하는데 모델은 "시장을 이길까"를 배운 상태였습니다. 실제로 직전 운영 모델(피처별 얕은 모델의 로그오즈 평균 · 초과수익 라벨)을 부호 기준으로 다시 재니 AUC 0.487, 상승 −0.8%p, 하락 −1.0%p였고 하락을 단 한 건도 내지 않았습니다.

# scripts/build_us_h5_model.py — 라벨은 화면 질문 그대로 둔다.
# 5영업일 뒤 수익률(fwd)을 만들고, 부호만 정답으로 쓴다. 횡보를 빼지 않는다.
fwd[:-HZN] = c[HZN:] / c[:-HZN] - 1
X, y = X[ok], (fwd[ok] > 0).astype(int)
# 정답표가 얼마나 쏠렸는지 학습 때마다 찍어 둔다(운영 학습 기준 61%대).
print(f'  기저상승 {y.mean()*100:.1f}%')

대신 쏠림은 라벨이 아니라 모델 쪽에서 다뤘습니다. 평균이 극단을 상쇄하던 구조를 단일 LightGBM으로 바꾸자 하락 예측이 나오기 시작했습니다(홀드아웃 하락 우위 +8.9%p · 하락 예측 56건).

6. 채택 수치와 한계

구간표본기저 상승률AUCAUC 95% 신뢰구간균형정확도

개발 (2014~2024) 2,267 61.23% 0.5218 0.487 ~ 0.559 51.79
홀드아웃 (2025~2026-08) 397 60.71% 0.5126 0.424 ~ 0.600 52.64

두 구간 모두 신뢰구간이 0.5를 포함합니다. "무작위보다 낫다"고 단정할 수 없는 수준이라는 뜻이고, 그래서 이 신호를 화면에서 단독 근거로 쓰지 않습니다. 채택 사유는 예측력 입증이 아니라 "직전 모델이 하락을 아예 못 내던 문제를 고쳤다"입니다. 목표였던 AUC 0.55·양방향 +5%p에는 미달했습니다.

남은 한계도 그대로 적어 둡니다. 확률 보정이 단조롭지 않아(개발 구간에서 0.4~0.5 구간의 실제 상승률이 0.5~0.6 구간보다 높음) 확률값을 세기로 읽으면 안 됩니다. "어제 방향 추종"이라는 가장 싼 기저 규칙의 균형 79.4도 못 넘는데, 이 값은 라벨 구간이 서로 겹쳐(중첩) 부풀려진 수치라 전략으로 쓸 수는 없지만 모델이 시계열 관성만큼도 못 잡는다는 신호입니다. 수익성은 검증하지 않았습니다.

7. 전체 흐름

① 피처 68개글로벌 지수 종가 · VIX · 야간/주간 분해② 라벨 = 부호5봉 뒤 수익률 > 0 (횡보 제외 안 함)③ 워크포워드21일마다 재학습 · 퍼지 + 5일 엠바고④ 홀드아웃 1회2025-01~2026-08 · 채택 직전에만 개봉⑤ pkl 저장라벨 정의 · 기저 · 성능 · 한계 동봉⑥ 운영 추론학습과 같은 피처 생성기를 그대로 호출

그림 3. ⑥이 ①과 같은 생성기를 쓰는 것이 조건이다. 정의가 갈리면 학습 때와 다른 값으로 추론하게 되어 예측이 통째로 무의미해진다.

정리

  • 라벨은 지표보다 먼저 본다 — 기저가 65~70%면 균형정확도는 하락 표본이 희소해 구조적으로 50을 넘기 어렵다.
  • 초과수익 라벨은 쏠림을 실제로 없앤다 — 62.0% → 53.2%. 성적도 41~47에서 45~50으로 올랐다.
  • 그래도 안 넘으면 원인은 다른 데 있다 — 이미 균형인 XLK(57.9%)도 하락 적중 29.6%로 무너졌다.
  • 정답을 무엇에서 재는지 먼저 확인한다 — 기저가 종목과 무관하게 같은 값이면 하네스를 의심한다.
  • 학습 문제와 화면 질문을 일치시킨다 — 초과수익으로 배운 모델을 부호로 평가하면 AUC 0.487, 하락 0건이었다.
  • 쏠림 대응은 라벨 말고 모델에서도 가능하다 — 평균이 극단을 상쇄하는 구조를 단일 모델로 바꾸자 하락 예측이 나왔다.
  • 신뢰구간이 0.5를 포함하면 그렇게 적는다 — 채택했다는 말과 입증됐다는 말은 다르다.

근거: docs/eval/2026-08-08-us-direction-timeseries.md · docs/eval/2026-08-12-us-h5-improve-attempt.md · scripts/build_us_h5_model.py