This project analyzes 426,880 used-vehicle listings to identify the factors that drive used-car prices and turns those findings into inventory and pricing recommendations for a used-car dealership. The full analysis, following the CRISP-DM process, is in what_drives_the_price.ipynb.
This analysis is conducted as a component of the curriculum requirements for the Professional Certificate in Machine Learning and Artificial Intelligence at UC Berkeley.
- The target is log price, which removes the heavy right skew of raw prices.
- The data is split 70/30 into train and test before any target-dependent fitting; the test set is used exactly once, to evaluate the final model.
- All preprocessing lives inside a scikit-learn Pipeline: a cross-fitted
TargetEncoderfor categorical columns,PolynomialFeatures(degree chosen by cross validation),StandardScaler, then the regressor. This keeps the encoding and hyperparameter search free of test-set leakage. - Candidates: a median-predicting baseline, linear regression at degrees 1 and 2, and Ridge and Lasso at degree 2 with alpha chosen by
GridSearchCVon the training set.
Cross-validated RMSE on the training set, in log-price units:
| Model | CV RMSE (log price) |
|---|---|
| Baseline (always predict median) | 0.894 |
| Linear regression, degree 1 | 0.508 |
| Linear regression, degree 2 | 0.464 |
| Lasso, degree 2, alpha 0.0001 | 0.487 |
| Ridge, degree 2, alpha 0.01 | 0.464 (selected) |
Final model performance on the held-out test set:
- R2 of 0.727 on log price (the baseline scores below zero)
- RMSE of 0.461 log units (test MSE 0.213)
- Median absolute error of $2,535, versus $9,190 for the baseline
- Mean absolute error of $4,289
Each finding maps to a chart or metric in the notebook.
- What the vehicle is matters most. Permutation importance on held-out data ranks
modelfirst (shuffling it costs about 0.25 of R2), ahead ofyear(about 0.19) andodometer(about 0.12). The model column effectively bundles brand, segment, and trim. - Age: prices climb steeply for vehicles newer than about 2010. Median listing price is flat near $5,000 to $7,000 for model years 1990 through 2005, then rises sharply to about $38,500 for 2021 models.
- Mileage: median price falls monotonically with odometer reading, fastest over the first 100,000 miles, and the linear model gives odometer the strongest negative coefficient.
- Segment: full-size pickups command roughly three times sedan prices. Among the 15 most-listed models, the 2500, 1500, Silverado 1500, and F-150 have median prices between $23,000 and $33,000, while the Corolla, Altima, Civic, Camry, and Accord sit near $7,000 to $8,000.
- Condition labels are noisy in the middle and reliable at the bottom. Listings marked
goodor with no stated condition carry higher median prices thanexcellent, because those labels skew toward newer, lower-mileage dealer listings. The unambiguous signal:fairandsalvagevehicles trade near $2,000 to $3,000, a fraction of everything else.
- Weight acquisition toward newer (roughly post-2015) and lower-mileage (under 100,000 miles) vehicles; the market pays a steep, quantifiable premium for both.
- Stock trucks and SUVs for revenue per unit; stock high-volume sedans (Civic, Corolla, Camry, Altima) for turnover. Their lower price level reflects the segment, not weak demand, since they are among the most-listed vehicles in the market.
- Use the model as a pricing sanity check: a listing priced far above its prediction will sit on the lot, and one priced far below leaves margin on the table. The test-set error above is the honest uncertainty band.
- Do not price off condition labels alone; anchor on year, odometer, and model first, and use condition mainly to screen out or steeply discount
fairandsalvagestock.
- Listing price is not transaction price; the data cannot show what buyers actually paid.
- The data is a snapshot and does not capture seasonality or macro shifts in the used-car market.
- Next steps: gradient-boosted trees for richer nonlinearity, calibrated prediction intervals for pricing bands, and days-on-lot data to model turnover as well as price.
pip install -r requirements.txt
jupyter notebook what_drives_the_price.ipynb
Python 3.10 or newer with scikit-learn 1.4 or newer (for TargetEncoder). The full run takes several minutes on the 351,240-row dataset.