인천공항 주차장 예측 대시보드 상세 계획

공식 주차 API를 바탕으로 짠 계획입니다. 계획을 세우면서 모델 입력으로 쓸 추가 공공 API 두 개(시간대별 예상 승객 수, 공휴일)도 확인했습니다.

0. 목표와 성공 기준

대시보드가 답할 질문: "내가 ○시에 도착하면 어느 주차장에 자리가 있을까?", 그리고 "그 예측은 실제로 얼마나 맞았나?"

초기 목표치 (4주 운영 후 실제 데이터로 다시 정합니다) → 우선은 모으는 것에 집중합니다. 아래는 임의로 지정한 지표와 목표입니다.

지표목표
1시간 뒤 예측 오차(점유율, 평균)3%p 이하
3시간 뒤 예측 오차(점유율, 평균)5%p 이하
예측 범위(하위 10%~상위 10%) 안에 실제값이 들어온 비율약 80%
"만차 위험" 경보가 실제 만차를 잡아낸 비율80% 이상
수집 성공률월 99% 이상 (빠진 5분 구간 1% 미만)

1. 데이터 소스

공공데이터포털 서비스키 하나로 아래 API를 모두 신청할 수 있습니다.

용도API호출 주기하루 호출 수
예측 대상: 구역별 주차 대수와 총 면수B551177/StatusOfParking/getTrackingParking5분288
선행 지표: 시간대별 예상 출·입국 승객 (오늘·내일)B551177/passgrAnncmt/getPassgrAnncmt1시간약 48
공휴일·연휴 달력한국천문연구원 특일 정보월 1회약 0
(선택) 날씨기상청 단기예보3시간8

구역 유형별로 움직이는 방식이 다릅니다.

2. 아키텍처 (Azure, MCAP 구독)

flowchart LR
  API["data.go.kr<br/>주차 · 승객예고 · 특일"] --> C["collect<br/>5분"]
  API --> X["exog<br/>1시간"]
  C --> RAW[("Blob raw/<br/>원본 JSON")]
  C --> OBS[("Blob obs/<br/>일별 JSONL")]
  X --> EXO[("Blob exog/")]
  OBS --> FC["forecast<br/>15분"]
  EXO --> FC
  FC --> FCS[("Blob forecasts/<br/>발행분 불변 저장")]
  FCS --> EV["evaluate + publish<br/>1시간 · 매일"]
  OBS --> EV
  EV --> PUB[("public/*.json")]
  C --> PUB
  PUB --> WEB["Static Web Apps<br/>ECharts 대시보드"]
  C -.-> AI["App Insights<br/>20분 무수집 알림"]


구성요소선택예상 월 비용
실행Azure Functions Flex Consumption (Python 3.12), 함수 4개무료 제공량 내외, $0~3
저장소Blob Storage (1년치가 수백 MB 수준)$0.5 미만
비밀값Key Vault (서비스키)약 $0.03
모니터링App Insights (하루 사용량 상한 설정)$0~2
웹Static Web Apps Free$0
배포GitHub + Actions(OIDC 인증) + Bicep$0

비용은 합쳐서 월 $1~5 정도로 추정합니다.

이렇게 짠 이유


검토했지만 뺀 선택지

선택지뺀 이유
GitHub Actions 예약 실행실행이 수 분~수십 분 밀리거나 건너뛰는 일이 흔해 5분 수집에 맞지 않음
Azure SQL serverless5분마다 쓰기가 들어와 자동 일시정지가 안 돼서 비용이 커짐
ADX 무료 클러스터시계열 분석 기능은 강하지만 외부 공개가 안 됨. 개인 분석용 보조로는 쓸 수 있음
Power BI 웹에 게시사내 정책상 보통 막혀 있음

먼저 확인할 위험: MCAP 구독에 Blob 공개 접근을 막는 정책이 걸려 있을 수 있습니다. 그렇다면 Function의 HTTP 엔드포인트가 managed identity로 Blob을 읽어 JSON을 캐시와 함께 내주는 방식으로 바꿉니다. 0단계에서 확인합니다.

3. 데이터 모델

테이블주요 컬럼
zones (구역 목록)zone_id, 터미널, 유형(단기/장기/타워/예약), 원본 구역명·별칭, 사용 기간
observations (실측)5분 구간 시각(KST), zone_id, 주차 대수, 총 면수, 가용 대수, 점유율, 원본 갱신 시각(datetm), 수집 시각, 품질 표시
raw_calls (호출 기록)호출 시각, HTTP 상태, 결과 코드, 응답 시간, 원본 파일 경로
calendar (달력)날짜, 요일, 공휴일 여부, 연휴 묶음 번호, 연휴 며칠째, 연휴까지 남은 날
exog_passenger (예상 승객)날짜, 시간, 터미널, 예상 출국·입국 승객, 가져온 시각
forecasts (예측, 덮어쓰지 않음)발행 시각, 모델·버전, zone_id, 대상 시각, 몇 분 뒤 예측인지, 점유율 예측(중앙값·하위 10%·상위 10%), 가용 대수 예측, 만차 확률
accuracy (정확도 집계)날짜, 모델, 구역, 예측 거리 구간, 요일·시간, 평균 오차, 편향, 적중률, 표본 수

4. 수집기 (collect, 5분마다)

  1. numOfRows=100, type=json으로 호출합니다. 타임아웃은 10초, 실패하면 2초·5초·10초 간격으로 세 번까지 다시 시도합니다.
  2. 받은 응답을 그대로 raw/parking/YYYY/MM/DD/HHmm.json에 저장합니다. 나중에 가공을 다시 하거나 점검할 때 씁니다.
  3. 정리 과정
  4. 품질 표시
  5. obs/YYYY/MM/DD.jsonl에 이어 붙이고, 중복은 읽을 때 걸러냅니다. public/latest.json도 갱신합니다.
  6. 20분 동안 수집 성공이 없거나 원본 갱신 시각이 30분 동안 멈추면 알림을 보냅니다.

5. 예측 모델 (데이터가 쌓이는 만큼 단계적으로)

예측 대상은 구역별 점유율입니다. 총 면수는 공사 등으로 바뀔 수 있어서, 점유율로 예측한 뒤 가용 대수로 바꿉니다. 발행은 15분마다, 15분 간격으로 24시간 뒤까지입니다.

모델방법쓸 수 있는 시점
M0지난주 같은 요일·같은 시각 값 (비교 기준선)수집 1주 뒤
M1최근 4~8주 같은 요일·같은 15분 구간의 가중 중앙값과 상·하위 10% 범위2주 뒤 (4주 뒤 안정)
M1bM1 × (오늘 예상 승객 ÷ 같은 요일 평균 예상 승객)2주 뒤, 연휴 대응
M2M1에 "지금 평소보다 얼마나 다른지"를 더하고, 먼 시간일수록 그 차이를 줄여 반영2주 뒤, 다가오는 몇 시간 예측의 핵심
M3LightGBM 분위수 회귀. 입력: 시간대, 요일, 연휴 정보, 예상 승객, 최근 값(현재·1시간 전·어제·지난주)8~12주 뒤

6. 예측과 실제 비교

7. 대시보드 구성

페이지보여줄 내용
앞으로 24시간 (메인)T1/T2 탭. 오늘 실측(실선), 예측 중앙값(점선), 예측 범위(띠)를 겹쳐 표시하고 현재 시각에 세로선. 만차 위험 시간대 강조. 도착 시각 선택 → 여유 예상 구역 순위와 만차 확률, 최근 정확도를 보여주는 신뢰도 표시
요일 × 시간 패턴최근 8주 기준 7×24 히트맵(점유율 / 만차 확률 / 가용 대수 전환), 요일별 하루 흐름 비교
예측 정확도어제·오늘 예측 대 실제 겹쳐 보기, 예측 거리별 오차 추이, 요일×시간 오차 히트맵, 모델 비교, 특이 상황 기록
장기 추이하루 최고 점유율 달력 히트맵, 연휴 3일 전~3일 후 겹쳐 보기, 주간 평균 추이
방법·출처출처 표시("인천국제공항공사, 공공데이터포털"), 비공식 서비스라는 안내, 데이터 수집률
파일갱신 주기내용
latest.json5분구역별 최신값과 오늘 5분 단위 흐름
forecast.json15분앞으로 24시간 예측
accuracy.json1시간정확도 지표
pattern.json매일요일×시간 통계
history_daily.json매일하루 단위 최고·평균 점유율

8. 저장소 구조

icn-parking-forecast/
  infra/        Bicep (main + modules)
  functions/    function_app.py, collect/, exog/, features/, models/, evaluate/, publish/
  web/          index.html, app.js, charts/, i18n/
  config/       zones.yaml, annotations.yaml
  notebooks/    데이터 탐색
  tests/
  .github/workflows/  infra.yml, functions.yml, web.yml

9. 일정

단계기간산출물완료 기준
0단계오늘~내일API 키 3개 발급, 첫 응답으로 구역 목록 확정, 리소스 그룹 결정, Blob 공개 정책 확인실제 응답을 받음
1단계 (최우선)1~3일수집기 가동, 원본 저장, 알림24시간 동안 288번 모두 수집
2단계1~2주대시보드 첫 버전: 오늘 실측 + 어제·지난주 겹쳐 보기, 수집 현황. M0 예측 발행 시작공개 URL로 접속 가능
3단계2~4주M1·M1b·M2, 정확도 페이지, 요일×시간 히트맵, 운영 계정 신청예측 거리별 정확도가 매일 갱신됨
4단계6~12주M3, 만차 확률 보정, 7일 전망운영 모델이 M0보다 20% 이상 정확
5단계3개월 이후장기 추이·연휴 비교, 전날 밤 "내일 만차 위험" 요약 알림연휴 3회 이상 평가 완료

⚠️ 1단계를 서두를 이유: 과거 데이터는 나중에 소급해서 받을 수 없습니다. 이번 주말 개천절 연휴(10/35)나 한글날 연휴(10/911) 전에 수집을 시작해야 첫 연휴 자료를 확보할 수 있습니다.

10. 위험 요소와 대응

위험대응
API 장애·지연재시도, 누락 구간 표시, 알림. 대시보드에 "데이터 지연" 표시
구역 구성 변경 (신규 주차장, 공사)구역 목록에 없는 이름이 오면 알림, 면수 변경 표시, 구역 목록 이력 관리
연휴 데이터 부족예상 승객 수로 보정(M1b), 1년 뒤 연휴 전용 모델로 전환
예측을 공식 정보로 오해"비공식 · 예측값" 안내 문구. 예상 승객 수를 화면에 보여줄 경우 API 설명에 따라 공항공사 관리부서와 안내 문구 협의 필요 (입력으로만 쓰면 협의 부담이 작음)
개발 계정 한도나 기간 만료공개 시점에 운영 계정으로 전환 (자동 승인)
비용 초과App Insights 하루 사용량 상한, 예산 알림

11. 결정할 사항 (괄호 안이 제가 권하는 기본값)

  1. 공개 범위 (외부 전체 공개)
  2. 배포할 구독 (기존 SWA와 같은 MCAP 구독)
  3. 예측 간격 (15분)
  4. 언어 (한국어 먼저, 영어는 5단계)

계획은 세션의 plan.md에 저장했고, 이 프로젝트 내용은 기억해 두었습니다. 1단계를 서둘러야 하는 만큼 다음 진행 방식을 골라 주세요. API 키는 공공데이터포털에 로그인해서 직접 발급받으셔야 하고, 나머지 코드와 인프라는 제가 준비할 수 있습니다.