AIApplication / app.py
Fadri's picture
Upload 3 files
71f1a78 verified
import gradio as gr
from sklearn.ensemble import RandomForestRegressor
import numpy as np
import pandas as pd
import pickle
from geopy.geocoders import Nominatim
from geopy.exc import GeocoderTimedOut
from math import radians, cos, sin, asin, sqrt
# Lade das Modell
# TODO change the file to your own model.
model_filename = "final_apartment_model.pkl"
random_forest_model = RandomForestRegressor()
with open(model_filename, 'rb') as f:
random_forest_model = pickle.load(f)
# Funktion zur Berechnung der Entfernung zwischen zwei Koordinatenpunkten
def haversine(lon1, lat1, lon2, lat2):
"""
Berechnet die Entfernung in Kilometern zwischen zwei Punkten
auf der Erde (anhand von Längen-/Breitengraden)
"""
lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])
dlon = lon2 - lon1
dlat = lat2 - lat1
a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
c = 2 * asin(sqrt(a))
return 6371 * c
transport_hubs = [
["Zürich HB", 47.3778, 8.5403],
["Zürich Stadelhofen", 47.3665, 8.5486],
["Zürich Oerlikon", 47.4111, 8.5438],
["Zürich Altstetten", 47.3911, 8.4889],
["Winterthur", 47.4996, 8.7241],
["Uster", 47.3474, 8.7201],
["Wetzikon", 47.3281, 8.7974],
["Dübendorf", 47.3973, 8.6186],
["Dietikon", 47.4051, 8.4012],
["Thalwil", 47.2916, 8.5641]
]
def get_coordinates(address):
"""Holt die Koordinaten für eine gegebene Adresse"""
try:
geolocator = Nominatim(user_agent="my_apartment_predictor")
if 'zürich' not in address.lower() and 'switzerland' not in address.lower():
address += ', Zürich, Switzerland'
location = geolocator.geocode(address)
if location:
return location.latitude, location.longitude, location.address
return None, None, None
except GeocoderTimedOut:
return None, None, None
def get_nearest_transport_distance(lat, lon):
"""Berechnet die Distanz zum nächsten Verkehrsknotenpunkt"""
distances = []
for hub in transport_hubs:
hub_name, hub_lat, hub_lon = hub
distance = haversine(lon, lat, hub_lon, hub_lat)
distances.append(distance)
return min(distances)
# Lade die BFS-Daten
df_bfs_data = pd.read_csv('bfs_municipality_and_tax_data.csv')
# Bereinige die tax_income Spalte von Tausendertrennzeichen und konvertiere zu float
df_bfs_data['tax_income'] = df_bfs_data['tax_income'].str.replace("'", "").astype(float)
# Berechne Durchschnittswerte für die Features
mean_values = {
'pop': df_bfs_data['pop'].mean(),
'pop_dens': df_bfs_data['pop_dens'].mean(),
'frg_pct': df_bfs_data['frg_pct'].mean(),
'emp': df_bfs_data['emp'].mean(),
'tax_income': df_bfs_data['tax_income'].mean()
}
def predict_apartment_price(rooms, area, address):
"""Vorhersage des Mietpreises basierend auf Zimmer, Fläche und Adresse"""
# Hole Koordinaten für die Adresse
lat, lon, full_address = get_coordinates(address)
if lat is None or lon is None:
return "Adresse konnte nicht gefunden werden. Bitte überprüfen Sie die Eingabe."
# Berechne die Distanz zum nächsten Verkehrsknotenpunkt
distance_to_transport = get_nearest_transport_distance(lat, lon)
# Erstelle DataFrame für die Vorhersage mit den vorberechneten Durchschnittswerten
prediction_data = pd.DataFrame({
'rooms': [rooms],
'area': [area],
'pop': [mean_values['pop']],
'pop_dens': [mean_values['pop_dens']],
'frg_pct': [mean_values['frg_pct']],
'emp': [mean_values['emp']],
'tax_income': [mean_values['tax_income']],
'distance_to_transport': [distance_to_transport]
})
# Mache die Vorhersage
prediction = random_forest_model.predict(prediction_data)
predicted_price = np.round(prediction[0], 0)
return f"Geschätzter Mietpreis für {full_address}: CHF {predicted_price:.0f}\nEntfernung zum nächsten Verkehrsknotenpunkt: {distance_to_transport:.1f} km"
iface = gr.Interface(
fn=predict_apartment_price,
inputs=[
gr.Number(label="Anzahl Zimmer"),
gr.Number(label="Wohnfläche (m²)"),
gr.Textbox(label="Adresse (z.B. Bahnhofstrasse 1, Zürich)")
],
outputs=gr.Textbox(label="Vorhersage"),
title="Mietpreis-Vorhersage",
description="Geben Sie die Details der Wohnung ein, um den geschätzten Mietpreis zu erhalten.",
examples=[
[4.5, 120, "Bahnhofstrasse 1, Zürich"],
[3.5, 80, "Universitätstrasse 84, Zürich"],
[2.5, 60, "Technikumstrasse 9, Winterthur"]
]
)
iface.launch()