Spaces:
Runtime error
Runtime error
Upload 8 files
Browse files- apartment_price_model.pkl +3 -0
- apartments_data_enriched_lat_lon_combined.csv +0 -0
- apartments_data_enriched_with_new_features-2.csv +0 -0
- app.py +76 -0
- data_with_large_residuals.csv +15 -0
- original_apartment_data_analytics_hs24_with_lat_lon.csv +0 -0
- requirement.txt +8 -0
- stzh.adm_stadtkreise_a.json +0 -0
apartment_price_model.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:476146d55b19877ff5a612807dc75bd5c2ceb18af22b5ca30f640e29644a5e34
|
| 3 |
+
size 16501313
|
apartments_data_enriched_lat_lon_combined.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
apartments_data_enriched_with_new_features-2.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
app.py
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import joblib
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
import gradio as gr
|
| 5 |
+
import geopy.distance
|
| 6 |
+
from sklearn.ensemble import RandomForestRegressor
|
| 7 |
+
from sklearn.model_selection import train_test_split
|
| 8 |
+
|
| 9 |
+
# ------------------------------
|
| 10 |
+
# Load Data
|
| 11 |
+
# ------------------------------
|
| 12 |
+
DATA_PATH = "apartments_data_enriched_lat_lon_combined.csv"
|
| 13 |
+
df = pd.read_csv(DATA_PATH)
|
| 14 |
+
|
| 15 |
+
# Handle missing coordinate columns
|
| 16 |
+
lat_col = "latitude" if "latitude" in df.columns else "lat"
|
| 17 |
+
lon_col = "longitude" if "longitude" in df.columns else "lon"
|
| 18 |
+
if lat_col not in df.columns or lon_col not in df.columns:
|
| 19 |
+
raise KeyError("Latitude and Longitude columns are missing!")
|
| 20 |
+
|
| 21 |
+
# Define public transport stations
|
| 22 |
+
public_transit_stations = [
|
| 23 |
+
{"name": "Hauptbahnhof", "lat": 47.378177, "lon": 8.540192},
|
| 24 |
+
{"name": "Bahnhof Stadelhofen", "lat": 47.366321, "lon": 8.548008},
|
| 25 |
+
{"name": "Hardbrücke", "lat": 47.385118, "lon": 8.517220},
|
| 26 |
+
{"name": "Enge", "lat": 47.364751, "lon": 8.531601}
|
| 27 |
+
]
|
| 28 |
+
|
| 29 |
+
# Function to compute distance to nearest station
|
| 30 |
+
def distance_to_nearest_station(lat, lon):
|
| 31 |
+
min_distance = np.inf
|
| 32 |
+
for station in public_transit_stations:
|
| 33 |
+
dist = geopy.distance.geodesic((lat, lon), (station["lat"], station["lon"]))
|
| 34 |
+
min_distance = min(min_distance, dist.km)
|
| 35 |
+
return min_distance
|
| 36 |
+
|
| 37 |
+
# Compute new feature
|
| 38 |
+
df["distance_to_transit"] = df.apply(lambda row: distance_to_nearest_station(row[lat_col], row[lon_col]), axis=1)
|
| 39 |
+
|
| 40 |
+
# ------------------------------
|
| 41 |
+
# Train Model
|
| 42 |
+
# ------------------------------
|
| 43 |
+
features = ["rooms", "area", "pop_dens", "tax_income", "distance_to_transit"]
|
| 44 |
+
X = df[features]
|
| 45 |
+
y = df["price"]
|
| 46 |
+
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
|
| 47 |
+
|
| 48 |
+
model = RandomForestRegressor(n_estimators=100, random_state=42)
|
| 49 |
+
model.fit(X_train, y_train)
|
| 50 |
+
|
| 51 |
+
# Save model
|
| 52 |
+
joblib.dump(model, "apartment_price_model.pkl")
|
| 53 |
+
|
| 54 |
+
# ------------------------------
|
| 55 |
+
# Gradio Web Interface
|
| 56 |
+
# ------------------------------
|
| 57 |
+
def predict_price(rooms, area, pop_dens, tax_income, distance_to_transit):
|
| 58 |
+
model = joblib.load("apartment_price_model.pkl")
|
| 59 |
+
input_data = pd.DataFrame([[rooms, area, pop_dens, tax_income, distance_to_transit]], columns=features)
|
| 60 |
+
prediction = model.predict(input_data)[0]
|
| 61 |
+
return f"Geschätzter Preis: {prediction:.2f} CHF"
|
| 62 |
+
|
| 63 |
+
app = gr.Interface(
|
| 64 |
+
fn=predict_price,
|
| 65 |
+
inputs=[
|
| 66 |
+
gr.Number(label="Anzahl Zimmer"),
|
| 67 |
+
gr.Number(label="Fläche (m²)"),
|
| 68 |
+
gr.Number(label="Bevölkerungsdichte"),
|
| 69 |
+
gr.Number(label="Steuerbares Einkommen"),
|
| 70 |
+
gr.Number(label="Distanz zur nächsten ÖV-Station (km)")
|
| 71 |
+
],
|
| 72 |
+
outputs="text"
|
| 73 |
+
)
|
| 74 |
+
|
| 75 |
+
if __name__ == "__main__":
|
| 76 |
+
app.launch()
|
data_with_large_residuals.csv
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
rooms,area,pop,pop_dens,frg_pct,emp,tax_income,room_per_m2,luxurious,temporary,furnished,area_cat_ecoded,zurich_city,recidual (error),price,predicted_price,description_raw,bfs_name,postalcode,town
|
| 2 |
+
2.0,54,29944,10008.0,32.4584678868,491193.0,85446,27.0,0,0,0,2.0,1,902.5900000000001,4853,3950.41,«2 Bedroom Apartment Senior Balcony»,Zürich,8004, Zürich
|
| 3 |
+
2.0,49,50950,5792.0,32.4584678868,491193.0,85446,24.5,0,0,0,0.0,1,981.3466666666668,4335,3353.653333333333,«2 Bedroom Apartment Junior Terrace»,Zürich,8003, Zürich
|
| 4 |
+
3.0,76,50950,5792.0,32.4584678868,491193.0,85446,25.33,0,0,0,2.0,1,923.5333333333338,1970,2893.5333333333338,«3- Zimmerwohnung im Kreis 3 direkt beim Goldbrunnenplatz»,Zürich,8003, Zürich
|
| 5 |
+
2.5,65,41411,4512.0,32.4584678868,491193.0,85446,26.0,0,0,0,2.0,1,887.0349999999999,5900,5012.965,«Serviced 1-bedroom with great view and luxurious interior design»,Zürich,8037, Zürich
|
| 6 |
+
2.5,75,41411,4512.0,32.4584678868,491193.0,85446,30.0,0,0,0,2.0,1,1016.3000000000002,6900,5883.7,"«""Serviced 1-bedroom apartment: spectacular view & luxurious interior»",Zürich,8037, Zürich
|
| 7 |
+
3.5,90,41411,4512.0,32.4584678868,491193.0,85446,25.71,0,1,0,2.0,1,941.585,1750,2691.585,«BEFRISTETES WOHNEN BIS 31. MÄRZ 2024»,Zürich,8049, Zürich
|
| 8 |
+
2.5,70,78801,5736.0,32.4584678868,491193.0,85446,28.0,0,0,0,2.0,1,1590.6400000000003,5900,4309.36,«Spacious apartment with spectacular view and luxururious design»,Zürich,8057, Zürich
|
| 9 |
+
3.5,126,37639,3254.0,32.4584678868,491193.0,85446,36.0,0,0,0,1.0,1,1282.1999999999998,6575,5292.8,«Live Above - Exklusive Mietwohnung über dem FIFA World Football Museum»,Zürich,8002, Zürich
|
| 10 |
+
2.5,70,39647,2574.0,32.4584678868,491193.0,85446,28.0,0,0,0,2.0,1,811.4266666666672,5900,5088.573333333333,"«""Wohnoase im Englisch Viertel - Serviced Apartment in Jugendstil-Villa»",Zürich,8032, Zürich
|
| 11 |
+
4.5,137,39647,2574.0,32.4584678868,491193.0,85446,30.44,0,0,0,1.0,1,1573.3366666666666,875,2448.3366666666666,«HISTORISCH MIT PRIVATER SONNENTERRASSE IM ZENTRUM»,Zürich,8001, Zürich
|
| 12 |
+
5.5,200,113173,1662.5973262818,24.535003932,73339.0,70966,36.36,0,0,0,1.0,0,899.6033333333335,5600,4700.3966666666665,"«RUHIG UND SONNIG, MIT WUNDERSCHÖNER AUSSICHT»",Winterthur,8404, Winterthur
|
| 13 |
+
3.5,130,18139,3298.0,29.0313688737,6582.0,113194,37.14,0,0,0,1.0,0,1256.3100000000004,6490,5233.69,«Weitblick im neu renovierten 2-Schlafzimmer-Serviced Apartment»,Thalwil,8800, Thalwil
|
| 14 |
+
3.5,100,13067,1664.5859872612,26.0580087243,5764.0,171602,28.57,0,0,0,2.0,0,812.1949999999997,5550,4737.805,«3 1/2-Zimmer-Wohnung mit Seesicht»,Zollikon,8702, Zollikon
|
| 15 |
+
4.5,101,35007,1228.7469287469,23.0096837775,17237.0,79839,22.44,0,0,0,1.0,0,861.7101666666663,3210,2348.2898333333337,«Helle und moderne Maisonette-Wohnung mit Galerie»,Uster,8610, Uster
|
original_apartment_data_analytics_hs24_with_lat_lon.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
requirement.txt
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
scikit-learn
|
| 2 |
+
geopy
|
| 3 |
+
pandas
|
| 4 |
+
numpy
|
| 5 |
+
scikit-learn
|
| 6 |
+
geopy
|
| 7 |
+
gradio
|
| 8 |
+
joblib
|
stzh.adm_stadtkreise_a.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|