基于地理位置标记的空间聚类分析(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()

 

猜你喜欢

转载自blog.csdn.net/qq_33356563/article/details/86548212