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. 같은 가격, 두 개의 정답표
쏠림을 없애는 표준 처방은 라벨에서 시장 전체 수익률을 빼는 것입니다. "올랐나"가 아니라 "시장보다 더 올랐나"를 묻는 초과수익 라벨입니다. 시장이 통째로 올라간 만큼은 정답에서 사라지므로 상승·하락 표본이 비슷해집니다.
그림 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건 |
3. 반례 — 균형인데도 무너진 종목
"쏠림이 전부가 아니다"의 결정적 증거는 XLK(기술 섹터 ETF)였습니다. 이 종목은 기저가 57.9%로 이미 균형에 가까운데도 하락 적중이 29.6%로 똑같이 무너졌습니다. 정답표가 균형이어도 배울 신호가 없으면 결과는 같았습니다.
여기에 다중비교 문제가 겹칩니다. 52개 구성 × 3개 구간 = 156칸을 봤으니, 그중 몇 개가 우연히 좋아 보이는 것은 당연합니다. 실제로 XLF를 한때 "미국 첫 양방향 플러스"로 판단했다가 구간별로 쪼개 보고 기각했습니다. 50을 넘는 구성도 3구간 중 1~2구간만 넘었고, 넘는 구간이 종목마다 제각각이었습니다.
4. 정답을 어디서 재고 있었나 — 하네스 버그
라벨 실험 도중 기저 상승률이 대상 종목과 무관하게 70.6%로 똑같이 찍히는 것을 발견했습니다. 워크포워드 하네스(과거 시점으로 되돌아가 학습·예측을 반복하는 평가 장치)가 정답 수익률을 항상 지역 프록시인 SPY에서 재고 있었기 때문입니다.
그림 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. 전체 흐름
그림 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