Spaces:
Sleeping
Sleeping
Upload 4 files
Browse files- app.py +86 -0
- bfs_municipality_and_tax_data.csv +0 -0
- random_forest_regression.pkl +3 -0
- requirements.txt +4 -0
app.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import numpy as np
|
| 4 |
+
import pickle
|
| 5 |
+
|
| 6 |
+
# Modell laden
|
| 7 |
+
model_filename = "random_forest_regression.pkl"
|
| 8 |
+
with open(model_filename, "rb") as f:
|
| 9 |
+
model = pickle.load(f)
|
| 10 |
+
|
| 11 |
+
# CSV-Daten laden
|
| 12 |
+
df_bfs_data = pd.read_csv("bfs_municipality_and_tax_data.csv", sep=",", encoding="utf-8")
|
| 13 |
+
df_bfs_data["tax_income"] = df_bfs_data["tax_income"].str.replace("'", "").astype(float)
|
| 14 |
+
|
| 15 |
+
# Neue Features berechnen
|
| 16 |
+
df_bfs_data["emp_per_capita"] = df_bfs_data["emp"] / df_bfs_data["pop"]
|
| 17 |
+
df_bfs_data["wealth_factor"] = df_bfs_data["tax_income"] * df_bfs_data["emp_per_capita"]
|
| 18 |
+
|
| 19 |
+
# Alle Ortschaften
|
| 20 |
+
locations = {
|
| 21 |
+
"Zürich": 261, "Kloten": 62, "Uster": 198, "Illnau-Effretikon": 296, "Feuerthalen": 27,
|
| 22 |
+
"Pfäffikon": 177, "Ottenbach": 11, "Dübendorf": 191, "Richterswil": 138, "Maur": 195,
|
| 23 |
+
"Embrach": 56, "Bülach": 53, "Winterthur": 230, "Oetwil am See": 157, "Russikon": 178,
|
| 24 |
+
"Obfelden": 10, "Wald (ZH)": 120, "Niederweningen": 91, "Dällikon": 84, "Buchs (ZH)": 83,
|
| 25 |
+
"Rüti (ZH)": 118, "Hittnau": 173, "Bassersdorf": 52, "Glattfelden": 58, "Opfikon": 66,
|
| 26 |
+
"Hinwil": 117, "Regensberg": 95, "Langnau am Albis": 136, "Dietikon": 243, "Erlenbach (ZH)": 151,
|
| 27 |
+
"Kappel am Albis": 6, "Stäfa": 158, "Zell (ZH)": 231, "Turbenthal": 228, "Oberglatt": 92,
|
| 28 |
+
"Winkel": 72, "Volketswil": 199, "Kilchberg (ZH)": 135, "Wetzikon (ZH)": 121, "Zumikon": 160,
|
| 29 |
+
"Weisslingen": 180, "Elsau": 219, "Hettlingen": 221, "Rüschlikon": 139, "Stallikon": 13,
|
| 30 |
+
"Dielsdorf": 86, "Wallisellen": 69, "Dietlikon": 54, "Meilen": 156, "Wangen-Brüttisellen": 200,
|
| 31 |
+
"Flaach": 28, "Regensdorf": 96, "Niederhasli": 90, "Bauma": 297, "Aesch (ZH)": 241,
|
| 32 |
+
"Schlieren": 247, "Dürnten": 113, "Unterengstringen": 249, "Gossau (ZH)": 115,
|
| 33 |
+
"Oberengstringen": 245, "Schleinikon": 98, "Aeugst am Albis": 1, "Rheinau": 38, "Höri": 60,
|
| 34 |
+
"Rickenbach (ZH)": 225, "Rafz": 67, "Adliswil": 131, "Zollikon": 161, "Urdorf": 250,
|
| 35 |
+
"Hombrechtikon": 153, "Birmensdorf (ZH)": 242, "Fehraltorf": 172, "Weiach": 102,
|
| 36 |
+
"Männedorf": 155, "Küsnacht (ZH)": 154, "Hausen am Albis": 4, "Hochfelden": 59,
|
| 37 |
+
"Fällanden": 193, "Greifensee": 194, "Mönchaltorf": 196, "Dägerlen": 214, "Thalheim an der Thur": 39,
|
| 38 |
+
"Uetikon am See": 159, "Seuzach": 227, "Uitikon": 248, "Affoltern am Albis": 2, "Geroldswil": 244,
|
| 39 |
+
"Niederglatt": 89, "Thalwil": 141, "Rorbas": 68, "Pfungen": 224, "Weiningen (ZH)": 251,
|
| 40 |
+
"Bubikon": 112, "Neftenbach": 223, "Mettmenstetten": 9, "Otelfingen": 94, "Flurlingen": 29,
|
| 41 |
+
"Stadel": 100, "Grüningen": 116, "Henggart": 31, "Dachsen": 25, "Bonstetten": 3,
|
| 42 |
+
"Bachenbülach": 51, "Horgen": 295
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
# Vorhersagefunktion
|
| 46 |
+
def predict(rooms, area, town):
|
| 47 |
+
if town not in locations:
|
| 48 |
+
return "Stadt nicht gefunden!"
|
| 49 |
+
|
| 50 |
+
bfs_number = locations[town]
|
| 51 |
+
df = df_bfs_data[df_bfs_data["bfs_number"] == bfs_number].copy()
|
| 52 |
+
df.reset_index(inplace=True)
|
| 53 |
+
|
| 54 |
+
if len(df) != 1:
|
| 55 |
+
return "Keine eindeutigen Daten für diese Stadt!"
|
| 56 |
+
|
| 57 |
+
# Benutzerwerte (`rooms` und `area`) hinzufügen
|
| 58 |
+
df.loc[0, "rooms"] = rooms
|
| 59 |
+
df.loc[0, "area"] = area
|
| 60 |
+
|
| 61 |
+
# Nur die Features verwenden, mit denen das Modell trainiert wurde
|
| 62 |
+
prediction = model.predict(df[['pop', 'pop_dens', 'frg_pct', 'emp', 'tax_income', 'emp_per_capita', 'wealth_factor']])
|
| 63 |
+
|
| 64 |
+
return f"Vorhergesagter Mietpreis: {round(prediction[0], 2)} CHF"
|
| 65 |
+
|
| 66 |
+
# Gradio-Interface
|
| 67 |
+
demo = gr.Interface(
|
| 68 |
+
fn=predict,
|
| 69 |
+
inputs=[
|
| 70 |
+
gr.Number(label="Anzahl Zimmer"),
|
| 71 |
+
gr.Number(label="Wohnfläche (m²)"),
|
| 72 |
+
gr.Dropdown(choices=locations.keys(), label="Stadt"),
|
| 73 |
+
],
|
| 74 |
+
outputs="text",
|
| 75 |
+
title="Mietpreis-Vorhersage",
|
| 76 |
+
description="Gibt eine Mietpreis-Vorhersage für eine Wohnung basierend auf Stadt, Wohnfläche und Zimmeranzahl aus.",
|
| 77 |
+
examples=[
|
| 78 |
+
[4.5, 120, "Dietlikon"],
|
| 79 |
+
[3.5, 60, "Winterthur"],
|
| 80 |
+
[2, 40, "Zürich"],
|
| 81 |
+
],
|
| 82 |
+
)
|
| 83 |
+
|
| 84 |
+
# App starten
|
| 85 |
+
if __name__ == "__main__":
|
| 86 |
+
demo.launch()
|
bfs_municipality_and_tax_data.csv
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
random_forest_regression.pkl
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:935683d59d84c4a9235045ebc7370c33274173e3682adf433844689a4964a8df
|
| 3 |
+
size 15697602
|
requirements.txt
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio
|
| 2 |
+
pandas
|
| 3 |
+
numpy
|
| 4 |
+
scikit-learn
|