NYC 택시 수요 예측 파이프라인 만들기 (1) 프로젝트 설계
모델 학습에서 끝나지 않고 데이터 적재부터 배포와 모니터링까지 만들어보는 End-to-End ML 프로젝트의 설계를 정리했습니다.
들어가며
캐글 노트북에서 모델을 학습하고 점수를 확인하는 것으로 끝나는 프로젝트는 이미 여러 번 해봤습니다. 그런데 실제 서비스에서 머신러닝이 동작하려면 그 앞뒤로 훨씬 많은 것이 필요합니다. 데이터는 어떻게 모으고 검증할지, 모델은 어디에 저장하고 어떻게 배포할지, 배포한 뒤 성능이 떨어지면 어떻게 알아챌지 같은 것들이요.
그래서 이번에는 데이터 적재부터 학습, 배포, 모니터링, 재학습까지 전체 사이클을 직접 구축하는 것을 목표로 프로젝트를 시작합니다. 이 글은 그 첫 번째 기록으로, 문제 정의와 전체 설계를 정리합니다.
무엇을 만드나
NYC Yellow Taxi 운행 데이터를 이용해, 특정 날짜, 시간, 지역이 주어졌을 때 다음 1시간 동안 발생할 택시 승차 건수를 예측합니다.
- 입력: 예측 기준 시각, 승차 지역(
PULocationID), 요일, 월, 시간대 같은 달력 변수, 최근 1시간, 24시간, 7일의 수요, 이동평균과 지연(lag) 변수 - 출력: 해당 지역에서 다음 1시간 동안 예상되는 승차 건수
pickup_count - 평가 지표: MAE, RMSE, RMSLE에 더해 지역별, 시간대별 MAE와 추론 시간까지 기록
데이터는 NYC TLC 공식 Trip Record Data를 사용합니다. 운행 단위의 원본 기록을 PULocationID × 1시간 단위로 집계해 학습 데이터를 만들고, 초기에는 1개월분으로 전체 흐름을 검증한 뒤 여러 달로 확장할 계획입니다.
시계열 문제이므로 무작위 분할 대신 시간 순서에 따른 학습, 검증, 테스트 분할을 사용합니다.
전체 아키텍처
flowchart TD
A[NYC TLC 원본 데이터] --> B[Airflow 수집 및 검증]
B --> C[MinIO Raw Storage]
C --> D[정제 및 시간대별, 지역별 집계]
D --> E[PostgreSQL Feature Table]
E --> F[LightGBM 및 PyTorch 학습]
F --> G[MLflow 실험 및 모델 관리]
G --> H[FastAPI 예측 API]
H --> I[성능 및 데이터 변화 모니터링]
I --> F
모니터링 결과가 다시 학습으로 이어지는 루프가 이 프로젝트의 핵심입니다. 한 번 배포하고 끝나는 게 아니라, 데이터가 변하면 그걸 감지하고 재학습하는 흐름까지 만드는 것이 목표입니다.
모델은 단순한 것부터
복잡한 모델이 항상 좋다고 가정하지 않고, 세 단계로 나눠 동일한 데이터 분할과 지표로 비교합니다.
- Baseline: 직전 시간 수요, 전날 같은 시간 수요, 최근 7일 같은 시간 평균
- Machine Learning: Linear Regression, Random Forest, LightGBM
- Deep Learning: MLP, LSTM 또는 TCN
Baseline을 먼저 두는 이유는 명확합니다. “전날 같은 시간 수요”만으로도 꽤 잘 맞는 문제라면, 그보다 못한 딥러닝 모델은 아무리 구조가 멋져도 의미가 없기 때문입니다.
기술 스택
| 영역 | 기술 | 선택 이유 |
|---|---|---|
| Data Processing | Pandas (확장 시 PySpark) | 1개월분은 Pandas로 충분, 스케일업 여지만 남겨둠 |
| Object Storage | MinIO | S3 호환 API를 로컬에서 재현 |
| Database | PostgreSQL | Feature 테이블 + Airflow/MLflow 메타 DB 겸용 |
| Workflow | Apache Airflow | 수집과 집계 파이프라인 스케줄링 |
| ML / DL | scikit-learn, LightGBM, PyTorch | 모델 단계별 비교 |
| Experiment Tracking | MLflow | 실험 파라미터, 지표, 모델 버전 관리 |
| Serving | FastAPI | 예측 API |
| Monitoring | Evidently, Prometheus, Grafana | 데이터 드리프트 + 서비스 메트릭 |
| Infra | Docker Compose | 전체 스택 로컬 구동 |
전부 Docker Compose로 묶어 로컬에서 돌립니다. 처음부터 다 띄우지는 않고 postgres + minio + mlflow 세 개로 시작해서, 단계가 진행될 때마다 서비스를 추가합니다. Airflow는 의존성 충돌이 심한 패키지라 가상환경에 설치하지 않고 컨테이너로만 구동합니다.
실험 원칙
프로젝트 내내 지킬 원칙을 미리 정해뒀습니다.
- 테스트 데이터는 최종 평가 전까지 모델 선택에 사용하지 않는다
- 모든 모델은 동일한 학습과 검증 기간으로 비교한다
- 성능뿐 아니라 학습 시간, 추론 시간, 메모리 사용량을 함께 기록한다
- 미래 시점 정보를 Feature 생성에 사용하지 않는다 (데이터 누수 방지)
- 실험 파라미터와 결과는 전부 MLflow에 남긴다
앞으로의 계획
- 데이터 1개월분 다운로드 및 스키마 확인, EDA
- 시간대별, 지역별 집계 및 Feature 생성
- 시계열 Baseline vs LightGBM 비교
- PostgreSQL, MinIO, MLflow 연동
- FastAPI 배포, Airflow DAG, 모니터링, 재학습 파이프라인
다음 글에서는 본격적인 작업에 앞서 개발환경(Python, uv, Docker 스택)을 세팅합니다.