Python · Datengenerierung
Code
import pandas as pd import numpy as np from datetime import datetime, timedelta np.random.seed(42) N = 4200 # --- Stadtteile mit unterschiedlicher Marktdynamik --- stadtteile = { 'Innenstadt': {'nachfrage': 1.4, 'avg_preis_qm': 5200}, 'Altstadt': {'nachfrage': 1.3, 'avg_preis_qm': 4800}, 'Universitätsvtl.': {'nachfrage': 1.5, 'avg_preis_qm': 4200}, 'Südvorstadt': {'nachfrage': 1.2, 'avg_preis_qm': 3800}, 'Westend': {'nachfrage': 1.0, 'avg_preis_qm': 3400}, 'Nordstadt': {'nachfrage': 0.85, 'avg_preis_qm': 2900}, 'Industriegebiet': {'nachfrage': 0.6, 'avg_preis_qm': 2200}, 'Umland Nord': {'nachfrage': 0.75, 'avg_preis_qm': 2600}, 'Umland Süd': {'nachfrage': 0.9, 'avg_preis_qm': 3000}, 'Umland West': {'nachfrage': 0.7, 'avg_preis_qm': 2400}, } records = [] for i in range(N): stadtteil = np.random.choice(list(stadtteile.keys()), p=[0.12,0.10,0.14,0.12,0.10,0.09,0.06,0.10,0.09,0.08]) st = stadtteile[stadtteil] objekt_typ = np.random.choice( ['ETW','EFH','DHH','RH','MFH','Penthouse'], p=[0.40,0.22,0.12,0.10,0.08,0.08]) wohnflaeche = np.random.normal( {'ETW':78,'EFH':145,'DHH':125,'RH':110,'MFH':320,'Penthouse':120}[objekt_typ], 20) wohnflaeche = max(30, wohnflaeche) baujahr = np.random.choice([1960,1975,1990,2000,2010,2018,2022], p=[0.12,0.15,0.18,0.15,0.18,0.12,0.10]) zimmer = np.random.choice([1,2,3,4,5,6], p=[0.05,0.20,0.30,0.25,0.12,0.08]) zustand = np.random.choice(['Erstbezug','Saniert','Gepflegt','Renovierungsbed.'], p=[0.15,0.25,0.40,0.20]) balkon = np.random.random() > 0.35 garten = np.random.random() > 0.7 if objekt_typ in ['EFH','DHH','RH'] else False stellplatz = np.random.random() > 0.4 energieeffizienz = np.random.choice(['A+','A','B','C','D','E','F'], p=[0.05,0.10,0.15,0.25,0.20,0.15,0.10]) # Inserats-Monat (Saisonalität) monat = np.random.choice(range(1,13), p=[0.09,0.08,0.10,0.10,0.09,0.08,0.06,0.06,0.09,0.10,0.08,0.07]) # Preispositionierung: Abweichung vom Marktwert preis_abweichung = np.random.normal(0.05, 0.10) # +5% über Markt im Schnitt anzahl_fotos = np.random.choice([5,8,12,18,25,30], p=[0.05,0.10,0.20,0.30,0.25,0.10]) # === VERKAUFSDAUER-MODELL (Tage) === basis = 55 # Nachfrage-Effekt: Hohe Nachfrage → schneller basis /= st['nachfrage'] # Preis-Effekt: Überteuert → langsamer basis *= (1 + preis_abweichung * 3.5) # Zustand if zustand == 'Erstbezug': basis *= 0.7 elif zustand == 'Renovierungsbed.': basis *= 1.6 # Saisonalität: Frühling schnell, Winter langsam saison = {1:1.15,2:1.05,3:0.85,4:0.80,5:0.82,6:0.90, 7:1.10,8:1.15,9:0.88,10:0.85,11:1.05,12:1.25} basis *= saison[monat] # Fotos: Mehr → schneller basis *= max(0.7, 1.3 - anzahl_fotos / 30) # Noise basis *= np.random.lognormal(0, 0.25) tage = int(np.clip(basis, 7, 365)) records.append({ 'stadtteil': stadtteil, 'objekt_typ': objekt_typ, 'wohnflaeche_qm': round(wohnflaeche,1), 'zimmer': zimmer, 'baujahr': baujahr, 'zustand': zustand, 'balkon': balkon, 'garten': garten, 'stellplatz': stellplatz, 'energieeffizienz': energieeffizienz, 'inserat_monat': monat, 'preis_abweichung_%': round(preis_abweichung*100,1), 'anzahl_fotos': anzahl_fotos, 'nachfrage_index': st['nachfrage'], 'verkaufsdauer_tage': tage, }) df = pd.DataFrame(records) print(f"Dataset: {len(df):,} Transaktionen") print(f"Ø Verkaufsdauer: {df['verkaufsdauer_tage'].mean():.0f} Tage") print(f"Median: {df['verkaufsdauer_tage'].median():.0f} Tage") print(f"Spanne: {df['verkaufsdauer_tage'].min()} – {df['verkaufsdauer_tage'].max()} Tage")