Update app.py
Browse files
app.py
CHANGED
|
@@ -2,101 +2,90 @@ import gradio as gr
|
|
| 2 |
import pandas as pd
|
| 3 |
import numpy as np
|
| 4 |
import pickle
|
| 5 |
-
from
|
| 6 |
|
| 7 |
# Load the model
|
| 8 |
with open("apartment_price_model.pkl", mode="rb") as f:
|
| 9 |
model = pickle.load(f)
|
| 10 |
|
| 11 |
-
#
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
-
def predict_price(neighborhood, rooms, area, has_balcony, is_renovated):
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
price_per_room = rooms / area if area != 0 else 0
|
| 23 |
|
| 24 |
-
|
| 25 |
-
neighborhood_encoded = neighborhood_encoder.transform([neighborhood])[0]
|
| 26 |
|
| 27 |
-
# Create input dataframe
|
| 28 |
input_data = pd.DataFrame([{
|
| 29 |
'rooms': rooms,
|
| 30 |
'area': area,
|
| 31 |
-
'pop':
|
| 32 |
-
'pop_dens':
|
| 33 |
-
'frg_pct':
|
| 34 |
-
'emp':
|
| 35 |
-
'tax_income':
|
| 36 |
-
'price_per_room':
|
|
|
|
| 37 |
'has_balcony': 1 if has_balcony else 0,
|
| 38 |
'is_renovated': 1 if is_renovated else 0,
|
| 39 |
-
'
|
| 40 |
}])
|
| 41 |
|
| 42 |
-
# Define features in the correct order
|
| 43 |
features = [
|
| 44 |
'rooms', 'area', 'pop', 'pop_dens', 'frg_pct', 'emp', 'tax_income',
|
| 45 |
-
'price_per_room', 'has_balcony', 'is_renovated', '
|
| 46 |
]
|
| 47 |
|
| 48 |
-
# Make prediction
|
| 49 |
predicted_price = model.predict(input_data[features])[0]
|
| 50 |
|
| 51 |
-
# Format the result
|
| 52 |
result = f"Predicted Monthly Rent: CHF {predicted_price:.0f}"
|
| 53 |
result += f"\n\nProperty Details:"
|
| 54 |
-
result += f"\n-
|
| 55 |
result += f"\n- {rooms} rooms, {area} m²"
|
|
|
|
| 56 |
result += f"\n- {'Has balcony' if has_balcony else 'No balcony'}"
|
| 57 |
result += f"\n- {'Renovated' if is_renovated else 'Not renovated'}"
|
| 58 |
-
|
| 59 |
-
return result
|
| 60 |
|
| 61 |
-
|
| 62 |
-
return ["City Center (Altstadt)", 3.5, 75, True, False, ""]
|
| 63 |
|
| 64 |
with gr.Blocks() as demo:
|
| 65 |
gr.Markdown("# Zurich Apartment Rent Prediction")
|
| 66 |
|
| 67 |
with gr.Row():
|
| 68 |
with gr.Column():
|
| 69 |
-
neighborhood = gr.Dropdown(
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
"City Center (Altstadt)", "Oerlikon", "Altstetten", "Wiedikon",
|
| 73 |
-
"Seefeld", "Schwamendingen", "Wollishofen", "Enge",
|
| 74 |
-
"Fluntern", "Hottingen"
|
| 75 |
-
],
|
| 76 |
-
value="City Center (Altstadt)"
|
| 77 |
-
)
|
| 78 |
rooms = gr.Number(label="Number of Rooms", value=3.5)
|
| 79 |
area = gr.Number(label="Area (m²)", value=75)
|
| 80 |
has_balcony = gr.Checkbox(label="Has Balcony", value=True)
|
| 81 |
is_renovated = gr.Checkbox(label="Is Renovated", value=False)
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
submit_button = gr.Button("Submit")
|
| 85 |
-
clear_button = gr.Button("Clear")
|
| 86 |
-
|
| 87 |
-
with gr.Column():
|
| 88 |
output = gr.Textbox(label="Output")
|
| 89 |
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
clear_button.click(
|
| 97 |
-
fn=reset_inputs,
|
| 98 |
-
inputs=None,
|
| 99 |
-
outputs=[neighborhood, rooms, area, has_balcony, is_renovated, output]
|
| 100 |
-
)
|
| 101 |
|
| 102 |
demo.launch()
|
|
|
|
| 2 |
import pandas as pd
|
| 3 |
import numpy as np
|
| 4 |
import pickle
|
| 5 |
+
from math import radians, cos, sin, asin, sqrt
|
| 6 |
|
| 7 |
# Load the model
|
| 8 |
with open("apartment_price_model.pkl", mode="rb") as f:
|
| 9 |
model = pickle.load(f)
|
| 10 |
|
| 11 |
+
# Zurich neighborhoods with coordinates and distances
|
| 12 |
+
zurich_neighborhoods = {
|
| 13 |
+
"City Center (Altstadt)": {"lat": 47.3769, "lon": 8.5417, "distance": 0.0},
|
| 14 |
+
"Oerlikon": {"lat": 47.4111, "lon": 8.5458, "distance": 3.8},
|
| 15 |
+
"Altstetten": {"lat": 47.3908, "lon": 8.4889, "distance": 4.2},
|
| 16 |
+
"Wiedikon": {"lat": 47.3708, "lon": 8.5128, "distance": 2.3},
|
| 17 |
+
"Seefeld": {"lat": 47.3550, "lon": 8.5550, "distance": 2.7},
|
| 18 |
+
"Schwamendingen": {"lat": 47.4053, "lon": 8.5648, "distance": 3.5},
|
| 19 |
+
"Wollishofen": {"lat": 47.3517, "lon": 8.5304, "distance": 3.0},
|
| 20 |
+
"Enge": {"lat": 47.3656, "lon": 8.5267, "distance": 1.2},
|
| 21 |
+
"Fluntern": {"lat": 47.3797, "lon": 8.5611, "distance": 1.8},
|
| 22 |
+
"Hottingen": {"lat": 47.3683, "lon": 8.5584, "distance": 1.5},
|
| 23 |
+
"Custom Location": {"lat": 47.3769, "lon": 8.5417, "distance": 0.0}
|
| 24 |
+
}
|
| 25 |
|
| 26 |
+
def predict_price(neighborhood, rooms, area, has_balcony, is_renovated, proximity_to_transport, custom_lat=None, custom_lon=None):
|
| 27 |
+
if neighborhood == "Custom Location" and custom_lat is not None and custom_lon is not None:
|
| 28 |
+
lat = custom_lat
|
| 29 |
+
lon = custom_lon
|
| 30 |
+
else:
|
| 31 |
+
lat = zurich_neighborhoods[neighborhood]["lat"]
|
| 32 |
+
lon = zurich_neighborhoods[neighborhood]["lon"]
|
|
|
|
| 33 |
|
| 34 |
+
distance_to_center = haversine_distance(lat, lon, 47.3769, 8.5417)
|
|
|
|
| 35 |
|
|
|
|
| 36 |
input_data = pd.DataFrame([{
|
| 37 |
'rooms': rooms,
|
| 38 |
'area': area,
|
| 39 |
+
'pop': 420217,
|
| 40 |
+
'pop_dens': 4778,
|
| 41 |
+
'frg_pct': 32.45,
|
| 42 |
+
'emp': 491193,
|
| 43 |
+
'tax_income': 85446,
|
| 44 |
+
'price_per_room': 0,
|
| 45 |
+
'distance_to_center': distance_to_center,
|
| 46 |
'has_balcony': 1 if has_balcony else 0,
|
| 47 |
'is_renovated': 1 if is_renovated else 0,
|
| 48 |
+
'proximity_to_transport': 1 if proximity_to_transport else 0
|
| 49 |
}])
|
| 50 |
|
|
|
|
| 51 |
features = [
|
| 52 |
'rooms', 'area', 'pop', 'pop_dens', 'frg_pct', 'emp', 'tax_income',
|
| 53 |
+
'price_per_room', 'distance_to_center', 'has_balcony', 'is_renovated', 'proximity_to_transport'
|
| 54 |
]
|
| 55 |
|
|
|
|
| 56 |
predicted_price = model.predict(input_data[features])[0]
|
| 57 |
|
|
|
|
| 58 |
result = f"Predicted Monthly Rent: CHF {predicted_price:.0f}"
|
| 59 |
result += f"\n\nProperty Details:"
|
| 60 |
+
result += f"\n- Location: {neighborhood}"
|
| 61 |
result += f"\n- {rooms} rooms, {area} m²"
|
| 62 |
+
result += f"\n- {distance_to_center:.2f} km from city center"
|
| 63 |
result += f"\n- {'Has balcony' if has_balcony else 'No balcony'}"
|
| 64 |
result += f"\n- {'Renovated' if is_renovated else 'Not renovated'}"
|
| 65 |
+
result += f"\n- {'Close to transport' if proximity_to_transport else 'Far from transport'}"
|
|
|
|
| 66 |
|
| 67 |
+
return result
|
|
|
|
| 68 |
|
| 69 |
with gr.Blocks() as demo:
|
| 70 |
gr.Markdown("# Zurich Apartment Rent Prediction")
|
| 71 |
|
| 72 |
with gr.Row():
|
| 73 |
with gr.Column():
|
| 74 |
+
neighborhood = gr.Dropdown(label="Neighborhood", choices=list(zurich_neighborhoods.keys()), value="City Center (Altstadt)")
|
| 75 |
+
custom_lat = gr.Number(label="Custom Latitude", value=47.3769, visible=False)
|
| 76 |
+
custom_lon = gr.Number(label="Custom Longitude", value=8.5417, visible=False)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 77 |
rooms = gr.Number(label="Number of Rooms", value=3.5)
|
| 78 |
area = gr.Number(label="Area (m²)", value=75)
|
| 79 |
has_balcony = gr.Checkbox(label="Has Balcony", value=True)
|
| 80 |
is_renovated = gr.Checkbox(label="Is Renovated", value=False)
|
| 81 |
+
proximity_to_transport = gr.Checkbox(label="Proximity to Transport", value=False)
|
| 82 |
+
submit_button = gr.Button("Submit")
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
output = gr.Textbox(label="Output")
|
| 84 |
|
| 85 |
+
submit_button.click(
|
| 86 |
+
fn=predict_price,
|
| 87 |
+
inputs=[neighborhood, rooms, area, has_balcony, is_renovated, proximity_to_transport, custom_lat, custom_lon],
|
| 88 |
+
outputs=output
|
| 89 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
demo.launch()
|