이 페이지의 이전 버전을 보고 있습니다. 현재 버전 보기.

현재와 비교 페이지 이력 보기

버전 1 현재 »

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

공식 주차 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
  • 합계가 하루 약 350회라서 개발 계정(주차·승객예고 API는 하루 1,000회) 안에 들어옵니다. 공개할 때는 운영 계정으로 올립니다.
  • 예상 승객 수가 중요한 이유: 연휴·명절 효과를 주차 데이터만으로 배우려면 1년이 필요합니다. 공항공사가 매일 내는 오늘·내일 예상 승객 수를 넣으면 첫 연휴부터 대응할 수 있습니다.

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

  • 장기주차장·주차타워는 며칠에 걸쳐 차가 쌓입니다. 연휴 전에 차오르고 연휴가 끝나면 빠집니다. 그래서 "지난 3일 출국 승객 − 입국 승객" 같은 누적 값을 입력으로 씁니다.
  • 단기주차장은 몇 시간 단위로 들고 납니다. 시간대별 출국 승객 수를 입력으로 씁니다.

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

%%{init: {'theme':'neutral'}}%% 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 정도로 추정합니다.

이렇게 짠 이유

  • 방문자는 미리 계산해 둔 JSON만 읽습니다. 사람이 몰려도 공공 API 호출 한도나 계산 비용에 영향이 없습니다.
  • 데이터가 하루 약 5,500행(19개 구역 × 288회)으로 작습니다. 그래서 DB 없이 일별 JSONL 파일을 DuckDB로 바로 읽는 구조로 충분합니다.


검토했지만 뺀 선택지

선택지뺀 이유
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 (정확도 집계)날짜, 모델, 구역, 예측 거리 구간, 요일·시간, 평균 오차, 편향, 적중률, 표본 수
  • 첫 구역 목록은 19개입니다(현재 외부 사이트 기준, 1단계 첫 응답으로 확정).
    • T1 10개: 단기 지하1·2·3층·지상층, 장기 P1·P2·P3, P1·P2 주차타워, P5 예약
    • T2 9개: 단기 지하M층·지상1~4층, 장기, P1·P2 주차타워, 예약
  • 예약주차장은 일반 이용자 추천에서 따로 분리합니다.

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

  1. numOfRows=100, type=json으로 호출합니다. 타임아웃은 10초, 실패하면 2초·5초·10초 간격으로 세 번까지 다시 시도합니다.
  2. 받은 응답을 그대로 raw/parking/YYYY/MM/DD/HHmm.json에 저장합니다. 나중에 가공을 다시 하거나 점검할 때 씁니다.
  3. 정리 과정
    • 구역 이름(floor)을 구역 목록과 맞춥니다. 목록에 없는 이름이 나오면 알림을 보냅니다(신규 주차장이나 이름 변경 감지).
    • 가용 대수와 점유율을 계산합니다. 총 면수가 0이면 미운영으로 처리합니다.
  4. 품질 표시
    • STALE: 원본 갱신 시각이 직전과 같음 (원천 데이터가 멈춤)
    • OVER: 주차 대수가 총 면수보다 많음
    • CAPCHANGE: 총 면수가 바뀜 (공사 등)
    • GAP: 수집이 빠진 구간
  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주 뒤
  • 운영 모델 선택: 모든 모델이 예측을 계속 내고, 최근 14일 오차율이 가장 낮은 모델을 대시보드에 보여줍니다. 구역 유형 × 예측 거리별로 따로 고릅니다.
  • 예측에서 뽑는 결과
    • 가용 대수 예측
    • 만차 확률: 가용 대수가 50대 또는 총 면수의 3% 중 큰 값보다 적을 확률
    • 도착 시각별 여유 구역 순위: 보수적 값(하위 10%) 기준

6. 예측과 실제 비교

  • 예측은 발행 당시 값 그대로 보관합니다. 발행 시각과 모델 버전(git 커밋)을 붙여 저장하고, 나중에 다시 계산해서 덮어쓰지 않습니다. 그래야 "그때 뭐라고 예측했나"를 정직하게 잴 수 있습니다.
  • 평가는 1시간마다 합니다. 대상 시각이 지난 예측을 가장 가까운 5분 실측값과 짝지어 비교합니다.
  • 지표
    • 평균 오차(%p와 대수 두 가지)
    • 편향: 늘 높게 또는 낮게 예측하는지
    • 오차율
    • 예측 범위 적중률
    • 만차 경보가 맞은 비율과 놓친 비율
  • 나눠 보는 기준: 모델, 구역·터미널, 예측 거리(1시간 이내 / 13시간 / 36시간 / 6~24시간), 요일 × 시간
  • 특이 상황 기록: 오차가 컸던 날에 연휴, 데이터 누락, 면수 변경을 자동으로 표시합니다. 폭설이나 공사 같은 메모는 annotations.yaml에 직접 적습니다.
  • 흐름 변화 감지: 최근 7일 편향이 ±5%p를 넘는 날이 3일 이어지면 알림을 보내고 재학습 대상으로 표시합니다.

7. 대시보드 구성

페이지보여줄 내용
앞으로 24시간 (메인)T1/T2 탭. 오늘 실측(실선), 예측 중앙값(점선), 예측 범위(띠)를 겹쳐 표시하고 현재 시각에 세로선. 만차 위험 시간대 강조. 도착 시각 선택 → 여유 예상 구역 순위와 만차 확률, 최근 정확도를 보여주는 신뢰도 표시
요일 × 시간 패턴최근 8주 기준 7×24 히트맵(점유율 / 만차 확률 / 가용 대수 전환), 요일별 하루 흐름 비교
예측 정확도어제·오늘 예측 대 실제 겹쳐 보기, 예측 거리별 오차 추이, 요일×시간 오차 히트맵, 모델 비교, 특이 상황 기록
장기 추이하루 최고 점유율 달력 히트맵, 연휴 3일 전~3일 후 겹쳐 보기, 주간 평균 추이
방법·출처출처 표시("인천국제공항공사, 공공데이터포털"), 비공식 서비스라는 안내, 데이터 수집률
  • 화면은 정적 HTML과 Apache ECharts로 만듭니다. 히트맵, 달력, 범위 띠를 그대로 지원합니다. 모바일을 먼저 생각하고, 필요하면 한/영 전환을 넣습니다.
  • 대시보드가 읽는 JSON 파일
파일갱신 주기내용
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 키는 공공데이터포털에 로그인해서 직접 발급받으셔야 하고, 나머지 코드와 인프라는 제가 준비할 수 있습니다.

  • 레이블 없음