END-TO-END REGRESSION PIPELINE
PYTHON 3.13 · SCIKIT-LEARN · FASTAPI · RENDER
USED CAR PRICE PREDICTOR
An automated, data-driven machine learning system that estimates fair used automobile market valuations in Indian Rupees (₹) based on 8 physical and operational vehicle parameters.
01 // Problem Statement & ML Framing
The Problem
Buying or selling pre-owned vehicles in India is subjective, unstandardized, and opaque. Private buyers risk overpaying due to asymmetric market data, while sellers struggle to establish competitive, market-grounded listing prices without manual appraisal overhead.
Why Regression?
Classification identifies discrete category buckets (e.g. affordable vs luxury). Because automobile price is a continuous, uninterrupted monetary quantity (e.g., ₹7,75,405.55), this problem is modeled as supervised continuous regression.
8 Input Features Analyzed
• Numerical (3):
year (1980–2026)
km_driven (0–1,000,000 km)
engine_cc (Displacement in cc)
• Categorical (5):
make (Brand: Maruti, Hyundai...)
model (Vehicle Model name)
fuel (Petrol, Diesel, CNG, Electric)
• Operational & Target:
transmission (Manual, Automatic)
owner (First, Second, Third, Fourth+)
Target (y): selling_price (INR ₹)
02 // Data Cleaning & Leakage-Free Pipeline
Real-world automotive datasets contain human formatting variations, such as commas ("35,000") and unit suffixes ("1200 cc"). A custom regex parser sanitizes raw inputs while filtering implausible domain outliers.
Preprocessing Pipeline Architecture
• Numerical Pipe: SimpleImputer(strategy="median") fills missing values with the median, providing robustness against extreme price skew.
• Categorical Pipe: SimpleImputer(strategy="most_frequent") + OneHotEncoder(handle_unknown="ignore") ensures new brands/models encountered in production encode as all-zeros without crashing the web service.
Data Leakage Elimination
Calculating imputation medians or one-hot encodings on the full dataset before splitting causes information from unseen test instances to leak into training. By chaining preprocessing and the estimator into a unified scikit-learn Pipeline, transformations are fitted strictly on X_train during pipeline.fit().
# Unified scikit-learn Pipeline prevents data leakage
numeric_pipe = Pipeline([("imputer", SimpleImputer(strategy="median"))])
categorical_pipe = Pipeline([
("imputer", SimpleImputer(strategy="most_frequent")),
("onehot", OneHotEncoder(handle_unknown="ignore"))
])
preprocessor = ColumnTransformer([
("numeric", numeric_pipe, ["year", "km_driven", "engine_cc"]),
("categorical", categorical_pipe, ["make", "model", "fuel", "transmission", "owner"])
])
pipeline = Pipeline([("preprocessor", preprocessor), ("model", LinearRegression())])
03 // Model Benchmarking & Metrics
Two candidate algorithms were evaluated on an 80/20 train-test split (1,108 training rows, 277 hold-out test rows, random_state=42) using Mean Absolute Error (MAE) and Coefficient of Determination (R²).
| CANDIDATE MODEL |
TEST MAE (INR ₹) |
TEST R² SCORE |
INFERENCE SPEED |
SELECTION OUTCOME |
| Linear Regression |
₹84,198.24 |
0.8079 (~80.8% variance) |
<1 ms (Sub-millisecond) |
SELECTED WINNER |
| Random Forest Regressor |
₹91,965.21 |
0.7628 (~76.3% variance) |
~15 ms (180 Trees) |
REJECTED |
Why Linear Regression Outperformed Random Forest
In this vehicle valuation domain, depreciation correlates strongly and monotonically with age (year) and usage (km_driven). Random Forest slightly overfit the training splits and generalized less smoothly on held-out test points, whereas Linear Regression achieved an MAE approximately ₹7,767 lower, delivering more consistent real-world valuations.
04 // FastAPI Backend & Serving Lifecycle
Pydantic Gateway Validation
Every inbound prediction payload is validated against strict Pydantic schemas (e.g. year: int = Field(ge=1980, le=2026), km_driven: float = Field(ge=0), engine_cc: float = Field(gt=0)). Malformed payloads are intercepted at the API gateway returning HTTP 422 before touching the ML model.
Single-Load Memory Serialization
Model weights and transformers are serialized via Joblib to best_model.joblib. FastAPI loads this artifact into memory once at server startup, enabling instantaneous predictions (<50ms latency) without re-instantiating estimators per request.
Automated Testing Suite (12 Pytest Tests)
Full automated regression coverage across tests/test_api.py: verifies health probes, model metadata serialization, HTML UI delivery, interactive Swagger docs, non-negative prediction clamping (max(0.0, price)), alternative vehicle types (Diesel/Automatic), and boundary validation rejection.
05 // Cloud CI/CD Deployment on Render
Automated GitOps deployment defined via render.yaml blueprint. On every push to GitHub, Render automatically provisions a Python 3.13 container, installs dependencies, executes python train.py to regenerate model artifacts from raw data, and serves the application via Uvicorn.
# render.yaml blueprint
services:
- type: web
name: used-car-price-prediction
runtime: python
buildCommand: pip install -r requirements.txt && python train.py
startCommand: uvicorn app.main:app --host 0.0.0.0 --port $PORT
healthCheckPath: /health