Engineering
Airbnb Price Prediction & Feature Analysis
- Role
- Feature selection, the KNN and random forest models, and the comparison
- Period
- Oct 2025 – Dec 2025
- Stack
- Python
- Pandas
- Scikit-learn
- Matplotlib
Context#
Nightly price is a continuous target, so this is a regression problem rather than the classification the course spent most of its time on. The data is a 2023 snapshot of US Airbnb listings: 232,147 rows carrying location, room type, review history and availability. The listing title is the only free text in it, and it was dropped as an identifier, so nothing in the feature set describes the property itself beyond its room type and its coordinates.
Cleaning cost 19,509 rows. Prices sit in a long right tail, and an interquartile-range filter removed everything more than 1.5 IQR outside the quartiles, about 8% of the listings. That stops a handful of thousand-dollar listings dominating the error term. It also means the models are trained on ordinary listings and say nothing about the luxury end, which is the segment where a price prediction would be worth the most money.
Selecting features#
One-hot encoding every categorical column turned twelve predictors into 1,475, almost all of them neighbourhood and city indicators. A decision-tree regressor fit on the training split then ranked them by importance.
- Private room (vs entire home)
- 0.161
- Longitude
- 0.132
- Latitude
- 0.131
- Days available per year
- 0.084
- Reviews per month
- 0.077
- Listings by the same host
- 0.076
- Minimum nights
- 0.061
- Total reviews
- 0.059
- Reviews in the last 12 months
- 0.035
- Shared room
- 0.017
Room type is the single strongest predictor, but latitude and longitude together outweigh it. Everything after that is host behaviour rather than property: how much of the year the place is available, how fast reviews accumulate, how many other listings the same host runs.
Location matters, yet the columns encoding it precisely all score close to zero, because the signal is spread across roughly 1,460 sparse neighbourhood indicators that each cover a handful of listings. Keeping the top ten therefore keeps location as two raw coordinates and discards the fine-grained version. That is a plausible explanation for the ceiling rather than a measured one; the ablation that would settle it was not run.
Comparing models#
Five regressors, the same held-out split, the same ten features.
| Model | R² | MAE |
|---|---|---|
| Random forest (100 trees, depth 15) | 0.443 | $53.73 |
| Decision tree (depth 10) | 0.343 | $59.39 |
| K-nearest neighbours (k = 9) | 0.321 | $59.85 |
| Support vector regression (RBF) | 0.266 | $59.49 |
| Linear regression | 0.214 | $67.30 |
The random forest wins on both metrics. With latitude and longitude doing the heavy lifting, an ensemble of trees can carve a map into regions where a single tree at depth 10 cannot. K-nearest neighbours lands third, standard-scaled because a distance metric over raw coordinates and review counts means nothing without it.
Linear regression is last, and its training and test scores are almost identical at 0.216 and 0.214. It is underfitting rather than overfitting: a straight line is the wrong shape for this data. Support vector regression posts a better MAE than KNN but a worse R², so it is more accurate on typical listings and worse on the extremes, which is what an RBF kernel does when it smooths toward the mean.
What this shows#
The best model explains 44% of the variance in nightly price, and the limit sits in the data rather than in the models. What a listing costs depends on the property, and the only columns describing the property are room type and a pair of coordinates. Square footage, amenities, photographs and review text carry the rest, and none of them are in this dataset.