基於地理位置標記的空間聚類分析(python-DBSCAN)

數據來源通過www.flickr.com/services/api接口抓取帶地理標記的flickr圖片及屬性數據,篩選年份,經過數據清洗,得到樣本數據。

使用軟件python 3

需求:得到熱點區域AOI

參考文獻

1.《基於地理標記照片的北京市入境旅遊流空間特徵》

2. https://www.cnblogs.com/pinard/p/6208966.html

具體思路:

首先將數據進行整理、清洗;然後使用Python scikit-learn中的DBSCAN聚類方法,選擇合適的搜索半徑,以及個數點,得到聚類結果;求出沒個聚類點的中心位置,就可得到熱點區域AOI。

聚類DBSCAN算法:

             DBSCAN是基於一組鄰域來描述樣本集的緊密程度的,參數(ϵϵ, MinPts)用來描述鄰域的樣本分佈緊密程度。其中,ϵϵ描述了某一樣本的鄰域距離閾值,MinPts描述了某一樣本的距離爲ϵϵ的鄰域中樣本個數的閾值。

    假設我的樣本集是D=(x1,x2,...,xm)(x1,x2,...,xm),則DBSCAN具體的密度描述定義如下:

    1) ϵϵ-鄰域:對於xj∈Dxj∈D,其ϵϵ-鄰域包含樣本集D中與xjxj的距離不大於ϵϵ的子樣本集,即Nϵ(xj)={xi∈D|distance(xi,xj)≤ϵ}Nϵ(xj)={xi∈D|distance(xi,xj)≤ϵ}, 這個子樣本集的個數記爲|Nϵ(xj)||Nϵ(xj)| 

    2) 核心對象:對於任一樣本xj∈Dxj∈D,如果其ϵϵ-鄰域對應的Nϵ(xj)Nϵ(xj)至少包含MinPts個樣本,即如果|Nϵ(xj)|≥MinPts|Nϵ(xj)|≥MinPts,則xjxj是核心對象。 

    3)密度直達:如果xixi位於xjxj的ϵϵ-鄰域中,且xjxj是核心對象,則稱xixi由xjxj密度直達。注意反之不一定成立,即此時不能說xjxj由xixi密度直達, 除非且xixi也是核心對象。

    4)密度可達:對於xixi和xjxj,如果存在樣本樣本序列p1,p2,...,pTp1,p2,...,pT,滿足p1=xi,pT=xjp1=xi,pT=xj, 且pt+1pt+1由ptpt密度直達,則稱xjxj由xixi密度可達。也就是說,密度可達滿足傳遞性。此時序列中的傳遞樣本p1,p2,...,pT−1p1,p2,...,pT−1均爲核心對象,因爲只有核心對象才能使其他樣本密度直達。注意密度可達也不滿足對稱性,這個可以由密度直達的不對稱性得出。

    5)密度相連:對於xixi和xjxj,如果存在覈心對象樣本xkxk,使xixi和xjxj均由xkxk密度可達,則稱xixi和xjxj密度相連。注意密度相連關係是滿足對稱性的。

效果圖:

           

Python代碼:


import numpy as np,pandas as pd
from sklearn.cluster import DBSCAN
from shapely.geometry  import MultiPoint
import geopandas
import shapefile

from matplotlib import pyplot as plt
plt.title("北京市遊客地理標記城區空間聚類結果")
plt.scatter(latlngs[:,0],latlngs[:,1], s=1, c="black", marker='.')
border_shape=shapefile.Reader(shape_path)
border_shape_2=shapefile.Reader(shape_path_2huan)
border_shape_5=shapefile.Reader(shape_path_5huan)
border=border_shape.shapes()
border_2=border_shape_2.shapes()
border_5=border_shape_5.shapes()
#聚類中心區域
def get_centermost_point(cluster):
    centroid = (MultiPoint(cluster).centroid.x, MultiPoint(cluster).centroid.y)
    print(centroid)
    return tuple(centroid)
# #渲染聚類結果
for border_detail in clusters:
    x ,y= [],[]
    for cell in border_detail:
            x.append(cell[0])
            y.append(cell[1])
    plt.scatter(x, y,marker='o')
plt.show()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章