Spaces:
Sleeping
A newer version of the Gradio SDK is available: 6.20.0
title: Application1
emoji: 🐠
colorFrom: yellow
colorTo: purple
sdk: gradio
sdk_version: 6.9.0
app_file: app.py
pinned: false
short_description: Appartement price prediction
Zurich Apartment Rent Predictor
This application predicts monthly rental prices (CHF) for apartments in the Canton of Zurich.
Live App: TODOOOOOOOOOHugging Face Spaces – Zurich Apartment Predictor
Model Iterations
Summary Table
| Iteration | Objective | Key Changes | Models Used | CV Mean R² | CV Std | Δ Performance | Fit Diagnosis |
|---|---|---|---|---|---|---|---|
| 1 | Baseline | Basic cleaning, no log transform, 9 features, default hyperparameters | Linear Regression, Random Forest (n=100) | 0.61 (RF) / 0.60 (LR) | 0.10 / 0.06 | Baseline | Overfitting (RF) |
| 2 | Improve generalization | Log-transform target, 32 features incl. income_density_score (new), lat/lon, Kreis dummies, tuned hyperparameters | Ridge (α=10), RF (n=300, depth=15), Gradient Boosting | 0.70 | 0.04–0.07 | +0.09 | Good Fit |
Iteration 1 Baseline
Establish a performance baseline.
Steps:
- Loaded
apartments_data_enriched_with_new_features.csv - Dropped rows with missing values in selected columns
- Used raw (untransformed) price as target
- Evaluated with 5-fold cross-validation (
KFold,shuffle=True,random_state=42)
Models and Hyperparameters:
- LinearRegression
- RandomForestRegressor(n_estimators=100, random_state=42)
Features: rooms, area, pop_dens, frg_pct, tax_income, luxurious, furnished, temporary, zurich_city
Results:
| Model | CV R² | CV Std | CV RMSE (CHF) |
|---|---|---|---|
| Linear Regression | 0.60 | 0.06 | ~679 |
| Random Forest | 0.61 | 0.10 | ~666 |
Random Forest shows large gap between train R² (0.93) and test R² (0.61) → Linear model underfits. Both need improvement.
Iteration 2 Improved Model
Reduce overfitting, improve generalization with richer features and better hyperparameters.
Steps:
- Log-transform target variable to reduce right skew and improve linear model performance
- Engineered new feature: income_density_score = (tax_income × pop_dens) / 1,000,000
- Engineered additional features: log_area, rooms_area_ratio
- Added geographic features:
lat,lon - Added Zurich district dummies:
Kreis 1–12 - Added keyword flags from listing text: (LOFT),(SEESICHT), etc.
Models and Hyperparameters:
- Ridge(alpha=10.0)
- RandomForestRegressor(n_estimators=300, max_depth=15, min_samples_leaf=3, random_state=42)
- GradientBoostingRegressor(n_estimators=300, max_depth=5, learning_rate=0.05, random_state=42)
Features: rooms, area, log_area, pop_dens, frg_pct, tax_income, income_density_score, rooms_area_ratio, lat, lon, luxurious, furnished, temporary, zurich_city, room_per_m2, Kreis 1–12, (ATTIKA), (LOFT), (SEESICHT), (LUXURIÖS), (POOL), (EXKLUSIV)
Results:
| Model | CV R² | CV Std |
|---|---|---|
| Ridge (alpha=10) | 0.70 | 0.04 |
| Random Forest (tuned) | 0.70 | 0.07 |
| Gradient Boosting | 0.70 | 0.07 |
All three models achieve ~0.70 R². RF train/test gap reduced to ~0.10 (was ~0.32). Good Fit.
Iteration 3 Room Scaling and Correct Defaults
Fix the prediction plateau and improve scaling across all room counts and price ranges.
Steps:
- Added log_rooms
- Added area_rooms_interact = area × rooms
- Corrected pop_dens defaults in the app:
4,729for Zurich City,1,328for outside (both derived from training data medians)
Models and Hyperparameters:
- Ridge(alpha=10.0)
- RandomForestRegressor(n_estimators=300, max_depth=15, min_samples_leaf=3, random_state=42)
- GradientBoostingRegressor(n_estimators=800, max_depth=5, learning_rate=0.03, min_samples_leaf=3, subsample=0.8, random_state=42)
Features: rooms, area, log_area, log_rooms, pop_dens, log_pop_dens, frg_pct, tax_income, income_density_score, log_income_dens, rooms_area_ratio, area_rooms_interact, lat, lon, luxurious, furnished, temporary, zurich_city, room_per_m2, Kreis 1–12, (ATTIKA), (LOFT), (SEESICHT), (LUXURIÖS), (POOL), (EXKLUSIV)
Results:
| Model | CV R² | CV Std |
|---|---|---|
| Ridge (alpha=10) | 0.72 | 0.04 |
| Random Forest (tuned) | 0.72 | 0.05 |
| Gradient Boosting (tuned) | 0.72 | 0.05 |
Example predictions after fix (Zurich City, Kreis 3):
| Rooms | Area | Predicted Rent |
|---|---|---|
| 1.0 | 30 m² | CHF 1,157 |
| 3.0 | 80 m² | CHF 3,121 |
| 4.5 | 115 m² | CHF 3,741 |
| 5.5 | 145 m² | CHF 4,972 |
| 6.5 | 175 m² | CHF 5,879 |
New Feature: income_density_score
income_density_score = (tax_income × pop_dens) / 1,000,000
This feature combines municipal tax income with population density to create a neighbourhood affluence proxy. A dense area with high-income residents (for example Kreis 1 or Küsnacht) will score much higher than a sparse rural municipality.
Final Selected Model
Model: RandomForestRegressor(n_estimators=300, max_depth=15, min_samples_leaf=3)
Target: log(1 + price) → predictions are back-transformed with expm1()
CV R²: 0.70 | CV Std: 0.07
Evaluation: 5-fold cross-validation
Top Feature Importances:
log_area— log-transformed living areaarea— living area in m²rooms— number of roomsincome_density_score(new feature)lat— latitude (geographic location)