비운영 참조

본사와 지점

계층 로지스틱 회귀

한 줄 결론 — 전체 경향과 노선·정류장·시간 차이를 함께 보는 후보다. 채택되지 못한 채 2026-08-19 결정으로 비운영 참조가 됐다.

왜 믿나 — 아직 채택하지 않는 이유

일일 평가는 앞선 날짜로 학습하고 뒤 날짜만 채점하는 시간순 분할로 매일 다시 계산해 왔다. 관측일과 만석 관측일이 모델 비교 가능 관문 기준을 채우기 전에는 모든 수치를 잠정으로 표시한다.

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

재표본 결과가 원장에 없어 불확실성 범위는 만들지 않는다. 아래 수치는 해당 평가 자료 안의 점추정으로만 읽는다. 기준선·관문·지표 정의는 평가 규약에 있다.

동결 이력 성적

종합 점수
53.5

상태 잠정 평가행 18,055 · 만석 173 · 비만석 17,882 · 모델 버전 hierarchical-logistic-v2+fd482d90

평가 관측일
2일 / 10일
만석 누적
173건 / 100건
만석 관측일
2일 / 5일
지표오늘 값읽는 법
Brier0.0095예측확률과 실제 0·1의 제곱 오차 평균. 낮을수록 좋다.
만석 누락률100.0%실제 만석 중 확률 50% 미만으로 말한 비율. 낮을수록 좋다.
ROC-AUC0.809만석·비만석 한 쌍에서 만석에 더 높은 확률을 줄 가능성. 높을수록 좋다.
Log loss0.0486확신하고 틀릴수록 커지는 벌점. 낮을수록 좋다.
ECCE-MAD0.0066확률 순서로 누적한 오차가 가장 크게 벌어진 정도. 낮을수록 좋다.
PR-AUC0.054드문 만석을 위쪽으로 모으는 힘. 높을수록 좋다.
확률 쏠림0.0066평균 예측확률에서 실제 만석률을 뺀 값. 0에 가까울수록 좋다.
비용 1:10.0096잘못 안심과 과한 경고를 같은 비용으로 둔 평균. 같은 가정끼리 낮을수록 좋다.
비용 2:10.0192잘못 안심을 2배 비용으로 둔 평균.
비용 4:10.0421잘못 안심을 4배 비용으로 둔 평균.

구간별 성적

구간행만석Brier만석 누락ROC-AUC
주말18,0551730.0095100.0%0.809
출근2,70200.0006——
퇴근4,195120.0045100.0%0.958
그 외11,1581610.0136100.0%0.837
노선 16507,5321600.0198100.0%0.767
노선 333010,523130.0021100.0%0.842
노선 1650·출근97000.0003——
노선 1650·퇴근1,694120.0067100.0%0.969
노선 1650·그 외4,8681480.0283100.0%0.745
노선 3330·출근1,73200.0008——
노선 3330·퇴근2,50100.0030——
노선 3330·그 외6,290130.0022100.0%0.928

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

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

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

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

현재 시각·노선·목표 정류장을 바탕으로, 목표 정류장 출발 뒤 남은 좌석이 0일 확률을 구한다.

Q. 어떻게 계산하나?

운영 버전 hierarchical-logistic-v2 기준이다. 이름과 달리 랜덤 효과 모델이 아니라, 수준별로 다른 L2 벌점을 건 단일 로지스틱 회귀다.

순방향 학습 건을 고른다

평가일보다 앞선 한국 표준시 날짜의 확정 통과 사건만 학습에 넣는다. 학습 관측만으로 노선별 정류장 축척을 만든다.

단일 설계 행렬을 만든다

절편과 0~1로 바꾼 연속 정류장 위치에 시간대(출근·퇴근·그 외)·노선·노선×정류장·노선×시간대 범주를 0 또는 1인 열(원-핫)로 더한다. 모든 항을 하나의 로지스틱 회귀에서 함께 맞춘다.

수준별 규제를 건다

계수가 지나치게 커지지 않게 하는 L2 규제를 1.0으로 두고, 벌점 가중치는 정류장 위치·시간대 0.25, 노선 0.75, 노선×시간대 1.5, 노선×정류장 2.0, 절편 0.01로 다르게 건다. 희소해지기 쉬운 노선×정류장 항을 가장 세게 누른다.

계수와 확률을 계산한다

수치 최적화 알고리즘 L-BFGS-B로 벌점 로지스틱 계수를 맞춘다. 각 입력의 선형 계산값을 로지스틱 함수로 0과 1 사이 만석확률로 바꾼다. 랜덤 효과의 사후분포가 아니다.

다음 날짜에서 평가한다

다음 한국 표준시 날짜에 확률을 적용하고, 성능은 일일 평가의 전체·고정 구간·이력에서 읽는다.

이 방식의 강점

재료 한눈에

재료 정보는 이 표가 정본이다. 운영 버전 hierarchical-logistic-v2 기준이다.

재료쓰임비고
노선원-핫 범주항 · 벌점 0.75두 노선의 기저 차이를 분리한다.
정류장 순번 → 연속 위치0~1 연속 특징 · 벌점 0.25학습 구간에서 관측된 노선별 최소·최대 순번으로 축척을 만든다.
시간대(출근·퇴근·그 외)원-핫 범주항 · 벌점 0.25, 노선×시간대 1.5시간은 세 범주로만 표현한다. 연속 시각과 평일·주말 구분은 넣지 않는다.
노선×정류장원-핫 범주항 · 벌점 2.0희소해지기 쉬워 가장 세게 누른다.
출발 뒤 remainSeatCnt라벨 생성에만 사용0이면 만석, 1 이상이면 비만석. -1·결측·출발 전 상태는 라벨로 쓰지 않는다. 예측 입력이 아니다.
노선×정류장×시간대 셀 항안 씀v2 구현에 없다. 연구 단계(v1) 구현에는 있었다.
현재 좌석·위치·상태·운행 간격안 씀이 후보는 역사적 시공간 위험만 본다. 같은 구간의 당일 급변에는 반응하지 못한다.
정원·점유율안 씀코퍼스 차량과 외부 정원의 조인이 0/77대, 옛 231,048행의 capacity_exact도 전부 0이었다. 라벨에는 정원이 필요 없다.
crowded안 씀공식 제공 노선유형(13·15·23) 밖의 노선(유형 11)이고 산식이 미확정이다.
queryTime안 씀서버 시계 되감김이 반증됐다. 시간대는 수집기의 응답 수신 시각으로만 만든다.

라벨 정의·분할 규칙·검열 처리의 공통 기준은 평가 규약에 있다.

Q. 보정은 실제로 적용됐나?

이 모델 자체에는 보정층을 적용하지 않는다. 보정 전에 낸 확률을 그대로 평가한다. 별도 보정층은 숫자 다듬기 · Platt 확률 보정이 담당한다.

Q. 언제 실패하나?

함께 읽을 한계

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

관문 기준·구간 정의·지표 정의·분할 규칙 등 공통 규약은 평가 규약 한 곳에 있다.

연구 워크스루 — 왜 이 구조가 나왔나

이 해설은 v1 연구 구현 기준이다. 운영 버전은 hierarchical-logistic-v2+fd482d90이다. v2는 30분대 대신 출근·퇴근·그 외 세 범주를 쓰고, 노선×정류장×시간대 셀 항과 isotonic 보정이 없다. 노선도 고정효과가 아니라 벌점 0.75 규제를 받고, 연속 정류장 위치 항이 새로 들어갔다. 아래 수치와 구조는 연구 당시 기록이다.

1. Q. 왜 셀 비율을 그대로 쓰지 않나?

정류장×30분대 셀은 833개다. 이 중 281개(33.73%)는 학습 표본이 10건 이하다. 719개(86.31%)는 만석을 한 번도 못 봤다. 0회라는 기록과 만석 위험 0%는 같은 말이 아니다.

위치와 시간 자체는 강한 신호였다. 정류장·시간만 본 기준선의 검증 AUC는 .9613이었다(위치 단독 .9336, 시간 단독 .6375). 하지만 셀 비율을 그대로 쓰면 학습에서 만석 0건인 셀에 확률 0을 줬다. 그 결과 log loss가 .1318이었다. 의사표본 1개만 섞어도 .1033으로 내려갔다. 셀은 살리되 얇은 셀의 확신은 눌러야 했다.

여기서 계층 로지스틱이 나왔다. 정류장 효과와 시간 효과를 따로 배우고, 둘이 만난 셀 효과도 남긴다. 표본이 적은 효과는 0 쪽으로 당기고, 기록이 쌓인 효과는 더 멀리 움직인다. 하루 매출 한 건만 나온 프랜차이즈 지점을 그 한 건으로 단정하지 않고, 본사 평균과 다른 날 기록도 함께 보는 것과 같다.

그림 1 · 한 셀을 네 효과로 푼다
노선·정류장·30분대
노선 분리
노선 고정효과
0 중심 Gaussian 규제
부분 풀링
노선×정류장 효과
노선×30분대 효과
정확한 셀 효과 · 4배 규제
더함
로짓 합
σ, 그 뒤 1-p
만석확률 → 탈 확률

v1 연구 구현 기준. 노선은 고정효과다. 정류장·30분대·정확한 셀은 0 중심 Gaussian 규제를 받는다.

2. Q. 한 셀을 어떻게 나누나?

Q. 무엇을 더하나?

모델은 만석확률을 먼저 낸다. 사용자에게 보이는 탈 확률은 그 여집합이다.

p_full = σ(절편 + 노선 + 노선×정류장 + 노선×30분대 + 정확한 셀)

30분대는 KST 응답 수신 시각으로 만든다. σ는 더한 점수를 0과 1 사이 확률로 바꾸는 로지스틱 함수다. 마지막에 p_board = 1 - p_full로 뒤집는다.

Q. “공통 분포”는 실제 코드에서 무엇인가?

노선은 규제하지 않는 고정효과다. 노선×정류장 139개, 노선×30분대 12개, 정확한 셀 833개는 0을 중심으로 한 Gaussian 규제를 받는다. 랜덤효과 계수는 모두 984개다.

완전한 베이즈 추론은 아니다. 계수의 사후분포를 뽑지 않고, 로지스틱 손실과 Gaussian 벌점을 함께 최소화한 MAP 추정이다. 벌점 후보 .5, 1, 2, 4, 8, 16, 32를 학습 구간 안의 날짜 순방향 2-fold로 겨뤘고 .5가 골라졌다.

Q. 셀 효과는 왜 더 세게 누르나?

정류장 효과와 시간 효과의 벌점은 .5다. 정확한 셀은 그 4배인 2.0이다. 셀 하나의 우연한 0회·1회보다 여러 시간에 반복된 정류장 성향과 여러 정류장에 반복된 시간 성향을 먼저 믿겠다는 뜻이다.

처음 보는 정류장×시간 조합에는 정확한 셀 효과가 0으로 들어간다. 정류장과 시간을 학습에서 봤다면 두 효과는 그대로 남는다. 정류장 자체도 처음이면 그 효과까지 0이 된다.

그림 2 · 안양시청 18:00 셀의 점수
절편-4.0796
3330-0.9832
안양시청+3.2674
18:00+0.1977
정확한 셀-0.3685
합-1.9661
raw p_full+0.1228
isotonic p_full+0.1181

학습 6건·만석 0회인 셀도 다른 시간의 정류장 효과를 받아 raw 만석확률 .1228이 됐다.

3. Q. 실제 숫자는 어떻게 합쳐지나?

코퍼스 학습분 12,065건·만석 705건으로 적합한 값이다. 3330번 안양시청 정류장(ID 209000108), 18:00~18:30 셀을 본다. 이 셀의 학습 표본은 6건이고 만석은 0건이었다. 같은 정류장의 여섯 30분대를 합치면 141건 중 만석 33건이었다.

더하는 항적합값
절편-4.0796
3330 노선-0.9832
3330×안양시청+3.2674
3330×18:00~18:30+0.1977
안양시청×18:00~18:30 셀-0.3685
합-1.9661

σ(-1.9661) = .1228이다. 셀 비율만 보면 0/6 = 0%지만, 부분 풀링한 보정 전 만석확률은 12.28%다. 학습 안에서 날짜순으로 떼어 낸 예측값에 isotonic(단조) 보정을 맞추면 .1181이 된다. 최종 탈 확률은 1 - .1181 = .8819, 88.19%다. 시간순 검증에서도 이 셀은 8건 중 만석 0건이었다. 8건만으로 0%와 11.81% 중 어느 쪽이 맞는지는 가릴 수 없다.

Q. 그래서 기준선을 이겼나?

아니다. 아래는 코퍼스 검증 10,040건·만석 583건에서, 각 후보군의 대표 변형을 비교한 값이다. 계층 로지스틱은 isotonic 변형이다.

지표정류장·시간 기준선계층 로지스틱좋은 방향
ECE.0063.0090낮음
Brier.0327.0341낮음
log loss.1033.1079낮음
AUC.9613.9628높음
비대칭 log loss.1670.1815낮음

AUC만 .0015 높았다. ECE·Brier·log loss·비대칭 log loss는 모두 나빠졌다. 순서는 조금 더 잘 세웠지만 확률값은 기준선보다 못 맞췄다. 재료별 채택·제외는 위 「재료 한눈에」 표가 정본이다.

4. Q. 어떤 그림으로 보면 되나?

그림 1은 한 셀을 노선·정류장·시간·정확한 셀 효과로 나누는 흐름이다. 그림 2는 안양시청 18:00 셀의 실제 적합값을 더하는 눈금이다. 기준선 비교는 3번 표에 있다.

5. Q. 연구에서는 언제 깨졌고, 프로토타입과 무엇이 다른가?

Q. 연구 구현은 언제 약했나?

Q. 프로토타입과 무엇이 다른가?

프로토타입계층 로지스틱
화면의 탑승 확률은 정류장×평일/주말×30분대의 마지막 스냅샷에서 1-zeroCount/samples로 계산했다.출발 후 0석 라벨로 만석확률을 직접 학습하고 1-p_full을 탈 확률로 낸다.
셀 비율을 그대로 썼다. 얇은 셀을 다른 정류장·시간과 묶지 않았다.정류장·시간·정확한 셀 효과를 나눠 부분 풀링한다.
차량 좌석 예보는 현재 잔여석과 수요 μ·σ를 0~80석 분포로 전파한 별도 계산이었다.좌석 수를 예보하지 않는다. 노선·정류장·30분대만으로 확률 하나를 낸다.
좌석 예보, +10 여유폭, 만석 연속으로 여유/빠듯/어려움을 정했다.+10, 만석 연속, 대기열, 이동 추천을 쓰지 않는다.
확률 보정층이 없었다.학습 안에서 날짜순으로 떼어 낸 예측값으로 Platt와 isotonic을 따로 검정했다. 이 모델에서는 isotonic도 기준선보다 나빴다.
재료 출처 필드 장부 — v1 연구 구현 기준

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

재료종류어느 API의 어느 필드
노선 (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 마스터
목표 정류장 ID (station_id)차량별 정규화 위치가 전진한 끝점의 station_seq를 만들고, 같은 노선의 staOrder와 맞춰 stationId를 붙인다.주의 — 응답의 msgBody.busLocationList[].stationId를 목표 통과 정류장 ID로 복사하지 않는다. 그 값은 응답 시점 차량 위치의 정류장이다.파생msgBody.busLocationList[].vehId, msgBody.busLocationList[].stationSeq, msgBody.busLocationList[].stateCd; routestation.routeName, routestation.staOrder, routestation.stationId; S1 station_idGBIS 버스위치정보 getBusLocationListv2 + GBIS routestation 마스터 + S1 통과 사건 빌더
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
노선×정류장 효과 (route_station)route + '|' + station_id 문자열 범주를 만든다.주의 — 원 API에 같은 이름의 필드는 없다. 학습에서 못 본 조합은 새 범주로 처리하지 않고 구현의 기본 효과로 돌아간다.파생S1 route, station_id → 모델 내부 route_station계층 로지스틱 내부 조합
노선×30분대 효과 (route_time)route + '|' + query_half_hour 문자열 범주를 만든다.주의 — 원 API 필드가 아니다.파생S1 route, query_half_hour → 모델 내부 route_time계층 로지스틱 내부 조합
노선×정류장×30분 셀 효과 (cell)route + '|' + station_id + '|' + query_half_hour 문자열 범주를 만든다.주의 — 얇은 셀을 그대로 독립 비율로 쓰지 않고 상위 효과와 함께 축소한다.파생S1 route, station_id, query_half_hour → 모델 내부 cell계층 로지스틱 내부 조합
출발 후 만석 라벨 (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 통과 사건 빌더

지금은 안 쓰는 재료 4개

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

이 접힘 안의 수치는 과거 연구와 이전 공개 평가의 기록이다. 당시 문장에 ‘최신’이나 ‘권위값’이라고 적혀 있어도 현재 성적을 뜻하지 않는다. 현재값은 위 오늘 성적 구역만 읽는다. 위 워크스루의 코퍼스 ECE·AUC 표와 68/32 이동 분할도 같은 연구 기록이다.

이전 공개 평가

평가평가 규격모델 버전행Brier
eval-20260815-7e03dc730de91f34evaluation-v1hierarchical-logistic-v2+fbebba552,8940.0086
eval-20260815-f0f59cf25a9c3503evaluation-v2hierarchical-logistic-v2+cca34cdb2,8940.0086

eval-20260815-f0f59cf25a9c3503 표본: 2,894행 · 만석 23건 · 비만석 2,871건 · 관측일 1일 · 만석 관측일 1일 · 잠정. 관측 기간 2026-08-14 16:38 KST ~ 2026-08-15 11:47 KST · 이 평가에 보정층을 적용한 행은 0행.

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 직접 수집분 성적 — B · 본사와 지점 + 숫자 다듬기 (raw fallback)

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

지표값 (95% 구간)
Brier · 얼마나 빗나갔나0.0046[0.0009, 0.0097]
ECCE-MAD · 확률 오차가 쌓이나0.0194[0.0145, 0.0244]
log loss · 확신하고 틀린 벌점0.0347[0.0219, 0.0525]
만석 누락 @ .5 · 만석을 안심으로 놓쳤나만석 20건 미만 · 수치 억제
1:1 결정비용 @ .500.0042[0.0000, 0.0099]
2:1 결정비용 @ .330.0084[0.0000, 0.0199]
4:1 결정비용 @ .200.0168[0.0000, 0.0397]
승자는 없다

동결 당시 표본은 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건이며 계속 금지한다.

출처와 검증 장부