Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files
README.md
CHANGED
|
@@ -80,6 +80,39 @@ Reduce overfitting, improve generalization with richer features and better hyper
|
|
| 80 |
|
| 81 |
All three models achieve ~0.70 R². RF train/test gap reduced to ~0.10 (was ~0.32). Good Fit.
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
---
|
| 84 |
|
| 85 |
## New Feature: `income_density_score`
|
|
|
|
| 80 |
|
| 81 |
All three models achieve ~0.70 R². RF train/test gap reduced to ~0.10 (was ~0.32). Good Fit.
|
| 82 |
|
| 83 |
+
## Iteration 3 Room Scaling and Correct Defaults
|
| 84 |
+
Fix the prediction plateau and improve scaling across all room counts and price ranges.
|
| 85 |
+
|
| 86 |
+
**Steps:**
|
| 87 |
+
- Added log_rooms
|
| 88 |
+
- Added area_rooms_interact = area × rooms
|
| 89 |
+
- Corrected pop_dens defaults in the app: `4,729` for Zurich City, `1,328` for outside (both derived from training data medians)
|
| 90 |
+
|
| 91 |
+
**Models and Hyperparameters:**
|
| 92 |
+
- Ridge(alpha=10.0)
|
| 93 |
+
- RandomForestRegressor(n_estimators=300, max_depth=15, min_samples_leaf=3, random_state=42)
|
| 94 |
+
- GradientBoostingRegressor(n_estimators=800, max_depth=5, learning_rate=0.03, min_samples_leaf=3, subsample=0.8, random_state=42)
|
| 95 |
+
|
| 96 |
+
**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)`
|
| 97 |
+
|
| 98 |
+
**Results:**
|
| 99 |
+
|
| 100 |
+
| Model | CV R² | CV Std |
|
| 101 |
+
|-------|--------|--------|
|
| 102 |
+
| Ridge (alpha=10) | 0.72 | 0.04 |
|
| 103 |
+
| Random Forest (tuned) | 0.72 | 0.05 |
|
| 104 |
+
| Gradient Boosting (tuned) | 0.72 | 0.05 |
|
| 105 |
+
|
| 106 |
+
Example predictions after fix (Zurich City, Kreis 3):
|
| 107 |
+
|
| 108 |
+
| Rooms | Area | Predicted Rent |
|
| 109 |
+
|-------|------|----------------|
|
| 110 |
+
| 1.0 | 30 m² | CHF 1,157 |
|
| 111 |
+
| 3.0 | 80 m² | CHF 3,121 |
|
| 112 |
+
| 4.5 | 115 m² | CHF 3,741 |
|
| 113 |
+
| 5.5 | 145 m² | CHF 4,972 |
|
| 114 |
+
| 6.5 | 175 m² | CHF 5,879 |
|
| 115 |
+
|
| 116 |
---
|
| 117 |
|
| 118 |
## New Feature: `income_density_score`
|
app.py
CHANGED
|
@@ -13,11 +13,13 @@ model = model_data["model"]
|
|
| 13 |
features = model_data["features"]
|
| 14 |
log_target = model_data["log_target"]
|
| 15 |
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
DEFAULT_FRG_PCT
|
| 19 |
-
|
| 20 |
-
|
|
|
|
|
|
|
| 21 |
|
| 22 |
|
| 23 |
def predict_price(
|
|
@@ -26,19 +28,21 @@ def predict_price(
|
|
| 26 |
attika, loft, seesicht,
|
| 27 |
kreis
|
| 28 |
):
|
| 29 |
-
# Use defaults for hidden features
|
| 30 |
-
pop_dens =
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
|
| 35 |
# Derived features
|
| 36 |
-
log_area
|
| 37 |
-
log_rooms
|
| 38 |
-
rooms_area_ratio
|
| 39 |
-
room_per_m2
|
| 40 |
income_density_score = tax_income * pop_dens / 1e6
|
| 41 |
-
|
|
|
|
|
|
|
| 42 |
|
| 43 |
# Kreis dummies
|
| 44 |
kreis_cols = {f"Kreis {i}": 0 for i in range(1, 13)}
|
|
@@ -51,9 +55,11 @@ def predict_price(
|
|
| 51 |
"log_area": log_area,
|
| 52 |
"log_rooms": log_rooms,
|
| 53 |
"pop_dens": pop_dens,
|
|
|
|
| 54 |
"frg_pct": frg_pct,
|
| 55 |
"tax_income": tax_income,
|
| 56 |
"income_density_score": income_density_score,
|
|
|
|
| 57 |
"rooms_area_ratio": rooms_area_ratio,
|
| 58 |
"area_rooms_interact": area_rooms_interact,
|
| 59 |
"lat": lat,
|
|
@@ -108,7 +114,7 @@ demo = gr.Interface(
|
|
| 108 |
title="Zurich Apartment Rent Predictor",
|
| 109 |
description=(
|
| 110 |
"Predict the monthly rental price for an apartment in the Canton of Zurich.\n\n"
|
| 111 |
-
"This model uses a **
|
| 112 |
"with features including location (district), apartment characteristics, "
|
| 113 |
"and the **Income-Density Score** (a neighbourhood affluence proxy)."
|
| 114 |
),
|
|
@@ -116,4 +122,4 @@ demo = gr.Interface(
|
|
| 116 |
)
|
| 117 |
|
| 118 |
if __name__ == "__main__":
|
| 119 |
-
demo.launch()
|
|
|
|
| 13 |
features = model_data["features"]
|
| 14 |
log_target = model_data["log_target"]
|
| 15 |
|
| 16 |
+
DEFAULT_POP_DENS_CITY = 4729.0
|
| 17 |
+
DEFAULT_POP_DENS_OUTSIDE = 1328.0
|
| 18 |
+
DEFAULT_FRG_PCT = 25.0
|
| 19 |
+
DEFAULT_LAT_CITY = 47.380402
|
| 20 |
+
DEFAULT_LON_CITY = 8.530496
|
| 21 |
+
DEFAULT_LAT_OUTSIDE = 47.424900
|
| 22 |
+
DEFAULT_LON_OUTSIDE = 8.638663
|
| 23 |
|
| 24 |
|
| 25 |
def predict_price(
|
|
|
|
| 28 |
attika, loft, seesicht,
|
| 29 |
kreis
|
| 30 |
):
|
| 31 |
+
# Use data-derived defaults for hidden features
|
| 32 |
+
pop_dens = DEFAULT_POP_DENS_CITY if zurich_city else DEFAULT_POP_DENS_OUTSIDE
|
| 33 |
+
lat = DEFAULT_LAT_CITY if zurich_city else DEFAULT_LAT_OUTSIDE
|
| 34 |
+
lon = DEFAULT_LON_CITY if zurich_city else DEFAULT_LON_OUTSIDE
|
| 35 |
+
frg_pct = DEFAULT_FRG_PCT
|
| 36 |
|
| 37 |
# Derived features
|
| 38 |
+
log_area = np.log1p(area)
|
| 39 |
+
log_rooms = np.log1p(rooms)
|
| 40 |
+
rooms_area_ratio = rooms / (area + 1)
|
| 41 |
+
room_per_m2 = area / rooms if rooms > 0 else area
|
| 42 |
income_density_score = tax_income * pop_dens / 1e6
|
| 43 |
+
log_income_dens = np.log1p(income_density_score)
|
| 44 |
+
log_pop_dens = np.log1p(pop_dens)
|
| 45 |
+
area_rooms_interact = area * rooms
|
| 46 |
|
| 47 |
# Kreis dummies
|
| 48 |
kreis_cols = {f"Kreis {i}": 0 for i in range(1, 13)}
|
|
|
|
| 55 |
"log_area": log_area,
|
| 56 |
"log_rooms": log_rooms,
|
| 57 |
"pop_dens": pop_dens,
|
| 58 |
+
"log_pop_dens": log_pop_dens,
|
| 59 |
"frg_pct": frg_pct,
|
| 60 |
"tax_income": tax_income,
|
| 61 |
"income_density_score": income_density_score,
|
| 62 |
+
"log_income_dens": log_income_dens,
|
| 63 |
"rooms_area_ratio": rooms_area_ratio,
|
| 64 |
"area_rooms_interact": area_rooms_interact,
|
| 65 |
"lat": lat,
|
|
|
|
| 114 |
title="Zurich Apartment Rent Predictor",
|
| 115 |
description=(
|
| 116 |
"Predict the monthly rental price for an apartment in the Canton of Zurich.\n\n"
|
| 117 |
+
"This model uses a **Gradient Boosting Regressor** trained on ~800 Zurich apartment listings, "
|
| 118 |
"with features including location (district), apartment characteristics, "
|
| 119 |
"and the **Income-Density Score** (a neighbourhood affluence proxy)."
|
| 120 |
),
|
|
|
|
| 122 |
)
|
| 123 |
|
| 124 |
if __name__ == "__main__":
|
| 125 |
+
demo.launch()
|