WYCENY NIERUCHOMOŚCI
+48 694 150 955

jak wytresować smoka 4 – lokalizacja

jak wytresować smoka 4 – lokalizacja

W poprzednim wpisie (tutaj) otrzymaliśmy zbiór ofert nieruchomości z uzupełnionymi danymi dotyczącymi roku budowy. Dziś pokażemy jak podzielić zbiór ze względu na lokalizację.

Do podzialu danych ze względu na lokalizację możemy użyć algorytmu KMeans z biblioteki Scikit-learn (sklearn).

KMeans jest to algorytm klasteryzacji (grupowania), który jest używany do grupowania podobnych obiektów w grupy (klastery). KMeans jest to algorytm iteracyjny, który zatrzymuje się, gdy centroidy nie ulegną już zmianie. Każdy obiekt jest przypisywany do jednej i tylko jednej grupy. W rezultacie otrzymujemy kilka grup obiektów, które są podobne do siebie. Szczegóły dostępne są np. na Wikipedi.

Na potrzeby obliczeń definiujemy funkcję:

def kmeans_geo(df,n_clusters):
    # tworzenie modelu k-średnich
    kmeans = KMeans(n_clusters=n_clusters)
    # dostosowywanie modelu do danych
    kmeans.fit(df[['geo_lat', 'geo_lng']])
    # dodawanie etykiet klastrów do oryginalnego DataFrame
    df['cluster_kmeans'] = kmeans.labels_
    return 'cluster_kmeans'

Wczytujemy także granice dzielnic z przygotowanego wcześniej pliku geojson, sprawdzamy w jakich dzielnicach znajdują się nasze nieruchomości oraz tworzymy dodatkową kolumnę ‘dzielnica’ do ktorej przypisujemy wartość kolumny z pliku geojson ‘NAZWAJEDNO’ która została przypisana do naszej nieruchomości i która odpowiada dzielnicy w której znajduje się nieruchomość:

city_borders = gpd.read_file("granice_miast.geojson")
gdf = gpd.GeoDataFrame(df, geometry=gpd.points_from_xy(df['geo_lng'], df['geo_lat']))
# sprawdzanie, które punkty znajdują się w granicach dzielnic
result = gpd.sjoin(gdf, city_borders, op='within')
df=result
df['dzielnica']=df['NAZWAJEDNO']
df=df[['cena1m2', 'pow', 'rok_budowy','kond','l_kond','geo_lat','geo_lng','prediction_standard','dzielnica']]

Definiujemy funkcję rysującą wykres z podziałem lokalizacji nieruchomości na klastry oraz z granicami dzielnic:

def plot_map(df,city_borders,cluster_area):
    x=df['geo_lng']
    y=df['geo_lat']
    
    codes, uniques= pd.factorize(df[cluster_area].apply(str))
    
    df[cluster_area]=codes
    z=df[cluster_area]

    delta_geo=0.02
    x_min, x_max = (x.min()-delta_geo), (x.max()+delta_geo)
    y_min, y_max = (y.min()-delta_geo), (y.max()+delta_geo)
       
    plt.gca().set_xlim([x_min, x_max])
    plt.gca().set_ylim([y_min, y_max])

    city_borders.plot(ax=plt.gca(), edgecolor='black', facecolor='white', zorder=1)

    cmap = cm.get_cmap('tab20c')
    min_z = np.min(z)
    max_z = np.max(z)
    normalize = colors.Normalize(vmin=min_z, vmax=max_z)
    colors_valid = cmap(normalize(z))

    plt.scatter(x, y, alpha=0.8, c=colors_valid)
    plt.xlabel('geo_lng')
    plt.ylabel('geo_lat')

    clusters = df[cluster_area].unique()
    for i, cluster in enumerate(clusters):
        x_mean = df[df[cluster_area] == cluster]['geo_lng'].mean()
        y_mean = df[df[cluster_area] == cluster]['geo_lat'].mean()
        plt.annotate(uniques[i], (x_mean, y_mean))
    plt.show()

Wywołujemy funkcję plot_map z podziałem za pomocą algorytmu KMeans na 18 klastrów (mamy 18 dzielnic w Warszawie):

plot_map(df,city_borders,cluster_area=kmeans_geo(df,n_clusters=18))

Jak widać, algorytm podzielił nam dane na obszary zaledwie zbliżone do obszarów dzielnic (co i tak wydaje się być sukcesem). Nie jest to podział zadowalający i zastosowanie go wymagałoby dobrego uzasadnienia. Jeżeli wolimy tradycyjny podział, możemy przeprowadzić podział ze względu na położenie w dzielnicach:

plot_map(df,city_borders,cluster_area='dzielnica')

Wykonajmy teraz algorytm KMeans dla jednej z dzielnic (podzielimy nieruchomości z jednej z dzielnic na 3 podzbiory, które zróźnicują nam lokalizacyjnie dzielnicę). Zrobimy to na przykładzie dzielnicy Ursus:

allowed_values = ['Ursus']
df = df[df['dzielnica'].isin(allowed_values)]

plot_map(df,city_borders,cluster_area=kmeans_geo(df,n_clusters=3))

otrzymaliśmy wykres:

Jak widać algorytm podzielił dane na 3 obszary w sposób całkiem logiczny. Możemy oczywiście dzielić obszary na dowolną ilość klastrów w zależności od specyfiki lokalnego rynku.

  1. http://www.adamczyk-wyceny.pl/jak-wytresowac-smoka-rok-budowy-na-podstawie-wspolrzednych-geo/
  2. http://www.adamczyk-wyceny.pl/jak-wytresowac-smoka-kategoryzacja-tekstu-czyli-standard-wykonczenia-na-podstawie-opisow-w-ogloszeniach/
  3. http://www.adamczyk-wyceny.pl/jak-wytresowac-smoka-czyli-sieci-neuronowe-w-praktyce/