비운영 참조

한계 재보기

비운영 그래디언트 부스팅 참조

한 줄 결론 — 운영하지 않는 참고 모델이다. 운영 후보가 놓친 신호가 얼마나 남았는지 재는 참조선이며, 점수가 낮아 보여도 채택이나 순위를 뜻하지 않는다.

왜 믿나

잠정 결과 · 표본이 아직 얕다

일일 평가가 시작된 지 얼마 되지 않아 관측일이 비교 관문에 못 미친다. 어디까지 왔는지는 아래 오늘 성적의 관문 막대로 확인한다.

이 모델의 일일 채점은 2026-08-19 평가일까지로 끝났다. 08번(A18)을 단일 운영 모델로 확정하며 evaluation-v3에서 도입한 결정이고, 현재 evaluation-v6도 이어받는다. 새 점수는 만들지 않으며 마지막 값과 중단 시점은 이력에 남는다.

일일 평가의 이 모델 예측에는 별도 보정층을 적용하지 않는다. 재표본 결과가 원장에 없어 불확실성 범위는 만들지 않았고, 수치는 이 평가 자료 안의 점추정으로만 읽는다.

동결 이력 성적

배포 시점 값 · 일일 평가 2026-08-16분 · 생성 08-17 00:15 KST 잠정

종합 점수
49.7
평가 관측일
2일 / 10일
만석 누적
173건 / 100건
만석 관측일
2일 / 5일

전체 표본 — 평가행 18,055 · 만석 173건 · 비만석 17,882건.

지표오늘 값읽는 법
Brier0.0101예측확률과 실제 0·1의 제곱 오차 평균. 낮을수록 좋다.
만석 누락률100.0%실제 만석 중 확률 50% 미만으로 말한 비율. 낮을수록 좋다.
ROC-AUC0.775만석·비만석 한 쌍에서 만석에 더 높은 확률을 줄 가능성. 높을수록 좋다.
Log loss0.0502확신하고 틀릴수록 커지는 벌점. 낮을수록 좋다.
ECCE-MAD0.0087확률 순서대로 쌓은 오차가 가장 벌어진 정도. 낮을수록 좋다.
PR-AUC0.060드문 만석을 위쪽으로 모으는 힘. 높을수록 좋다.
확률 쏠림0.0087평균 예측확률에서 실제 만석률을 뺀 값. 0에 가까울수록 좋다.
비용 1:10.0096잘못 안심과 과한 경고를 같은 비용으로 둔 평균 비용. 같은 가정끼리 비교한다.
비용 2:10.0224잘못 안심을 2배 비용으로 둔 평균 비용. 같은 가정끼리 비교한다.
비용 4:10.0444잘못 안심을 4배 비용으로 둔 평균 비용. 같은 가정끼리 비교한다.

점수 50 = 시간순 과거 만석률 기준 모델 · 자세한 기준은 평가 규약

구간별 동결 이력 성적

구간행만석Brier만석 누락ROC-AUC
주말18,0551730.0101100.0%0.775
출근2,70200.0005——
퇴근4,195120.0083100.0%0.880
그 외11,1581610.0131100.0%0.782
노선 16507,5321600.0200100.0%0.756
노선 333010,523130.0030100.0%0.721
노선 1650·출근97000.0006——
노선 1650·퇴근1,694120.0119100.0%0.867
노선 1650·그 외4,8681480.0267100.0%0.766
노선 3330·출근1,73200.0004——
노선 3330·퇴근2,50100.0058——
노선 3330·그 외6,290130.0025100.0%0.733

평가 행이 없는 구간 1개: 평일

해설 기준: gradient-boosting-upper-v1 연구 구현 — 보조 코퍼스·초기 수집분으로 개발했고 isotonic 보정을 포함한다. 해설의 수치는 개발 당시 기록이고, 오늘 성적은 위 섹션이 정본이다. 관문 기준·구간 정의·지표 정의·분할 규칙·라벨 정의·상류 시계 반증은 평가 규약에 있다.

Q. 이 모델은 지금 무엇을 계산하나?

수집기가 예측 시점까지 모은 승인 정보의 비선형 조합이, 목표 정류장 출발 뒤 만석일 확률을 얼마나 가르는지 잰다. 목적은 배포가 아니라, 운영 후보가 놓친 신호의 잔량 확인이다.

오픈북 모의고사와 같다. 허용된 재료는 다 펼치지만, 그 답안지를 운영안으로 내지는 않는다. 운영 후보와 같은 평가 행·구간·지표로 채점하되 결과는 비운영 참고로만 표시하고 순위와 승자를 만들지 않는다.

Q. 정류장·시간만 봐도 되는데 왜 더 복잡하게 보나?

노선×정류장×30분 셀은 833개다. 이 중 281개(33.73%)는 학습 표본이 10건 이하고, 719개(86.31%)는 만석을 한 번도 못 봤다. 셀 비율만으로는 얇은 칸을 0% 위험으로 굳히기 쉽다.

그래서 이 모델에는 허용된 신호를 한꺼번에 넣었다. 위치와 시간뿐 아니라 앞선 버스의 절대 잔여석, 직전 통과, 헤드웨이 구간, 노선 전체 좌석 분포까지 준다.

보조 코퍼스의 시간순 검증 10,040건(만석 583건)에서 이 모델은 isotonic 보정 뒤 Brier 0.0155 · log loss 0.0524 · AUC 0.9910을 냈고, 잠정 운영 후보인 구간 검열 모형은 0.0268 · 0.0878 · 0.9751이었다. 차이는 남았다. 직접 수집분 validation 443건(만석 14건)에서는 이 모델이 0.0144 · 0.0731 · 0.9595, 구간 검열이 0.0244 · 0.0987 · 0.9093이었다. 다만 두 모델의 차이는 이 표본으로 가리지 못한다. train과 validation이 같은 날짜라 isotonic 보정 fold가 없었고 양쪽 예측 모두 raw다.

여기서 상한은 수학적 한계가 아니다. 이번 재료, 이번 구현, 이번 검증에서 찍힌 참조 기록이다.

상한과 운영 후보의 간격 — 개발 당시 연구 기록
모델ECEBrierlog lossAUC
정류장×시간 기준선 raw.0063.0327.1033.9613
구간 검열 isotonic.0053.0268.0878.9751
GB 상한 isotonic.0053.0155.0524.9910

보조 코퍼스 validation 10,040건·만석 583건·정류소×날짜 644군집의 점추정이다.

Q. 어떻게 계산하나?

평가 사건을 고정한다

현재 수집 자료에서 라벨 규칙을 통과한 사건만 남기고, 같은 통과 사건은 한 번만 센다.

시간 순서를 지킨다

예측 시점까지 알 수 있는 특징만 만들고, 앞선 한국 표준시 날짜로 학습한 뒤 다음 날짜를 평가한다.

작은 나무를 이어 붙인다

각 결정나무가 앞선 나무들이 남긴 오차를 조금씩 줄이도록 학습해 비선형 관계와 특징 조합을 표현한다.

만석 확률을 낸다

나무들의 기여를 합쳐 목표 정류장 출발 뒤 남은 좌석이 없을 확률을 낸다.

Q. 나무 한 그루는 무엇을 하나?

한 그루는 짧은 예·아니오 질문을 이어 붙인다.

질문을 통과한 행들은 같은 잎에 모인다. 잎에는 만석 여부를 바로 적지 않는다. 현재 점수를 올리거나 내릴 보정값을 적는다. 숫자 결측은 억지로 0이나 평균으로 채우지 않는다. 나무가 결측을 어느 쪽으로 보낼지도 학습한다.

Q. 왜 한 그루로 끝내지 않나?

첫 나무가 크게 틀린 행을 다음 나무가 다시 본다. 그다음 나무도 남은 오차를 본다. 이 구현은 log loss를 줄이는 작은 나무 250개를 순서대로 더한다.

F_m(x) = F_{m-1}(x) + 0.05 h_m(x)

마지막에는 p_full = 1 / (1 + exp(-F_250))로 만석확률을 만든다. 250개 나무의 다수결이 아니다. 앞선 답을 뒤 나무가 조금씩 고치는 누적 계산이다. 조기 종료는 쓰지 않았다. 250개를 끝까지 더했다.

Q. 얇은 셀은 어떻게 다루나?

정류장×시간 셀을 따로 외우는 규칙은 없다. 대신 한 잎에 최소 30건이 들어가야 한다. 나무 한 그루의 잎은 최대 63개다. 잎 보정값에는 L2 10을 건다. 얇은 셀 하나만으로 잎을 만들지 못하고, 같은 갈림길을 지난 다른 정류장·시각과 묶인다.

이것이 boosting식 풀링이다. 누구와 묶을지 미리 정하지 않고 잔여석·위치·시간의 경계로 정한다. 다만 나무 250개의 잎을 겹치면 최종 구역은 30건보다 훨씬 얇아질 수 있다. 규제가 있어도 운영 모델로 바로 쓰지 않는 이유다.

상한 측정 파이프라인
가용 특징 46개
반복 분할
작은 나무 250개 잎≤63·잎 표본≥30
오차 보정값 합산
합산 log-odds
sigmoid
raw p_full
OOF 보정
isotonic 58개 임계점
사용자 확률로 뒤집기
p_board=1-p_full
상한 측정 전용 운영 후보 아님

허용 특징 46개가 250개 나무를 거쳐 raw 만석확률이 되고, 시간순 OOF isotonic이 눈금을 다시 맞춘다.

이 방식의 강점

연구 구현은 train 내부 시간순 OOF 예측으로 isotonic 보정을 맞췄다. 일일 평가의 이 모델 예측에는 별도 보정층을 적용하지 않으며, 보정층은 숫자 다듬기가 따로 다룬다.

Q. 실제 한 건은 어떻게 흘렀나?

아래 사례는 직접 수집분이 아니라 보조 코퍼스의 검증행이다.

항목실제 값
질의2026-08-06 07:28:58 KST
장소3330번 롯데백화점.범계역, 축 순번 55
최근접 상류 버스축거리 1, stateCd=0, 잔여석 0
상류 버스 좌석 변화분당 -6.6165석
직전 통과만석, 출발 후 잔여석 0
노선 응답차량 22대, 만석 3대, 평균 잔여석 29.1364석
계획 배차5분
실제 정답이 버스도 출발 후 만석

학습분의 만석은 705/12,065건이었다. 시작 log-odds는 ln(705/11,360) = -2.7797, 만석확률은 .0584다.

첫 나무에서 이 행은 상류 잔여석 0 ≤ 1.5, 정류장 순번 55 ≤ 64를 차례로 통과했다. 학습률을 반영한 잎 보정값은 +.5084였다.

F_1 = -2.7797 + .5084 = -2.2712 → p_full = .0935
범계역 한 행의 확률 변화
시작.0584
첫 잎 +.5084 log-odds
1개.0935
49개 보정
50개.8095
100개 보정
150개.9365
100개 보정
250개 raw.9114
확률 눈금 교정
isotonic.8577
1-p_full
탈 확률.1423

2026-08-06 07:28:58 KST, 3330번 롯데백화점.범계역 검증행의 실측 계산이다.

250개 잎 보정값의 합은 +5.1104였다. 최종 점수는 2.3307, raw 만석확률은 .9114가 됐다. 나무가 늘수록 확률이 한 방향으로만 움직이지는 않는다. 150개 뒤 .9365에서 마지막에는 .9114로 내려왔다.

train 내부 시간순 OOF 10,236건 중 만석 572건으로 맞춘 58개 임계점의 isotonic 보정기가 .9114를 .8577로 바꿨다. 실제 출발은 만석이었다. 한 건을 맞힌 사례일 뿐, 이 한 줄이 성능 증거는 아니다.

재료 한눈에

최종 입력은 46열이다. 문자열은 노선과 원천 표시만 숫자로 바꿨다. 크게 다섯 묶음이다 — 축·시각(만석 위험의 1차 구조), 상류 버스(곧 올 관측 버스의 현재 상태), 통과 버스(방금 지나간 공급), 통과 이력(점시각 없이 쓰는 과거 공급 간격), 노선 응답 요약(한 버스 밖의 노선 전체 혼잡 국면). 출발 뒤 만석 여부는 학습 정답으로만 쓰고, 현재 수집 계열 밖의 이전 연구 자료는 학습 입력과 비교선에서 제외한다.

쓰는 재료 47개 — 출처 필드까지

재료종류어느 API의 어느 필드
목표 축 순번 (station_seq)stateCd=1이면 현재 stationSeq-1, stateCd=0·2이면 현재 stationSeq를 마지막 통과 순번으로 놓는다. 인접 적격 응답에서 이 값이 전진한 끝점을 통과 사건 순번으로 삼는다.주의 — 모델 축은 routestation 전체 순번이다. 학습 행은 서비스 정차점만 남겨도 축 간격에는 미정차·경유 지점이 들어간다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; routestation.staOrder; S1 station_seqGBIS 버스위치정보 getBusLocationListv2 + GBIS routestation 마스터 + S1 통과 사건 빌더
KST 하루 중 분 (query_minute_of_day)KST 시각에서 hour*60+minute을 계산한다.주의 — msgHeader.queryTime은 쓰지 않는다. 초는 버린다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 query_minute_of_day우리 수집기 응답 수신시각; 제한 코퍼스는 수집기가 붙인 collectedAt
KST 시 (query_hour)KST 응답 수신시각의 hour를 뽑는다.주의 — msgHeader.queryTime의 시각이 아니다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 query_hour우리 수집기 응답 수신시각; 제한 코퍼스는 수집기가 붙인 collectedAt
KST 30분대 (query_half_hour)응답 수신시각을 KST로 바꾸고 hour*2 + 1[minute>=30]으로 0~47을 만든다.주의 — msgHeader.queryTime과 HTTP Date는 시간 계산에 쓰지 않는다. 코퍼스 collectedAt은 본문 파싱 뒤 시각이다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 query_half_hour우리 수집기 응답 수신시각; 제한 코퍼스는 수집기가 붙인 collectedAt
요일 (query_day_of_week)KST 날짜에 Python weekday()를 적용한다. 월요일 0, 일요일 6이다.주의 — 공휴일 표시는 없다. 요일만 구분한다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 query_day_of_week우리 수집기 응답 수신시각; 제한 코퍼스는 수집기가 붙인 collectedAt
날짜 순번 (query_day_index)KST 날짜에서 2026-07-19를 뺀 일수를 쓴다.주의 — 이 데이터셋의 고정 기준일에 묶인 값이다. 달력 날짜의 보편적 ID가 아니다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 query_day_index우리 수집기 응답 수신시각; 제한 코퍼스는 수집기가 붙인 collectedAt
계획 배차간격 (master_dispatch_interval_min)현재 구현은 평일 06:30~09:29·17:00~20:29에 peekAlloc, 그 밖 평일에 npeekAlloc을 고른다. 토요일은 satNpeekAlloc, 일요일은 sunNpeekAlloc을 고른다.주의 — 계획값이지 실제 헤드웨이가 아니다. 현재 코드의 피크 조건에 평일 검사가 들어가 토·일 *PeekAlloc 분기는 닿지 않는다. we*도 고르지 않는다.파생route.peekAlloc, route.npeekAlloc, route.satPeekAlloc, route.satNpeekAlloc, route.sunPeekAlloc, route.sunNpeekAlloc, route.wePeekAlloc, route.weNpeekAlloc; timing.response_received_at.kst, timing.response_received_at.utc; S1 master_dispatch_interval_minGBIS route 마스터 + 우리 수집기 응답 수신시각 + S1 특징 빌더
직전 적격 응답 간격 (previous_poll_gap_sec)같은 원천·수집 묶음·노선·KST 날짜·고정 수집창 안의 직전 적격 응답과 초 차이를 낸다. 0<gap<=90인 연결만 쓴다.주의 — 실패·정상 0대 호출은 학습 스냅샷이 아니다. 90초 초과, 날짜 경계, 수집창 경계에서는 연결을 끊는다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 previous_poll_gap_sec우리 수집기 응답 수신시각 + S1 호출 연결
회차 순번 (turn_seq)대상 노선의 route.turnSeq를 그대로 붙인다.주의 — routestation에서 읽는 값이 아니다.응답 원본route.turnSeq; S1 turn_seqGBIS route 마스터
회차 전 여부 (is_outbound)station_seq<=turn_seq면 1, 아니면 0이다.주의 — 공식 upDown을 그대로 쓴 값이 아니다. 내부 순번축을 회차점에서 둘로 나눈 표시다.파생route.turnSeq, S1 station_seq; S1 is_outboundGBIS route 마스터 + S1 통과 사건
기점부터 축 순번거리 (axis_distance_from_origin_seq)station_seq-1을 계산한다.주의 — 표시용 서비스 정류장 수가 아니라 routestation 전체 순번 차이다.파생routestation.staOrder; S1 station_seq, axis_distance_from_origin_seqGBIS routestation 마스터 + S1 축 빌더
회차점까지 부호 있는 축 순번거리 (signed_axis_distance_to_turn_seq)turn_seq-station_seq를 계산한다.주의 — 회차점을 지나면 음수다.파생route.turnSeq, routestation.staOrder; S1 signed_axis_distance_to_turn_seqGBIS route 마스터 + GBIS routestation 마스터 + S1 축 빌더
기점부터 축 거리 km (axis_distance_from_origin_km)staOrder 순으로 인접한 x,y 좌표의 Haversine 거리를 누적한다.주의 — 도로 주행거리가 아니라 정류장 좌표 사이 대권거리 합이다. 현재 빌더는 station.x, station.y를 읽지 않는다.파생routestation.routeName, routestation.staOrder, routestation.x, routestation.y; S1 axis_distance_from_origin_kmGBIS routestation 마스터 + S1 축 빌더
회차점까지 축 거리 km (axis_distance_to_turn_km)목표 순번의 누적 Haversine 거리와 회차 순번의 누적 거리 차의 절댓값을 쓴다.주의 — 도로망 최단거리나 실시간 이동거리가 아니다.파생route.turnSeq; routestation.staOrder, routestation.x, routestation.y; S1 axis_distance_to_turn_kmGBIS route 마스터 + GBIS routestation 마스터 + S1 축 빌더
상류 버스 존재 (upstream_bus_exists)정규화 마지막 통과 순번이 목표 station_seq보다 작은 차량이 하나라도 있으면 1이다.주의 — API가 노선의 모든 차량을 포착한다는 뜻은 아니다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; S1 정규화 last_passed; S1 upstream_bus_existsGBIS 버스위치정보 getBusLocationListv2 + S1 스냅샷 특징 빌더
상류 버스 축거리 (upstream_axis_gap_seq)상류 후보 중 목표에 가장 가까운 차량을 고르고 target station_seq-last_passed를 계산한다.주의 — 동률은 출발 stateCd=2, 교차 0, 도착 1 순, 더 최신 운행, 차량키 사전순으로 푼다. 좌석값은 선택 기준이 아니다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; S1 정규화 last_passed; S1 upstream_axis_gap_seqGBIS 버스위치정보 getBusLocationListv2 + S1 스냅샷 특징 빌더
상류 최근접 동률 수 (upstream_tie_count)최소 upstream_axis_gap_seq에 놓인 후보 차량 수를 센다.주의 — 응답 전체 차량 수가 아니다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; S1 정규화 last_passed; S1 upstream_tie_countGBIS 버스위치정보 getBusLocationListv2 + S1 스냅샷 특징 빌더
상류 버스 잔여석 (upstream_remain_seats)축거리와 동률 규칙으로 고른 상류 차량의 remainSeatCnt를 붙인다.주의 — -1은 0으로 바꾸지 않고 결측으로 둔다. 이 값은 목표 차량의 미래 라벨이 아니다.파생msgBody.busLocationList[].remainSeatCnt, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd, msgBody.busLocationList[].vehId; S1 upstream_remain_seatsGBIS 버스위치정보 getBusLocationListv2 + S1 최근접 상류차 선택
상류 버스 상태 (upstream_state_cd)선택된 상류 차량의 원 stateCd를 붙인다.주의 — 로지스틱은 0·1·2를 원핫 표시로 바꾼다. 상태 의미와 축 위치 정규화는 별개다.파생msgBody.busLocationList[].stateCd, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].vehId; S1 upstream_state_cdGBIS 버스위치정보 getBusLocationListv2 + S1 최근접 상류차 선택
상류 버스 좌석 변화율 (upstream_seat_change_per_min)선택된 차량을 직전 적격 응답의 같은 차량과 잇고 (현재 좌석-직전 좌석)/(경과초/60)을 계산한다.주의 — 두 좌석값이 비음수이고 0<경과<=90초, 정규화 순번 변화가 0 또는 1일 때만 만든다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd, msgBody.busLocationList[].remainSeatCnt; timing.response_received_at.kst, timing.response_received_at.utc; S1 upstream_seat_change_per_minGBIS 버스위치정보 getBusLocationListv2 + 우리 수집기 응답 수신시각 + S1 차량 연결
상류 버스 축 속도 (upstream_speed_seq_per_min)같은 차량의 정규화 순번 변화량을 (경과초/60)으로 나눈다.주의 — 0<경과<=90초이고 순번 변화가 0 또는 1일 때만 만든다. +2 이상 도약은 속도로 쓰지 않는다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; timing.response_received_at.kst, timing.response_received_at.utc; S1 upstream_speed_seq_per_minGBIS 버스위치정보 getBusLocationListv2 + 우리 수집기 응답 수신시각 + S1 차량 연결
이미 지난 버스 존재 (passed_bus_exists)정규화 마지막 통과 순번이 목표 station_seq 이상인 차량이 하나라도 있으면 1이다.주의 — 그 차량이 사용자가 탈 다음 차량이라는 뜻은 아니다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; S1 정규화 last_passed; S1 passed_bus_existsGBIS 버스위치정보 getBusLocationListv2 + S1 스냅샷 특징 빌더
지난 버스 축거리 (passed_axis_gap_seq)이미 지난 후보 중 목표에 가장 가까운 차량을 고르고 last_passed-target station_seq를 계산한다.주의 — 동률 규칙은 상류 선택과 같다. 좌석값은 선택 기준이 아니다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; S1 정규화 last_passed; S1 passed_axis_gap_seqGBIS 버스위치정보 getBusLocationListv2 + S1 스냅샷 특징 빌더
지난 버스 최근접 동률 수 (passed_tie_count)최소 passed_axis_gap_seq에 놓인 후보 차량 수를 센다.주의 — 응답 전체 차량 수가 아니다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; S1 정규화 last_passed; S1 passed_tie_countGBIS 버스위치정보 getBusLocationListv2 + S1 스냅샷 특징 빌더
지난 버스 잔여석 (passed_remain_seats)축거리와 동률 규칙으로 고른 지난 차량의 remainSeatCnt를 붙인다.주의 — -1은 결측이다. 목표 정류장을 지난 뒤의 관측이라도 목표 차량의 정답 라벨과는 다른 스냅샷 차량이다.파생msgBody.busLocationList[].remainSeatCnt, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd, msgBody.busLocationList[].vehId; S1 passed_remain_seatsGBIS 버스위치정보 getBusLocationListv2 + S1 최근접 지난 차 선택
지난 버스 상태 (passed_state_cd)선택된 지난 차량의 원 stateCd를 붙인다.주의 — 로지스틱은 0·1·2 원핫 표시로 바꾼다.파생msgBody.busLocationList[].stateCd, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].vehId; S1 passed_state_cdGBIS 버스위치정보 getBusLocationListv2 + S1 최근접 지난 차 선택
직전 통과 라벨 존재 (previous_passage_exists)같은 원천·노선·정류장에서 질의시각 전에 구간이 끝나고 라벨까지 관측된 가장 최근 통과가 있으면 1이다.주의 — 현재 행의 미래 라벨은 후보가 될 수 없다. 원천을 넘겨 연결하지 않는다.파생S1 passage_events.source, passage_events.route, passage_events.station_seq, passage_events.passage_interval_end, passage_events.label_observed_at, passage_events.label_status; 특징 previous_passage_existsS1 passage_events
직전 통과 출발 후 잔여석 (previous_passage_remain_seats)인과 조건을 만족하는 같은 정류장의 가장 최근 통과에서 label_remain_seats를 가져온다.주의 — 현재 목표 차량의 출발 후 좌석이 아니다.파생S1 passage_events.label_remain_seats, passage_events.label_observed_at, passage_events.passage_interval_end; 특징 previous_passage_remain_seatsS1 passage_events
직전 통과 만석 여부 (previous_passage_is_full)인과 조건을 만족하는 가장 최근 같은 정류장 통과의 label_full을 가져온다.주의 — 직전 API 응답 한 대와 같은 뜻이 아니다. 직전으로 확정된 통과 사건이다.파생S1 passage_events.label_full, passage_events.label_observed_at, passage_events.passage_interval_end; 특징 previous_passage_is_fullS1 passage_events
직전 통과 라벨 나이 (previous_passage_label_age_sec)현재 질의 응답 수신시각에서 직전 통과 라벨 관측시각을 뺀다.주의 — msgHeader.queryTime으로 빼지 않는다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 passage_events.label_observed_at, previous_passage_label_age_sec우리 수집기 응답 수신시각 + S1 passage_events
최근 통과 나이 하한 (latest_passage_age_lower_sec)현재 질의시각에서 최근 통과 구간의 끝을 뺀다.주의 — 통과시각이 폴링 사이 구간이라 한 점의 정확한 나이가 아니다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 passage_events.passage_interval_end, latest_passage_age_lower_sec우리 수집기 응답 수신시각 + S1 passage_events
최근 통과 나이 상한 (latest_passage_age_upper_sec)현재 질의시각에서 최근 통과 구간의 시작을 뺀다.주의 — 하한과 함께 봐야 한다.파생timing.response_received_at.kst, timing.response_received_at.utc; S1 E4 response_received_kst, response_received_utc; 코퍼스 collectedAt; S1 passage_events.passage_interval_start, latest_passage_age_upper_sec우리 수집기 응답 수신시각 + S1 passage_events
관측 헤드웨이 하한 (observed_headway_lower_sec)같은 원천·노선·정류장의 최근 통과 시작에서 그 전 통과 끝을 빼고 0 아래를 자른다.주의 — 정확 통과시각 차가 아니라 두 검열 구간이 허용하는 하한이다.파생S1 passage_events.passage_interval_start, passage_events.passage_interval_end; 특징 observed_headway_lower_secS1 passage_events의 연속 통과 구간
관측 헤드웨이 상한 (observed_headway_upper_sec)최근 통과 끝에서 그 전 통과 시작을 빼고 0 아래를 자른다.주의 — 계획 배차간격과 다른 관측 구간 상한이다.파생S1 passage_events.passage_interval_start, passage_events.passage_interval_end; 특징 observed_headway_upper_secS1 passage_events의 연속 통과 구간
응답 내 노선 차량 수 (route_vehicle_count)make_observation 정규화에 성공한 차량 행 수를 센다.주의 — 실제 운행 대수 보장이 아니다. 차량키·순번·상태가 잘못된 원행은 먼저 빠진다. 정상 0대와 실패도 학습 스냅샷 행이 아니다.파생msgBody.busLocationList[]; S1 E4 derived/observations.jsonl 행; 코퍼스 vehicles[]; S1 route_vehicle_countGBIS 버스위치정보 getBusLocationListv2
좌석값이 있는 차량 수 (route_known_seat_count)remainSeatCnt>=0인 차량 수를 센다.주의 — -1은 포함하지 않는다.파생msgBody.busLocationList[].remainSeatCnt; S1 route_known_seat_countGBIS 버스위치정보 getBusLocationListv2
응답 내 0석 차량 수 (route_full_bus_count)remainSeatCnt==0인 차량 수를 센다.주의 — 응답에 잡힌 차량만 센다.파생msgBody.busLocationList[].remainSeatCnt; S1 route_full_bus_countGBIS 버스위치정보 getBusLocationListv2
노선 응답 잔여석 평균 (route_seat_mean)응답 안의 비음수 remainSeatCnt에 산술평균을 적용한다.주의 — remainSeatCnt=-1은 제외한다. 유효 좌석값이 없으면 결측이다.파생msgBody.busLocationList[].remainSeatCnt; S1 route_seat_meanGBIS 버스위치정보 getBusLocationListv2 + S1 노선 응답 요약
노선 응답 잔여석 표준편차 (route_seat_std)응답 안의 비음수 remainSeatCnt에 모표준편차(ddof=0)을 적용한다.주의 — remainSeatCnt=-1은 제외한다. 유효 좌석값이 없으면 결측이다.파생msgBody.busLocationList[].remainSeatCnt; S1 route_seat_stdGBIS 버스위치정보 getBusLocationListv2 + S1 노선 응답 요약
노선 응답 잔여석 최솟값 (route_seat_min)응답 안의 비음수 remainSeatCnt에 최솟값을 적용한다.주의 — remainSeatCnt=-1은 제외한다. 유효 좌석값이 없으면 결측이다.파생msgBody.busLocationList[].remainSeatCnt; S1 route_seat_minGBIS 버스위치정보 getBusLocationListv2 + S1 노선 응답 요약
노선 응답 잔여석 10백분위 (route_seat_p10)응답 안의 비음수 remainSeatCnt에 numpy.quantile 기본 선형 보간의 0.10 분위수를 적용한다.주의 — remainSeatCnt=-1은 제외한다. 유효 좌석값이 없으면 결측이다.파생msgBody.busLocationList[].remainSeatCnt; S1 route_seat_p10GBIS 버스위치정보 getBusLocationListv2 + S1 노선 응답 요약
노선 응답 잔여석 중앙값 (route_seat_median)응답 안의 비음수 remainSeatCnt에 numpy.quantile 기본 선형 보간의 0.50 분위수를 적용한다.주의 — remainSeatCnt=-1은 제외한다. 유효 좌석값이 없으면 결측이다.파생msgBody.busLocationList[].remainSeatCnt; S1 route_seat_medianGBIS 버스위치정보 getBusLocationListv2 + S1 노선 응답 요약
노선 응답 잔여석 90백분위 (route_seat_p90)응답 안의 비음수 remainSeatCnt에 numpy.quantile 기본 선형 보간의 0.90 분위수를 적용한다.주의 — remainSeatCnt=-1은 제외한다. 유효 좌석값이 없으면 결측이다.파생msgBody.busLocationList[].remainSeatCnt; S1 route_seat_p90GBIS 버스위치정보 getBusLocationListv2 + S1 노선 응답 요약
스냅샷 공간 헤드웨이 (spatial_headway_axis_seq)선택된 지난 차량의 last_passed에서 선택된 상류 차량의 last_passed를 뺀다.주의 — 양쪽 차량이 모두 있어야 한다. 시간 헤드웨이가 아니라 전체 순번축의 간격이다.파생msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd, msgBody.busLocationList[].vehId; S1 spatial_headway_axis_seqGBIS 버스위치정보 getBusLocationListv2 + S1 상류·지난 차 선택
노선 (route)직접 수집은 calls.jsonl.route_name, 코퍼스는 route.name을 모델 범주로 읽고 같은 route.routeName 마스터 행을 찾는다. 수집기 설정의 route.route_id와 원응답 routeId는 원문에 남는다.주의 — 현재 S1 구현은 실제로 routeName으로 마스터를 찾는다. msgBody.busLocationList[].routeId를 모델의 route로 복사하지 않는다. 대상 두 노선 밖으로 넓힐 때는 ID 검증이 필요하다.응답 원본msgBody.busLocationList[].routeId; 운영 수집기 route.name, route.route_id; S1 E4 calls.jsonl.route_name; 코퍼스 route.name; route.routeName, route.routeId; S1 routeGBIS 버스위치정보 getBusLocationListv2 + 우리 수집기 노선 메타데이터 + 제한 코퍼스 + GBIS route 마스터
원천 구분 (source_kind)직접 수집 행은 direct_e4, 제한 코퍼스 행은 corpus로 붙인다.주의 — GBIS 응답 필드가 아니다. GBM에는 범주형 예측 재료로 들어가고, 구간 검열에서는 같은 원천끼리 연결하는 데 쓴다.파생S1 source_kindS1 데이터셋 빌더
출발 후 만석 라벨 (label_full)정류장 s 통과 뒤 같은 차량에서 (stateCd,stationSeq)=(2,s),(0,s),(1,s+1) 중 처음 잡힌 유효 좌석값을 찾는다. 0이면 1, 양수면 0이다.주의 — remainSeatCnt=-1은 결측이다. (stateCd,stationSeq)=(1,s)는 도착 상태라 라벨이 아니다. 예측 시점 뒤에 생기므로 학습 정답으로만 쓴다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd, msgBody.busLocationList[].remainSeatCnt; timing.response_received_at.kst, timing.response_received_at.utc; S1 passage_events.label_full, label_remain_seatsGBIS 버스위치정보 getBusLocationListv2 + 우리 수집기 응답 수신시각 + S1 통과 사건 빌더

지금은 안 쓰는 재료 6개

모델 공통의 재료 판정과 후보별 사용 범위는 재료 문서에 있다.

Q. 언제 실패하나?

함께 읽을 한계

Q. 개인정보와 미래 정답은 어떻게 막나?

기존 프로토타입과 다른 점

관점프로토타입Gradient boosting 상한
맞히는 것화면 탑승률은 셀의 1-zeroCount/samples; 좌석 예보는 별도 계산다음 관측 버스의 출발 후 label_full 하나
계산현재 잔여석에서 정류장별 정규 수요를 빼며 0~80석 분포 전파46개 입력을 250개 나무로 나눠 만석 log-odds 합산
얇은 셀history 셀 비만석률을 그대로 표시잎당 최소 30건·L2 10으로 암묵 풀링
고정 규칙2분/순번, 10석 여유폭, 90분 streak 등데이터에서 분할 경계를 학습. 계획 배차와 로컬 시각은 입력으로만 사용
확률 보정별도 보정층 없음train 내부 시간순 OOF 10,236건으로 isotonic 적합
쓰임사용자 화면 기능비교표 전용. 배포·채택 대상 아님

프로토타입의 좌석 예보를 더 복잡하게 만든 모델이 아니다. 질문부터 바뀌었다. 이 모델은 몇 석 남는지, 몇 분 기다리는지, 몇 대 보내는지 답하지 않는다. 운영 후보가 상한과 얼마나 벌어졌는지만 잰다.

다음 평가 관문

M3 연구 이력 — 2026-08-15 동결

이 접힌 구역의 M3·코퍼스·프로토타입 수치는 과거 연구 기록이다. 당시 문장에 ‘최신’이나 ‘권위값’이라고 적혀 있어도 현재 공개 평가를 뜻하지 않는다. 현재값은 위 오늘 성적 구역만 읽는다.

Brier0.0022ECCE-MAD0.0023log loss0.01011:1 결정비용0.00262:1 결정비용0.00324:1 결정비용0.0079
M3 권위값

직접 API 응답 582개를 고정해 train 604행·만석 28건, validation 1,901행·만석 8건·날짜 1일로 나눴다.

모델 7개를 paired bootstrap 5,000회와 Holm 21쌍으로 비교했다. 결정은 no_winner, 승자 없음이다. 최소 관문은 validation 날짜 10일·만석 100건이다.

validation 양성 20건 미만이면 만석 누락률·PR-AUC·ROC-AUC 수치를 억제한다. 아래 M1·M2 수치는 역사 기록이며 최신 결론과 섞지 않는다.

M3 직접 수집분 성적

68/32 이동 분할이 아니라 M2 마지막 응답 뒤의 고정 미래구간을 썼다. 검증 1,901행·만석 8건·하루·정류소×날짜 129군집, paired_station_id_x_query_date_cluster_bootstrap 5,000회다.

G · 한계 재보기 + 숫자 다듬기 (raw fallback)

비운영 상한 참조 · M3 고정 미래구간 기술값 · 낮을수록 좋음

지표값 (95% 구간)
Brier · 얼마나 빗나갔나0.0022[0.0001, 0.0053]
ECCE-MAD · 확률 오차가 쌓이나0.0023[0.0021, 0.0035]
log loss · 확신하고 틀린 벌점0.0101[0.0028, 0.0205]
만석 누락 @ .5 · 만석을 안심으로 놓쳤나만석 20건 미만 · 수치 억제
1:1 결정비용 @ .500.0026[0.0000, 0.0061]
2:1 결정비용 @ .330.0032[0.0000, 0.0085]
4:1 결정비용 @ .200.0079[0.0000, 0.0203]
승자는 없다

동결 당시 표본은 validation 날짜 1/10일 (미달), 만석 8/100건 (미달)이다. 만석 민감 지표는 양성 20건부터 숫자를 내며 동결 시점에는 수치 억제였다. 관문은 검토 최소선이지 충분조건이 아니다.

모델별 보정 관문은 미달 — 적격 적용 0/3개 · raw fallback 5,703행이다. 비억제 모델쌍×지표 bootstrap 유효비율 최소값은 100.0%(기준 90%), 운영 후보 비용 방향 뒤집힘은 0/15쌍이다. 마지막 세 날짜 누적 Brier도 승자 전에 확인한다.

하루 조건부 기술 구간과 Holm 계산상 0을 벗어난 Brier 쌍은 10/21쌍이지만 날짜 일반화나 우열 판정이 아니다. 최종 판정은 0/21쌍이다. 만석 8건이면 누락률이 한 사건당 12.5%p 움직인다. PR-AUC·ROC-AUC도 만석 20건 미만이면 억제하며 순위에 쓰지 않는다.

1–4일은 관측 날짜 안 조건부 기술값, 5–9일은 진단 기술값이다. 검증 10일부터도 모든 관문을 통과해야 추론과 승자 선언을 검토한다. 경로·수집구간·날짜·라벨 규칙·관측간격 다섯 축은 한 축씩 기록하고 90초 초과는 검열한다. ECCE 동률은 독립 동결 nonce의 SHA-256 순서로 재현하고 전 행 누적곡선을 남긴다. 이번 재실행은 registry 후보 3,054건 중 기존 nonce 3,054건을 재사용했고 신규는 0건이다.

보정은 이름이 아니라 실제 예측 출처로 판정한다. 이 페이지 변형의 적격 적용은 0/1개, raw fallback은 1,901행이다. 모델별 순방향 fold·실제 calibrated prediction·raw fallback 0행을 모두 확인하기 전에는 보정 우위를 말하지 않는다.

정원·차종은 검증해서 버린 재료가 아니다

M3는 직접 수집분만 쓰고 공식 이력·제원으로 정원·차종 ablation을 실행했다. 직접 관측 고유차량 55/62대에 공식 이력이 연결됐다. 공유 페이지에는 차량번호와 비공개 조인 식별자 값을 싣지 않는다.

새 지표에서 명백한 개선으로 판정한 조합은 0개다. 표본 관문 미달이라 쓸모없다는 뜻은 아니다. 관측 최대 잔여석으로 정원을 추정한 행은 0건이며 계속 금지한다.

이전 공개 평가

아래 값은 이전 공개 평가의 기록이며 현재 점추정과 합치거나 변화율로 계산하지 않는다.

평가평가 규격행Brier
eval-20260815-7e03dc730de91f34evaluation-v12,8940.008799
출처와 검증 장부

오늘 값 — 일일 평가 보고서 daily-20260816-86afbfc70dbb876b(2026-08-16분, 생성 08-17 00:15 KST) · 모델 버전 gradient-boosting-upper-v1+fd482d90 · 평가 규격 evaluation-v2 · 구간 규격 cohort-v1.

이력 — 첫 공개 평가 eval-20260815-f0f59cf25a9c3503 · 자료판 current-7cf2243ffe6c4cdc · 모델 버전 gradient-boosting-upper-v1+cca34cdb · 관측 2026-08-14 16:38 ~ 2026-08-15 11:47 KST · 표본 2,894행 · 만석 23건 · 관측일 1일 · 모델만 변경. 그보다 앞선 eval-20260815-7e03dc730de91f34(evaluation-v1)는 위 M3 연구 이력의 표에 있다.

검증 해시(SHA-256) — 평가 규약 43913ebf483a48a02f6a83e01181a01ccf8bc10a728a38b9e838031ac9dbeec5 · 구현 cca34cdb16f663754e630e9f41abd26b6b441a19dd5002291f18af63f9a21a9a · 평가 산출물 d133e3d6c2db757c5fa780d5ffb19e6998b2dcefc049b844a8faebd64e14a817.