feat: 입소 예측 정확도를 백테스트로 측정하고 공개 - #125
Merged
Merged
Conversation
확률을 보여주면서 그 확률이 맞는지 확인한 적이 없었다. 정원 관측 시계열이 이미 쌓이므로 예측을 기록해 몇 달 기다릴 필요 없이 과거 시점을 재현해 검증할 수 있다. - AdmissionForecastCalculator: 예측 계산을 순수 클래스로 분리. 라이브와 백테스트가 같은 코드를 쓴다 (검증용을 따로 구현하면 무엇을 검증했는지 알 수 없다). - ForecastBacktestService: 기준일 이전 관측만으로 예측을 재계산하고 이후 구간 관측으로 실제 결과를 확인. 기준일을 30일씩 옮기며 표본을 모은다. 확률대별 적중률, Brier 점수, 기준선(항상 평균으로 답했을 때)을 기록. - TBL_FORECAST_ACCURACY (V20): 기간별(1·3·6개월) 측정 결과. - 표본이 30건 미만이면 정확도를 내보내지 않고, 구간 표본 10건 미만이면 그 구간만 비운다. - 예측 응답에 accuracy(같은 확률대의 실제 적중률) 추가, GET /facilities/forecast-accuracy 공개. - 주 1회 자동 측정(일 04:30) + POST /api/admin/sync/forecast-accuracy/measure 수동 실행.
통합 테스트 클래스를 추가하면서 컨텍스트가 14개까지 떠, 기본 힙으로는 워커가 OutOfMemoryError 로 죽었다(GC 스래싱으로 실행 시간도 3분 34초 → 9분 55초로 늘었다). 컨텍스트마다 JPA·커넥션풀·캐시를 들고 있어 개수가 곧 메모리다. - maxHeapSize 2g - spring.test.context.cache.maxSize=6: 기본값(32)이면 한 번 뜬 컨텍스트가 끝까지 남아 클래스를 추가할 때마다 메모리가 계단식으로 늘어난다. 넘치면 오래된 컨텍스트를 닫는다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #124
왜
확률을 보여주면서 그 확률이 맞는지 확인한 적이 없었다. 사용자는 이 숫자를 보고 다른 시설을 포기할 수도 있다.
정원 관측 시계열이 이미 쌓이므로 과거 시점을 재현해 검증할 수 있다. 예측을 기록하고 몇 달 기다릴 필요가 없다.
무엇
AdmissionForecastCalculatorForecastBacktestServiceTBL_FORECAST_ACCURACY(V20)accuracy,GET /facilities/forecast-accuracy(공개)POST /api/admin/sync/forecast-accuracy/measure(수동)기준선을 함께 기록하는 이유: 예측이 "평균으로 답하기" 보다 못하면 확률을 보여줄 근거가 없다. 응답의
betterThanBaseline로 그대로 드러난다.표본이 적으면 숨긴다: 전체 30건 미만이면 정확도를 아예 내보내지 않고, 구간 표본 10건 미만이면 그 구간만 비운다. "3건 중 3건 적중 = 100%" 는 근거 없는 확률보다 더 나쁘게 오해를 만든다.
측정 기간에 1·3개월을 둔 이유: 6개월만 재면 관측이 6개월 넘게 쌓인 시설이 있어야 표본이 생겨 수집 초기에는 아무것도 검증할 수 없다.
테스트
ForecastBacktestServiceTest(7) — look-ahead 방지(기준일 이후 관측이 예측에 섞이지 않음), 구간표 합계 = 전체 표본, 기준선 기록, 기간별 분리, 시설 수 상한ForecastAccuracyServiceTest(6) — 표본 부족 시 숨김, 구간 매칭, 깨진 JSON 격리ForecastAccuracyContractTest— 측정 전 빈 목록 → 관리자 측정(일반 회원 403) → 공개 노출 → 예측 응답의 accuracy 까지 한 흐름두 번째 커밋 (test)
이 PR 로 컨텍스트가 14개가 되면서 테스트 워커가 OutOfMemory 로 죽었다(실행 시간도 3분 34초 → 9분 55초). 힙 2g +
spring.test.context.cache.maxSize=6으로 고정했다. 지금은 3분 34초.한계
관측이 쌓인 만큼만 검증된다. 수집 초기에는 1개월 기간만 표본이 모이고, 그마저 30건 미만이면 화면에 아무것도 나가지 않는다 — 의도한 동작이다.