성적표에서 금요일 예측만 빠져 있었다 — 채점이 만드는 편향
예측의 적중률은 모델만큼이나 채점 방식에 좌우됩니다. 휴장일, 주말, 자신 있는 예측만 세기, 빈칸을 0으로 채우기 등 채점 과정에서 실제로 겪은 편향과 점검법을 정리했습니다.
최종 수정 2026-09-18
채점도 코드이고, 코드는 틀린다
어떤 서비스가 "적중률 68%"라고 말할 때 우리는 모델이 좋은지를 궁금해합니다. 하지만 그 숫자에는 모델 말고도 하나가 더 들어 있습니다. 채점기입니다. 어느 날의 가격과 비교했는지, 어떤 예측을 집계에서 뺐는지, 값을 모를 때 무엇으로 채웠는지. 이 결정들이 적중률을 10%p씩 움직일 수 있습니다.
이 서비스는 모든 예측을 저장하고 기한이 되면 실제 가격과 대조해 성적을 공개합니다. 그 채점기를 운영하면서 발견한 편향들을 적습니다. 모두 오류 메시지 없이, 그럴듯한 숫자를 내면서 일어났습니다.
사례 1 — 휴장일이 예측을 지웠다
휴장일에는 새 가격이 없습니다. 화면에 빈 날짜가 생기지 않도록 배치가 직전 거래일의 리포트를 복제해 넣었는데, 채점기가 그 복제본을 "다음 날"로 집었습니다. 예측한 날의 가격과 복제된 가격이 같으므로 실제 수익률은 0.00%, 판정은 "변동 없음"이 되어 집계에서 제외되었습니다.
더 나쁜 것은 그 판정이 굳는다는 점이었습니다. 채점기는 아직 채점되지 않은 예측만 다시 보는데, "변동 없음"도 채점된 것으로 기록되었기 때문입니다. 어느 금요일의 예측 32건 가운데 30건이 일요일 복제본으로 채점되어 성적표에서 사라졌습니다. 남은 2건은 주말에도 거래되는 암호화폐였습니다.
사례 2 — 금요일 예측만 영원히 미채점
복제 표시를 건너뛰도록 고친 뒤에도 비슷한 일이 남아 있었습니다. 금요일 저녁 배치와 월요일 아침 배치가 둘 다 금요일 종가를 담는 경우입니다. 복제 표시는 없지만 같은 봉입니다. 채점기는 "가격이 같으면 보류"했고, 다음 배치에서도 같은 리포트를 다시 집어 또 보류했습니다.
- 채점되지 않고 남은 예측
- 89건
- 그중 이 문제로 막힌 것
- 69건
- 그 69건의 요일
- 전부 금요일
이것은 단순한 누락이 아니라 요일 편향입니다. 주말을 건너뛰는 예측 — 이틀 치 뉴스가 쌓이고 월요일 갭이 생기는, 가장 어려운 예측 — 만 골라서 성적표에서 빠졌습니다. 남은 성적은 쉬운 날들의 성적입니다. 지금은 "다음 리포트"가 아니라 "다음 봉을 담은 첫 리포트"를 찾습니다.
사례 3 — 자신 있는 예측만 세기
모델의 과거 적중률을 계산하는 코드에 "예측 크기가 0.3% 미만이면 제외"라는 조건이 있었습니다. 의도는 그럴듯합니다. 0에 가까운 예측은 방향을 말한 것이 아니니 빼자는 것입니다. 결과는 둘이었습니다.
- 표본이 사라졌습니다. 480건 가운데 조건을 통과한 것이 종목당 0~4건이었습니다. 어떤 종목은 네 번 맞혔다는 이유로 적중률 100%가 되었고, 하루 치 자료가 늘자 66.7%에서 0%로 뒤집혔습니다. 이 숫자가 모델 가중치와 신뢰도 표시에 쓰이고 있었습니다.
- 위로 편향되었습니다. 모델이 크게 예측한 날만 남기면 재는 것은 "정확도"가 아니라 "자신 있을 때의 정확도"입니다. 한 종목은 이 방식으로 56.8%, 전체 표본으로 52.3%였습니다.
조건을 없애고 표본이 100건 미만이면 적중률을 아예 내지 않도록 바꾼 뒤, 엿새 동안의 변동 폭은 66.67%p에서 2.58%p로 줄었습니다. 하루 만에 60%p씩 움직이는 지표는 아무것도 재고 있지 않은 것입니다.
사례 4 — 비교하는 가격의 시각
모델은 "종가에서 다음 종가까지"를 예측합니다. 주식은 장이 끝난 뒤 배치가 돌므로 저장되는 가격이 곧 종가입니다. 암호화폐는 24시간 거래되어 배치가 도는 시각의 가격은 하루 봉의 중간 어딘가입니다. 예측은 종가 기준인데 채점은 중간 시세로 하고 있었습니다.
암호화폐 예측의 적중률이 20건 중 20%로 나온 것이 단서였습니다. 무작위라면 50% 근처여야 하므로 20%는 모델이 나쁘다기보다 무언가 어긋나 있다는 신호입니다. 지금은 완성된 일봉의 종가로 채점하고, 봉이 아직 완성되지 않았으면 채점을 미룹니다.
무작위보다 뚜렷하게 나쁜 성적은 좋은 소식일 수 있습니다. 정말 아무 정보도 없는 모델은 50%를 맞힙니다. 20%는 부호가 뒤집혔거나, 날짜가 하루 밀렸거나, 비교 대상이 틀렸다는 뜻인 경우가 많습니다.
사례 5 — 빈칸을 0으로 채우기
예측 구간이 실제 가격을 덮었는지(커버리지)를 기록하기 시작했을 때, 그 기능이 생기기 전의 옛 예측에는 구간 정보가 없었습니다. 이 빈칸을 0으로 채우면 "덮지 못했다"로 집계되어 커버리지가 실제보다 나쁘게 나옵니다. 1로 채우면 반대가 됩니다. 옳은 값은 빈칸 그대로이고, 집계에서 분모에도 넣지 않는 것입니다.
같은 원칙이 반대 방향으로도 적용됩니다. 예측을 만들 수 없는 종목(이력이 너무 짧은 경우)에 그럴듯한 값을 지어내 저장하면 그 값이 채점되어 성적에 섞입니다. 이 서비스는 그런 경우를 "예측 불가"로 저장하고 채점하지 않습니다.
모델이 바뀌면 성적표도 끊는다
모델의 입력을 고치다가 예전 코드가 라벨이 없는 최신 봉을 버리고 있었다는 것을 발견했습니다. 결과적으로 어제까지의 자료로 내일을 예측하고 있었습니다. 고치고 나면 모든 종목의 예측 입력이 하루씩 이동합니다. 이것은 개선이지만, 고치기 전과 후의 성적을 한 줄로 이어 비교할 수 없게 됩니다. 다른 시험을 본 두 학생의 점수를 평균 내는 것과 같습니다.
남의 적중률을 볼 때 물어볼 것
- 분모가 무엇입니까. 전체 예측 가운데 몇 건이 집계에 들어갔습니까. 제외된 예측은 왜 제외되었습니까.
- "중립"이나 "보류"가 얼마나 됩니까. 애매한 예측을 중립으로 돌리면 남은 예측의 적중률은 올라갑니다.
- 항상 "상승"이라고만 말했다면 몇 %입니까. 상승장에서는 그것만으로 55~60%가 나옵니다. 그 기준선과 나란히 놓아야 합니다.
- 예측 시점에 기록된 것입니까. 나중에 정리한 성적표는 기억처럼 다듬어집니다.
- 기간과 표본 수가 적혀 있습니까. 석 달, 40건의 적중률은 아직 아무 말도 하지 않습니다.
채점기를 고칠 때마다 이 서비스의 적중률은 대체로 50% 쪽으로 움직였습니다. 실망스러운 숫자이지만 그것이 실제 성적이고, 부풀려진 성적표로는 무엇을 고쳐야 할지 알 수 없습니다.
광고