중고차 가격 예측 · 문서

01/ 01

중고차 가격 예측 플랫폼

Owen Lee · 이원빈기존 원고

기존 원고를 임시로 옮겼습니다. 내용과 근거는 순차적으로 다시 정리할 예정입니다.

가격 하나만으로는 판매 시점을 정하기 어려웠다

중고차 가격을 알아보는 사람은 현재 시세만 궁금한 것이 아니다. 지금 파는 것이 나은지, 몇 년 더 타면 감가가 얼마나 커질지, 같은 연식의 다른 차량보다 왜 비싸거나 싼지를 함께 알고 싶다.

차량 가격은 브랜드와 모델, trim, 연식, 주행거리, 색상, 사고 이력처럼 여러 속성이 함께 만든 결과다. 시장에는 판매자와 구매자가 알고 있는 정보의 차이도 크다. 숫자 하나를 제시하더라도 사용자가 그 숫자의 근거를 이해하지 못하면 실제 판매 결정으로 이어지기 어렵다.

이 팀 프로젝트는 현재 예상 가격과 미래 감가 흐름, 가격에 영향을 준 요인을 한 화면에서 설명하는 제품을 목표로 했다. Portfolio에서는 대표 AI agent 프로젝트로 두기보다, 데이터 수집과 모델 artifact, API와 결과 UI를 연결해 본 ML 제품화의 보조 사례로 소개한다.

수집부터 화면까지 네 영역으로 나눴다

flowchart LR
  Source[차량 원천 데이터] --> Collect[수집 · Checkpoint]
  Collect --> Clean[정제 · B/M/T Mapping]
  Clean --> Research[CatBoost Research · W&B]
  Research --> Artifact[Model · Feature Manifest · Metrics]
  Artifact --> API[FastAPI Prediction Service]
  API --> UI[Streamlit Result Experience]
  DB[(Vehicle DB)] --> API

data_collection은 매물 상세 페이지와 성능 기록을 수집하고, 중간 결과와 checkpoint를 남긴다. predict_engine_research는 학습 데이터와 model experiment, W&B tracking을 관리한다. be는 차량 입력을 feature vector로 바꾸고 model runtime을 호출해 frontend용 가격과 요인 결과를 제공한다. fe는 사용자가 차량을 선택하고 결과를 해석하는 Streamlit 화면이다.

루트는 uv workspace로 구성돼 각 영역을 함께 설치할 수 있고, Docker Compose가 frontend와 backend 실행 진입점을 묶는다. 연구 notebook 하나로 끝내지 않고 학습과 serving, 화면의 책임을 분리하려 했다.

차량 이름을 모델 입력으로 바꾸는 과정

원천 데이터의 차량 이름은 항상 같은 형식이 아니다. 브랜드, 모델, trim의 표기가 흔들리거나 상세 이름에 옵션과 세대 정보가 섞인다. 이 상태에서 문자열을 그대로 category로 사용하면 같은 차량이 여러 그룹으로 갈라진다.

수집 영역에는 brand-model-trim reference, 문자열 normalizer, mapping schema와 category/cohort score 모듈이 있다. 먼저 차량 이름을 canonical B/M/T 구조로 맞추고, model이 사용할 category와 비교 cohort를 만든다. 일부 mapping 과정에는 agent client와 prompt, source reference를 분리해 결과가 어떤 기준에서 나왔는지 확인할 수 있게 했다.

Crawler에는 detail page와 performance record 단위의 test와 checkpoint가 있다. VPN 연결을 포함한 수집 보조 script도 별도로 두었다. 수집이 중간에 멈췄을 때 처음부터 다시 시작하지 않고, 원본과 정제 결과의 경계를 유지하기 위한 구성이다.

모델과 API 사이에 contract를 뒀다

Backend는 request를 바로 model object에 넘기지 않는다. Feature vectorizer가 차량 record를 runtime input으로 변환하고, provider가 model asset과 실행 방식을 감싼다. feature_manifest.json은 model이 기대하는 feature를, metrics.json은 저장된 artifact의 평가 정보를 담는다.

Service layer는 prediction 결과와 frontend용 가격 요인, 차량 이미지, 선택적인 AI 설명을 분리한다. DB, AI agent, prediction engine도 각각 client/provider 경계를 갖는다. 모델을 다시 학습하거나 설명 방식을 바꿀 때 frontend API 전체가 model 내부 구조에 묶이지 않게 하기 위한 선택이다.

저장소의 과거 architecture 문서에는 별도 gRPC/ONNX model host가 등장하지만, 현재 checkout의 source tree는 backend 내부 model runtime을 중심으로 구성돼 있다. 이 차이는 숨기지 않고 project가 진행되며 serving 구조를 조정한 흔적으로 본다. 공개 글에서는 현재 source로 확인할 수 있는 구현을 기준으로 설명한다.

결과는 세 층으로 보여준다

Streamlit UI는 차량 정보 입력을 받은 뒤 결과를 현재 가격, 감가 흐름, 요인 설명으로 나눠 보여준다.

  • Result hero는 지금 입력한 차량의 예상 가격을 먼저 보여준다.
  • Price chart와 history tab은 시간이 지나며 가격이 어떻게 변할 수 있는지 비교한다.
  • Factor insights는 주행거리, 연식, 사고 이력, 색상과 차량 category 같은 입력이 결과를 해석하는 데 어떤 역할을 하는지 보여준다.

숫자를 크게 보여주는 것만으로는 충분하지 않아 input summary와 vehicle/accident selector를 함께 둔다. 사용자가 어떤 조건으로 예측했는지 다시 확인하고, 조건을 바꿔 결과 차이를 비교할 수 있게 했다.

검증할 때 나눠 본 것

Backend에는 DB client integration test, AI-agent client와 service unit test, 선택적인 live integration test가 분리돼 있다. Data collection에는 crawler와 mapping/cohort score test가 있고, research workspace에는 experiment config와 W&B run summary가 남아 있다.

다만 portfolio에 쓸 최종 성능 수치와 baseline 비교는 별도 확인이 필요하다. 저장소에 model과 metrics artifact가 있다는 이유만으로 가장 좋은 모델이거나 실제 시장 가격을 보장한다고 말할 수는 없다. Train/test split이 시간과 차량 cohort의 누수를 막았는지, 특정 브랜드와 가격대에서 error가 어떻게 달라지는지까지 함께 봐야 한다.

모델이 설명하지 못하는 것

중고차 시장은 계속 변한다. 같은 차량도 지역과 계절, 신차 출시, 금리와 유가, 매물 상태에 따라 가격이 달라질 수 있다. 사고 이력과 옵션도 source data의 품질이 낮으면 정확히 반영하기 어렵다. 예측 결과는 판매가를 보장하는 견적이 아니라 의사결정을 돕는 참고 정보다.

미래 감가 역시 실제 미래를 알고 계산한 값이 아니다. 현재 데이터에서 학습한 경향을 조건부로 확장한 결과이므로, horizon이 길어질수록 불확실성이 커진다. 제품 화면에는 point estimate만이 아니라 data 기준 시점과 한계, 가능하다면 prediction interval을 함께 보여주는 방향이 필요하다.

이 프로젝트에서 남은 것

모델을 학습하는 것과 모델을 사용하는 제품을 만드는 것은 다른 작업이었다. 원천 문자열을 안정적인 category로 바꾸고, feature contract를 맞추고, API와 화면에서 사용자가 입력과 결과를 다시 확인할 수 있어야 비로소 하나의 예측 경험이 된다.

이 프로젝트의 의미는 특정 algorithm 이름보다 그 연결에 있다. 데이터 수집, 정제, experiment, model serving, 설명 UI가 서로 어떤 artifact와 interface를 주고받는지 직접 구성해 본 첫 번째 ML 제품화 사례다.

원고 연결

전체 원고: 00_원본 전체 원고 — SKN28 1차 — 중고차 가격·감가 예측 플랫폼